helpers.py (2401B)
1 #!/usr/bin/env python3 2 # electrum-obelisk 3 # Copyright (C) 2020-2021 Ivan J. <parazyd@dyne.org> 4 # Copyright (c) 2018-2020 Chris Belcher (MIT License) 5 # 6 # This program is free software: you can redistribute it and/or modify 7 # it under the terms of the GNU Affero General Public License as published by 8 # the Free Software Foundation, either version 3 of the License, or 9 # (at your option) any later version. 10 # 11 # This program is distributed in the hope that it will be useful, 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 # GNU Affero General Public License for more details. 15 # 16 # You should have received a copy of the GNU Affero General Public License 17 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 """ Useful helper functions """ 19 from binascii import hexlify 20 21 code_strings = { 22 2: '01', 23 10: '0123456789', 24 16: '0123456789abcdef', 25 32: 'abcdefghijklmnopqrstuvwxyz234567', 26 58: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz', 27 256: ''.join([chr(x) for x in range(256)]), 28 } 29 30 31 def get_code_string(base): 32 """ Get valid characters for base """ 33 if base in code_strings: 34 return code_strings[base] 35 raise ValueError('Invalid base!') 36 37 38 def encode(val, base, minlen=0): 39 """ Encoding for serialization """ 40 base, minlen = int(base), int(minlen) 41 code_string = get_code_string(base) 42 result_bytes = bytes() 43 while val > 0: 44 curcode = code_string[val % base] 45 result_bytes = bytes([ord(curcode)]) + result_bytes 46 val //= base 47 48 pad_size = minlen - len(result_bytes) 49 50 padding_element = b'\x00' if base == 256 else b'1' \ 51 if base == 58 else b'0' 52 if pad_size > 0: 53 result_bytes = padding_element * pad_size + result_bytes 54 55 result_string = ''.join([chr(y) for y in result_bytes]) 56 result = result_bytes if base == 256 else result_string 57 return result 58 59 60 def safe_hexlify(_str): 61 """ hexlify and return a string """ 62 return str(hexlify(_str), 'utf-8') 63 64 65 def num_to_var_int(num): 66 """ number to bytes """ 67 num = int(num) 68 if num < 253: 69 return bytes([num]) 70 if num < 65536: 71 return bytes([253]) + encode(num, 256, 2)[::-1] 72 if num < 4294967296: 73 return bytes([254]) + encode(num, 256, 4)[::-1] 74 return bytes([255]) + encode(num, 256, 8)[::-1]