71 lines
1.7 KiB
Python
71 lines
1.7 KiB
Python
|
CHARSET = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l'
|
||
|
|
||
|
|
||
|
def polymod(values):
|
||
|
chk = 1
|
||
|
generator = [
|
||
|
(0x01, 0x98f2bc8e61),
|
||
|
(0x02, 0x79b76d99e2),
|
||
|
(0x04, 0xf33e5fb3c4),
|
||
|
(0x08, 0xae2eabe2a8),
|
||
|
(0x10, 0x1e4f43e470)]
|
||
|
for value in values:
|
||
|
top = chk >> 35
|
||
|
chk = ((chk & 0x07ffffffff) << 5) ^ value
|
||
|
for i in generator:
|
||
|
if top & i[0] != 0:
|
||
|
chk ^= i[1]
|
||
|
return chk ^ 1
|
||
|
|
||
|
|
||
|
def prefix_expand(prefix):
|
||
|
return [ord(x) & 0x1f for x in prefix] + [0]
|
||
|
|
||
|
|
||
|
def calculate_checksum(prefix, payload):
|
||
|
poly = polymod(prefix_expand(prefix) + payload + [0, 0, 0, 0, 0, 0, 0, 0])
|
||
|
out = list()
|
||
|
for i in range(8):
|
||
|
out.append((poly >> 5 * (7 - i)) & 0x1f)
|
||
|
return out
|
||
|
|
||
|
|
||
|
def verify_checksum(prefix, payload):
|
||
|
return polymod(prefix_expand(prefix) + payload) == 0
|
||
|
|
||
|
|
||
|
def b32decode(inputs):
|
||
|
out = list()
|
||
|
for letter in inputs:
|
||
|
out.append(CHARSET.find(letter))
|
||
|
return out
|
||
|
|
||
|
|
||
|
def b32encode(inputs):
|
||
|
out = ''
|
||
|
for char_code in inputs:
|
||
|
out += CHARSET[char_code]
|
||
|
return out
|
||
|
|
||
|
|
||
|
def convertbits(data, frombits, tobits, pad=True):
|
||
|
acc = 0
|
||
|
bits = 0
|
||
|
ret = []
|
||
|
maxv = (1 << tobits) - 1
|
||
|
max_acc = (1 << (frombits + tobits - 1)) - 1
|
||
|
for value in data:
|
||
|
if value < 0 or (value >> frombits):
|
||
|
return None
|
||
|
acc = ((acc << frombits) | value) & max_acc
|
||
|
bits += frombits
|
||
|
while bits >= tobits:
|
||
|
bits -= tobits
|
||
|
ret.append((acc >> bits) & maxv)
|
||
|
if pad:
|
||
|
if bits:
|
||
|
ret.append((acc << (tobits - bits)) & maxv)
|
||
|
elif bits >= frombits or ((acc << (tobits - bits)) & maxv):
|
||
|
return None
|
||
|
return ret
|