package util import ( "fmt" "github.com/ipfs/go-cid" "math/big" "strings" ) const base62Alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // ConvertCIDBase32ToBase62 converts an IPFS CID from base32 to base62 func ConvertCIDBase32ToBase62(cidBase32 string) (string, error) { c, err := cid.Decode(cidBase32) if err != nil { return "", err } return encodeBase62(c.Bytes()), nil } // ConvertCIDBase62ToBase32 converts an IPFS CID from base62 to base32 func ConvertCIDBase62ToBase32(cidBase62 string) (string, error) { decodedBytes, err := decodeBase62(cidBase62) if err != nil { return "", fmt.Errorf("failed to decode base62: %w", err) } c, err := cid.Cast(decodedBytes) if err != nil { return "", err } return c.String(), nil } func encodeBase62(data []byte) string { if len(data) == 0 { return "" } num := new(big.Int).SetBytes(data) if num.Cmp(big.NewInt(0)) == 0 { return "0" } var result []byte base := big.NewInt(62) zero := big.NewInt(0) for num.Cmp(zero) > 0 { remainder := new(big.Int) num.DivMod(num, base, remainder) result = append(result, base62Alphabet[remainder.Int64()]) } // Reverse the result for i, j := 0, len(result)-1; i < j; i, j = i+1, j-1 { result[i], result[j] = result[j], result[i] } return string(result) } func decodeBase62(encoded string) ([]byte, error) { if encoded == "" { return []byte{}, nil } num := big.NewInt(0) base := big.NewInt(62) for _, char := range encoded { index := strings.IndexRune(base62Alphabet, char) if index == -1 { return nil, fmt.Errorf("invalid character in base62 string: %c", char) } num.Mul(num, base) num.Add(num, big.NewInt(int64(index))) } return num.Bytes(), nil } func IsBase32(str string) bool { if str == "" { return false } // Base32 uses A-Z, 2-7 (case insensitive) for _, char := range strings.ToUpper(str) { if !((char >= 'A' && char <= 'Z') || (char >= '2' && char <= '7') || char == '=') { return false } } return len(str) > 0 }