github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/snow/base32.go (about) 1 package snow 2 3 import "errors" 4 5 const ( 6 encodeBase32Map = "ybndrfg8ejkmcpqxot1uwisza345h769" 7 ) 8 9 // nolint gochecknoglobals 10 var ( 11 decodeBase32Map [256]byte 12 13 // ErrInvalidBase32 is returned by ParseBase32 when given an invalid []byte 14 ErrInvalidBase32 = errors.New("invalid base32") 15 ) 16 17 // Create maps for decoding Base58/Base32. 18 // This speeds up the process tremendously. 19 // nolint gochecknoinits 20 func init() { 21 for i := 0; i < len(encodeBase32Map); i++ { 22 decodeBase32Map[i] = 0xFF 23 } 24 25 for i := 0; i < len(encodeBase32Map); i++ { 26 decodeBase32Map[encodeBase32Map[i]] = byte(i) 27 } 28 } 29 30 // ParseBase32 parses a base32 []byte into a snowflake ID 31 // NOTE: There are many different base32 implementations so becareful when 32 // doing any interoperation. 33 func ParseBase32(b []byte) (ID, error) { 34 var id int64 35 36 for i := range b { 37 if decodeBase32Map[b[i]] == 0xFF { // nolint gomnd 38 return -1, ErrInvalidBase32 39 } 40 41 id = id*32 + int64(decodeBase32Map[b[i]]) // nolint gomnd 42 } 43 44 return ID(id), nil 45 } 46 47 // Base32 uses the z-base-32 character set but encodes and decodes similar 48 // to base58, allowing it to create an even smaller result string. 49 // NOTE: There are many different base32 implementations so becareful when 50 // doing any interoperation. 51 // nolint gomnd 52 func (f ID) Base32() string { 53 if f < 32 { 54 return string(encodeBase32Map[f]) 55 } 56 57 b := make([]byte, 0, 12) 58 for f >= 32 { 59 b = append(b, encodeBase32Map[f%32]) 60 f /= 32 61 } 62 63 b = append(b, encodeBase32Map[f]) 64 65 for x, y := 0, len(b)-1; x < y; x, y = x+1, y-1 { // nolint gomnd 66 b[x], b[y] = b[y], b[x] 67 } 68 69 return string(b) 70 }