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:
Justin T 2019-11-27 01:22:36 -06:00
parent 4a3167a96b
commit d1b0d8f87f
2 changed files with 78 additions and 0 deletions

View File

@ -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))
}

View File

@ -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
}