From 27c16537ec7fcc549273bd378871f7cff1ff05ac Mon Sep 17 00:00:00 2001 From: thinkgos Date: Tue, 3 Dec 2024 23:15:47 +0800 Subject: [PATCH] fixfeat: add base32n --- base32n/base32n.go | 73 +++++++++++++++++++++++++++++++++++++++++ base32n/base32n_test.go | 22 +++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 base32n/base32n.go create mode 100644 base32n/base32n_test.go diff --git a/base32n/base32n.go b/base32n/base32n.go new file mode 100644 index 0000000..96fa625 --- /dev/null +++ b/base32n/base32n.go @@ -0,0 +1,73 @@ +package base32n + +import ( + "errors" + "strconv" + "unsafe" +) + +var StdEncoding = NewEncoding("abcdefghijklmnopqrstuvwxyz234567") + +const ( + decodeMapInitialize = "" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + invalidIndex = '\xff' +) + +type Encoding struct { + encode [32]byte // mapping of symbol index to symbol byte value + decodeMap [256]uint8 // mapping of symbol byte value to symbol index +} + +func NewEncoding(encoder string) *Encoding { + e := new(Encoding) + copy(e.encode[:], encoder) + copy(e.decodeMap[:], decodeMapInitialize) + for i := 0; i < len(encoder); i++ { + char := encoder[i] + e.decodeMap[char] = uint8(i) + } + return e +} + +func (enc *Encoding) Encode(num int64) string { + result := make([]byte, 0, 13) + for num > 0 { + remainder := num & 0x1f + result = append(result, enc.encode[remainder]) + num >>= 5 + } + for i, j := 0, len(result)-1; i < j; i, j = i+1, j-1 { + result[i], result[j] = result[j], result[i] + } + return unsafe.String(unsafe.SliceData(result), len(result)) +} + +func (enc *Encoding) Decode(s string) (int64, error) { + var num int64 = 0 + + for i := 0; i < len(s); i++ { + char := s[i] + val := enc.decodeMap[char] + if val == invalidIndex { + return 0, errors.New("illegal base32n data at input byte " + strconv.FormatInt(int64(char), 10)) + } + num += int64(val) * int64(1<