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  }