2021-08-24 06:22:46 +03:00
|
|
|
module base58
|
|
|
|
|
2022-08-08 15:33:16 +03:00
|
|
|
const impossible = 'this should never happen'
|
2021-08-24 06:22:46 +03:00
|
|
|
|
2022-08-08 15:33:16 +03:00
|
|
|
pub const btc_alphabet = new_alphabet('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz') or {
|
|
|
|
panic(impossible)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub const flickr_alphabet = new_alphabet('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ') or {
|
|
|
|
panic(impossible)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub const ripple_alphabet = new_alphabet('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz') or {
|
|
|
|
panic(impossible)
|
|
|
|
}
|
|
|
|
|
|
|
|
// alphabets is a map of common base58 alphabets:
|
|
|
|
pub const alphabets = {
|
|
|
|
'btc': btc_alphabet
|
|
|
|
'flickr': flickr_alphabet
|
|
|
|
'ripple': ripple_alphabet
|
2021-08-24 06:22:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Alphabet is the series of characters that an input
|
|
|
|
// will be encoded to and a decode table.
|
|
|
|
struct Alphabet {
|
|
|
|
mut:
|
2022-04-15 18:25:45 +03:00
|
|
|
decode []i8 = []i8{len: 128, init: -1}
|
2022-04-15 15:35:35 +03:00
|
|
|
encode []u8 = []u8{len: 58}
|
2021-08-24 06:22:46 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// str returns an Alphabet encode table byte array as a string
|
|
|
|
pub fn (alphabet Alphabet) str() string {
|
|
|
|
// i guess i had a brain fart here. Why would I actually use this code?!
|
2022-04-15 15:35:35 +03:00
|
|
|
// mut str := []u8{}
|
2021-08-24 06:22:46 +03:00
|
|
|
// for entry in alphabet.encode {
|
|
|
|
// str << entry
|
|
|
|
// }
|
|
|
|
// return str.bytestr()
|
|
|
|
return alphabet.encode.bytestr()
|
|
|
|
}
|
|
|
|
|
|
|
|
// new_alphabet instantiates an Alphabet object based on
|
|
|
|
// the provided characters
|
|
|
|
pub fn new_alphabet(str string) ?Alphabet {
|
|
|
|
if str.len != 58 {
|
|
|
|
return error(@MOD + '.' + @FN + ': string must be 58 characters in length')
|
|
|
|
}
|
|
|
|
|
|
|
|
mut ret := Alphabet{}
|
2022-03-09 21:26:00 +03:00
|
|
|
copy(mut ret.encode, str.bytes())
|
2021-08-24 06:22:46 +03:00
|
|
|
|
|
|
|
mut distinct := 0
|
|
|
|
for i, b in ret.encode {
|
|
|
|
if ret.decode[b] == -1 {
|
|
|
|
distinct++
|
|
|
|
}
|
|
|
|
ret.decode[b] = i8(i)
|
|
|
|
}
|
|
|
|
|
|
|
|
if distinct != 58 {
|
|
|
|
return error(@MOD + '.' + @FN + ': string must not contain repeating characters')
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret
|
|
|
|
}
|