diff --git a/monero/base58.py b/monero/base58.py index 1ad2e7f..38530f4 100644 --- a/monero/base58.py +++ b/monero/base58.py @@ -16,19 +16,16 @@ __encodedBlockSizes = [0, 2, 3, 5, 6, 7, 9, 10, 11] __fullBlockSize = 8 __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): - return "".join('%02x' % int(b) for b in bin) +def _hexToBin(hex_): + 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): - return ''.join([chr(bin[i]) for i in range(len(bin))]) +def _binToHex(bin_): + return "".join('%02x' % int(b) for b in bin_) + def _uint8be_to_64(data): if not (1 <= len(data) <= 8): @@ -39,6 +36,7 @@ def _uint8be_to_64(data): res = res << 8 | b return res + def _uint64_to_8be(num, size): if size < 1 or size > 8: raise ValueError("Invalid input length: %d" % size) @@ -51,6 +49,7 @@ def _uint64_to_8be(num, size): return res + def encode_block(data, buf, index): l_data = len(data) @@ -68,6 +67,7 @@ def encode_block(data, buf, index): return buf + def encode(hex): '''Encode hexadecimal string as base58 (ex: encoding a Monero address).''' data = _hexToBin(hex) @@ -80,7 +80,7 @@ def encode(hex): last_block_size = l_data % __fullBlockSize 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): res = encode_block(data[(i*__fullBlockSize):(i*__fullBlockSize+__fullBlockSize)], res, i * __fullEncodedBlockSize) @@ -88,7 +88,8 @@ def encode(hex): 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) - return _binToStr(res) + return bytes(res).decode('ascii') + def decode_block(data, buf, index): 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)) tmp_buf = _uint64_to_8be(res_num, res_size) - for i in range(len(tmp_buf)): - buf[i+index] = tmp_buf[i] + buf[index:index + len(tmp_buf)] = tmp_buf return buf + def decode(enc): '''Decode a base58 string (ex: a Monero address) into hexidecimal form.''' - enc = _strToBin(enc) + enc = bytearray(enc, encoding='ascii') l_enc = len(enc) if l_enc == 0: @@ -140,7 +141,7 @@ def decode(enc): 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): data = decode_block(enc[(i*__fullEncodedBlockSize):(i*__fullEncodedBlockSize+__fullEncodedBlockSize)], data, i * __fullBlockSize)