mirror of
https://github.com/ap-pauloafonso/ratio-spoof.git
synced 2026-03-11 17:45:32 +00:00
86 lines
2.3 KiB
Go
86 lines
2.3 KiB
Go
package beencode
|
|
|
|
import (
|
|
"strconv"
|
|
)
|
|
|
|
const (
|
|
dictToken = byte('d')
|
|
numberToken = byte('i')
|
|
listToken = byte('l')
|
|
endOfCollectionToken = byte('e')
|
|
lengthValueStringSeparator = byte(':')
|
|
)
|
|
|
|
//Decode accepts a byte slice and returns a map with information parsed.(panic if it fails)
|
|
func Decode(data []byte) map[string]interface{} {
|
|
result, _ := findParse(0, &data)
|
|
return result.(map[string]interface{})
|
|
}
|
|
|
|
func findParse(currentIdx int, data *[]byte) (result interface{}, nextIdx int) {
|
|
token := (*data)[currentIdx : currentIdx+1][0]
|
|
switch {
|
|
case token == dictToken:
|
|
return mapParse(currentIdx, data)
|
|
case token == numberToken:
|
|
return numberParse(currentIdx, data)
|
|
case token == listToken:
|
|
return listParse(currentIdx, data)
|
|
case token >= byte('0') || token <= byte('9'):
|
|
return stringParse(currentIdx, data)
|
|
default:
|
|
panic("Error decoding beencode")
|
|
}
|
|
}
|
|
|
|
func mapParse(startIdx int, data *[]byte) (result map[string]interface{}, nextIdx int) {
|
|
result = make(map[string]interface{})
|
|
initialMapIndex := startIdx
|
|
current := startIdx + 1
|
|
for (*data)[current : current+1][0] != endOfCollectionToken {
|
|
mapKey, next := findParse(current, data)
|
|
current = next
|
|
mapValue, next := findParse(current, data)
|
|
current = next
|
|
result[mapKey.(string)] = mapValue
|
|
}
|
|
current++
|
|
result["byte_offsets"] = []int{initialMapIndex, current}
|
|
nextIdx = current
|
|
return
|
|
}
|
|
|
|
func listParse(startIdx int, data *[]byte) (result []interface{}, nextIdx int) {
|
|
current := startIdx + 1
|
|
for (*data)[current : current+1][0] != endOfCollectionToken {
|
|
value, next := findParse(current, data)
|
|
result = append(result, value)
|
|
current = next
|
|
}
|
|
current++
|
|
nextIdx = current
|
|
return
|
|
}
|
|
|
|
func numberParse(startIdx int, data *[]byte) (result int, nextIdx int) {
|
|
current := startIdx
|
|
for (*data)[current : current+1][0] != endOfCollectionToken {
|
|
current++
|
|
}
|
|
value, _ := strconv.Atoi(string((*data)[startIdx+1 : current]))
|
|
result = value
|
|
nextIdx = current + 1
|
|
return
|
|
}
|
|
|
|
func stringParse(startIdx int, data *[]byte) (result string, nextIdx int) {
|
|
current := startIdx
|
|
for (*data)[current : current+1][0] != lengthValueStringSeparator {
|
|
current++
|
|
}
|
|
sizeStr, _ := strconv.Atoi(string(((*data)[startIdx:current])))
|
|
result = string((*data)[current+1 : current+1+int(sizeStr)])
|
|
nextIdx = current + 1 + int(sizeStr)
|
|
return
|
|
}
|