base64 & vl64 encoding implemented
Added the encoders/decoders for FUSE-Base64 & VL64. Shout out to Puomi Wiki for their examples, some of my comments in code are straight from there.
This commit is contained in:
parent
4a3167a96b
commit
d1b0d8f87f
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
base64 contains an implementation of the FUSE-Base64 tetrasexagesimal numeric system used in the FUSE v0.2.0 protocol.
|
||||||
|
It typically uses two ASCII characters between decimal indexes 64 (@) and 127 (DEL control character) to produce a
|
||||||
|
two-character representation of a number between 0 and 4095.
|
||||||
|
|
||||||
|
This implementation is a Golang port of the examples from Puomi's wiki for Base64.
|
||||||
|
*/
|
||||||
|
package encoding
|
||||||
|
|
||||||
|
// EncodeB64 takes an integer, encodes it in FUSE-Base64 & returns a slice of bytes that should contain two char's.
|
||||||
|
func EncodeB64(i int) []byte {
|
||||||
|
return []byte{byte(i/64 + 64), byte(i%64 + 64)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeB64 take a slice of bytes, decodes it from FUSE-Base64 & returns the decoded bytes as an integer.
|
||||||
|
func DecodeB64(bytes []byte) int {
|
||||||
|
return 64 * (int(bytes[0]%64) + int(bytes[1]%64))
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
vl64 contains an implementation of the FUSE mixed radix numeric encoding used by Sulake in HH.
|
||||||
|
This implementation is a Golang port of the examples from Puomi's wiki for VL64.
|
||||||
|
*/
|
||||||
|
package encoding
|
||||||
|
|
||||||
|
import "math"
|
||||||
|
|
||||||
|
// DecodeVl64 returns a single number from the Vl64 encoded input.
|
||||||
|
// Any characters after the length indicated by first char of input will be discarded.
|
||||||
|
func DecodeVl64(input []byte) int {
|
||||||
|
length := length(input[0])
|
||||||
|
total := int(input[0]) % 4 // Base4 value
|
||||||
|
|
||||||
|
// Increment all Base64 symbols to the total
|
||||||
|
for inc := 0; inc < length; inc++ {
|
||||||
|
total += (int(input[inc]) - 64) * int(math.Pow(64, float64(inc))/16)
|
||||||
|
}
|
||||||
|
|
||||||
|
if int(input[0]%8) < 4 {
|
||||||
|
return total // Base4 positive
|
||||||
|
}
|
||||||
|
|
||||||
|
return -total // Base4 negative
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodeVl64 returns a slice of bytes capable of storing all increments.
|
||||||
|
// Removes all @ symbols (padding) after last non-@ before returning.
|
||||||
|
func EncodeVl64(input int) []byte {
|
||||||
|
vl64 := make([]byte, 6) // 32-bit integer causes VL64 to have max length of 6.
|
||||||
|
num := int(math.Abs(float64(input))) // Operate on normalized, positive integer
|
||||||
|
length := 1 // Length indicator, updated during encode
|
||||||
|
|
||||||
|
var indicator int
|
||||||
|
if input < 0 {
|
||||||
|
indicator = 'D' // positive(+64)
|
||||||
|
} else {
|
||||||
|
indicator = '@' // negative(+68)
|
||||||
|
}
|
||||||
|
vl64[0] = byte(num%4 + indicator) // Base4 char, positive(+64)/negative(+68) indicator
|
||||||
|
num /= 4 // Base4 processed, prepare for remaining Base64 symbols
|
||||||
|
|
||||||
|
for i := 1; i < 6; i++ {
|
||||||
|
vl64[i] = byte(num%64 + 64) // Base64
|
||||||
|
num /= 64
|
||||||
|
|
||||||
|
if vl64[i] != 64 {
|
||||||
|
length = i + 1 // @ = padding / zero symbol
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
vl64[0] = byte(int(vl64[0]) + length*8) // Base4 char shifted to indicate total length
|
||||||
|
return vl64[:length] // Last padding symbols trimmed out
|
||||||
|
}
|
||||||
|
|
||||||
|
// length returns the total length of the mixed radix number.
|
||||||
|
func length(firstChar byte) int {
|
||||||
|
return (int(firstChar) - 64) / 8
|
||||||
|
}
|
Loading…
Reference in New Issue