Bech32 is a checksummed base32 format. It is being used in cryptocurrencies development (bitcoin, cardano,…) https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki, https://cips.cardano.org/cips/cip19/.
Let’s explore the algorithm.
A Bech32 is consist of three parts, the human readable part(hrp) the separator (always “1”) and the data part. Our algorithm will have two inputs the hrp and the input data. The output of the algorithm will be hrp + 1 + Transformed(input data + checksum) .
Once we calculate the checksum (will tackle it in a bit) we map the values as keys to the following array of characters qpzry9x8gf2tvdw0s3jn54khce6mua7l .
Let’s now calculate the checksum. The checksum is always 6 bytes. In order to calculate it we have to follow the following algorithm:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
def bech32_create_checksum(hrp, data): values = bech32_hrp_expand(hrp) + data polymod = bech32_polymod(values + [0,0,0,0,0,0]) ^ 1 return [(polymod >> 5 * (5 - i)) & 31 for i in range(6)] def bech32_polymod(values): GEN = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3] chk = 1 for v in values: b = (chk >> 25) chk = (chk & 0x1ffffff) << 5 ^ v for i in range(5): chk ^= GEN[i] if ((b >> i) & 1) else 0 return chk def bech32_hrp_expand(s): return [ord(x) >> 5 for x in s] + [0] + [ord(x) & 31 for x in s] |
To write he algorithm in Swift is straight forward but we have to be careful with the operators precedence. You can find an algorithm in Swift here: https://github.com/arnot-project/swift-bech32 along side with test cases so you can practise TDD while you implement the algorithm.