base58 improvements
This commit is contained in:
parent
414f38b124
commit
e4af96540d
|
@ -16,19 +16,16 @@ __encodedBlockSizes = [0, 2, 3, 5, 6, 7, 9, 10, 11]
|
||||||
__fullBlockSize = 8
|
__fullBlockSize = 8
|
||||||
__fullEncodedBlockSize = 11
|
__fullEncodedBlockSize = 11
|
||||||
|
|
||||||
def _hexToBin(hex):
|
|
||||||
if len(hex) % 2 != 0:
|
|
||||||
raise ValueError("Hex string has invalid length: %d" % len(hex))
|
|
||||||
return [int(hex[i*2:i*2+2], 16) for i in range(len(hex)//2)]
|
|
||||||
|
|
||||||
def _binToHex(bin):
|
def _hexToBin(hex_):
|
||||||
return "".join('%02x' % int(b) for b in bin)
|
if len(hex_) % 2 != 0:
|
||||||
|
raise ValueError("Hex string has invalid length: %d" % len(hex_))
|
||||||
|
return [int(hex_[i:i + 2], 16) for i in range(0, len(hex_), 2)]
|
||||||
|
|
||||||
def _strToBin(a):
|
|
||||||
return [ord(s) for s in a]
|
|
||||||
|
|
||||||
def _binToStr(bin):
|
def _binToHex(bin_):
|
||||||
return ''.join([chr(bin[i]) for i in range(len(bin))])
|
return "".join('%02x' % int(b) for b in bin_)
|
||||||
|
|
||||||
|
|
||||||
def _uint8be_to_64(data):
|
def _uint8be_to_64(data):
|
||||||
if not (1 <= len(data) <= 8):
|
if not (1 <= len(data) <= 8):
|
||||||
|
@ -39,6 +36,7 @@ def _uint8be_to_64(data):
|
||||||
res = res << 8 | b
|
res = res << 8 | b
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def _uint64_to_8be(num, size):
|
def _uint64_to_8be(num, size):
|
||||||
if size < 1 or size > 8:
|
if size < 1 or size > 8:
|
||||||
raise ValueError("Invalid input length: %d" % size)
|
raise ValueError("Invalid input length: %d" % size)
|
||||||
|
@ -51,6 +49,7 @@ def _uint64_to_8be(num, size):
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def encode_block(data, buf, index):
|
def encode_block(data, buf, index):
|
||||||
l_data = len(data)
|
l_data = len(data)
|
||||||
|
|
||||||
|
@ -68,6 +67,7 @@ def encode_block(data, buf, index):
|
||||||
|
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
|
|
||||||
def encode(hex):
|
def encode(hex):
|
||||||
'''Encode hexadecimal string as base58 (ex: encoding a Monero address).'''
|
'''Encode hexadecimal string as base58 (ex: encoding a Monero address).'''
|
||||||
data = _hexToBin(hex)
|
data = _hexToBin(hex)
|
||||||
|
@ -80,7 +80,7 @@ def encode(hex):
|
||||||
last_block_size = l_data % __fullBlockSize
|
last_block_size = l_data % __fullBlockSize
|
||||||
res_size = full_block_count * __fullEncodedBlockSize + __encodedBlockSizes[last_block_size]
|
res_size = full_block_count * __fullEncodedBlockSize + __encodedBlockSizes[last_block_size]
|
||||||
|
|
||||||
res = [__alphabet[0]] * res_size
|
res = bytearray([__alphabet[0]] * res_size)
|
||||||
|
|
||||||
for i in range(full_block_count):
|
for i in range(full_block_count):
|
||||||
res = encode_block(data[(i*__fullBlockSize):(i*__fullBlockSize+__fullBlockSize)], res, i * __fullEncodedBlockSize)
|
res = encode_block(data[(i*__fullBlockSize):(i*__fullBlockSize+__fullBlockSize)], res, i * __fullEncodedBlockSize)
|
||||||
|
@ -88,7 +88,8 @@ def encode(hex):
|
||||||
if last_block_size > 0:
|
if last_block_size > 0:
|
||||||
res = encode_block(data[(full_block_count*__fullBlockSize):(full_block_count*__fullBlockSize+last_block_size)], res, full_block_count * __fullEncodedBlockSize)
|
res = encode_block(data[(full_block_count*__fullBlockSize):(full_block_count*__fullBlockSize+last_block_size)], res, full_block_count * __fullEncodedBlockSize)
|
||||||
|
|
||||||
return _binToStr(res)
|
return bytes(res).decode('ascii')
|
||||||
|
|
||||||
|
|
||||||
def decode_block(data, buf, index):
|
def decode_block(data, buf, index):
|
||||||
l_data = len(data)
|
l_data = len(data)
|
||||||
|
@ -118,14 +119,14 @@ def decode_block(data, buf, index):
|
||||||
raise ValueError("Overflow: %d doesn't fit in %d bit(s)" % (res_num, res_size))
|
raise ValueError("Overflow: %d doesn't fit in %d bit(s)" % (res_num, res_size))
|
||||||
|
|
||||||
tmp_buf = _uint64_to_8be(res_num, res_size)
|
tmp_buf = _uint64_to_8be(res_num, res_size)
|
||||||
for i in range(len(tmp_buf)):
|
buf[index:index + len(tmp_buf)] = tmp_buf
|
||||||
buf[i+index] = tmp_buf[i]
|
|
||||||
|
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
|
|
||||||
def decode(enc):
|
def decode(enc):
|
||||||
'''Decode a base58 string (ex: a Monero address) into hexidecimal form.'''
|
'''Decode a base58 string (ex: a Monero address) into hexidecimal form.'''
|
||||||
enc = _strToBin(enc)
|
enc = bytearray(enc, encoding='ascii')
|
||||||
l_enc = len(enc)
|
l_enc = len(enc)
|
||||||
|
|
||||||
if l_enc == 0:
|
if l_enc == 0:
|
||||||
|
@ -140,7 +141,7 @@ def decode(enc):
|
||||||
|
|
||||||
data_size = full_block_count * __fullBlockSize + last_block_decoded_size
|
data_size = full_block_count * __fullBlockSize + last_block_decoded_size
|
||||||
|
|
||||||
data = [0] * data_size
|
data = bytearray(data_size)
|
||||||
for i in range(full_block_count):
|
for i in range(full_block_count):
|
||||||
data = decode_block(enc[(i*__fullEncodedBlockSize):(i*__fullEncodedBlockSize+__fullEncodedBlockSize)], data, i * __fullBlockSize)
|
data = decode_block(enc[(i*__fullEncodedBlockSize):(i*__fullEncodedBlockSize+__fullEncodedBlockSize)], data, i * __fullBlockSize)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue