Upload images to your PDS and get instant CDN URLs via images.blue
at main 95 lines 2.0 kB view raw
1package util 2 3import ( 4 "fmt" 5 "github.com/ipfs/go-cid" 6 "math/big" 7 "strings" 8) 9 10const base62Alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 11 12// ConvertCIDBase32ToBase62 converts an IPFS CID from base32 to base62 13func ConvertCIDBase32ToBase62(cidBase32 string) (string, error) { 14 c, err := cid.Decode(cidBase32) 15 if err != nil { 16 return "", err 17 } 18 return encodeBase62(c.Bytes()), nil 19} 20 21// ConvertCIDBase62ToBase32 converts an IPFS CID from base62 to base32 22func ConvertCIDBase62ToBase32(cidBase62 string) (string, error) { 23 decodedBytes, err := decodeBase62(cidBase62) 24 if err != nil { 25 return "", fmt.Errorf("failed to decode base62: %w", err) 26 } 27 c, err := cid.Cast(decodedBytes) 28 if err != nil { 29 return "", err 30 } 31 32 return c.String(), nil 33} 34 35func encodeBase62(data []byte) string { 36 if len(data) == 0 { 37 return "" 38 } 39 40 num := new(big.Int).SetBytes(data) 41 if num.Cmp(big.NewInt(0)) == 0 { 42 return "0" 43 } 44 45 var result []byte 46 base := big.NewInt(62) 47 zero := big.NewInt(0) 48 49 for num.Cmp(zero) > 0 { 50 remainder := new(big.Int) 51 num.DivMod(num, base, remainder) 52 result = append(result, base62Alphabet[remainder.Int64()]) 53 } 54 55 // Reverse the result 56 for i, j := 0, len(result)-1; i < j; i, j = i+1, j-1 { 57 result[i], result[j] = result[j], result[i] 58 } 59 60 return string(result) 61} 62 63func decodeBase62(encoded string) ([]byte, error) { 64 if encoded == "" { 65 return []byte{}, nil 66 } 67 68 num := big.NewInt(0) 69 base := big.NewInt(62) 70 71 for _, char := range encoded { 72 index := strings.IndexRune(base62Alphabet, char) 73 if index == -1 { 74 return nil, fmt.Errorf("invalid character in base62 string: %c", char) 75 } 76 77 num.Mul(num, base) 78 num.Add(num, big.NewInt(int64(index))) 79 } 80 81 return num.Bytes(), nil 82} 83 84func IsBase32(str string) bool { 85 if str == "" { 86 return false 87 } 88 // Base32 uses A-Z, 2-7 (case insensitive) 89 for _, char := range strings.ToUpper(str) { 90 if !((char >= 'A' && char <= 'Z') || (char >= '2' && char <= '7') || char == '=') { 91 return false 92 } 93 } 94 return len(str) > 0 95}