35 lines
832 B
Go
35 lines
832 B
Go
|
package trie
|
||
|
|
||
|
// HexToCompact converts a hex path to the compact encoded format
|
||
|
func HexToCompact(hex []byte) []byte {
|
||
|
return hexToCompact(hex)
|
||
|
}
|
||
|
|
||
|
func hexToCompact(hex []byte) []byte {
|
||
|
terminator := byte(0)
|
||
|
if hasTerm(hex) {
|
||
|
terminator = 1
|
||
|
hex = hex[:len(hex)-1]
|
||
|
}
|
||
|
buf := make([]byte, len(hex)/2+1)
|
||
|
buf[0] = terminator << 5 // the flag byte
|
||
|
if len(hex)&1 == 1 {
|
||
|
buf[0] |= 1 << 4 // odd flag
|
||
|
buf[0] |= hex[0] // first nibble is contained in the first byte
|
||
|
hex = hex[1:]
|
||
|
}
|
||
|
decodeNibbles(hex, buf[1:])
|
||
|
return buf
|
||
|
}
|
||
|
|
||
|
func decodeNibbles(nibbles []byte, bytes []byte) {
|
||
|
for bi, ni := 0, 0; ni < len(nibbles); bi, ni = bi+1, ni+2 {
|
||
|
bytes[bi] = nibbles[ni]<<4 | nibbles[ni+1]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// hasTerm returns whether a hex key has the terminator flag.
|
||
|
func hasTerm(s []byte) bool {
|
||
|
return len(s) > 0 && s[len(s)-1] == 16
|
||
|
}
|