# -*- coding: UTF-8 -*- #/** # * Software Name : pycrate # * Version : 0.4 # * # * Copyright 2016. Benoit Michau. ANSSI. # * # * This library is free software; you can redistribute it and/or # * modify it under the terms of the GNU Lesser General Public # * License as published by the Free Software Foundation; either # * version 2.1 of the License, or (at your option) any later version. # * # * This library is distributed in the hope that it will be useful, # * but WITHOUT ANY WARRANTY; without even the implied warranty of # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # * Lesser General Public License for more details. # * # * You should have received a copy of the GNU Lesser General Public # * License along with this library; if not, write to the Free Software # * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # * MA 02110-1301 USA # * # *-------------------------------------------------------- # * File Name : pycrate_core/utils_py2.py # * Created : 2016-02-11 # * Authors : Benoit Michau # *-------------------------------------------------------- #*/ # # All basic conversion function in native Python should be handled here # import sys from struct import pack, unpack from binascii import hexlify, unhexlify from types import NoneType # use gmpy for handling very large integers try: from gmpy import mpz except ImportError: try: from gmpy2 import mpz except ImportError: # just use Python large integer handling (which is slow) _WITH_MPZ = False else: _WITH_MPZ = True _MPZ_T = type(mpz(0)) else: _WITH_MPZ = True _MPZ_T = type(mpz(0)) #------------------------------------------------------------------------------# # Python2 oddities #------------------------------------------------------------------------------# python_version = sys.version_info[0] # Python2 has long type if _WITH_MPZ: integer_types = (int, long, _MPZ_T) else: integer_types = (int, long) # str and bytes are similar in Python2 bytes_types = (str, ) # unicode is defined in Python2 and not in Python3 str_types = (str, unicode) # NoneType imported from types # defines bchr() identical to chr() bchr = chr #------------------------------------------------------------------------------# # Pycrate generic error #------------------------------------------------------------------------------# class PycrateErr(Exception): pass #------------------------------------------------------------------------------# # bit list functions #------------------------------------------------------------------------------# ARRTOBIT_LUT = { 0: (0, 0, 0, 0, 0, 0, 0, 0), 1: (0, 0, 0, 0, 0, 0, 0, 1), 2: (0, 0, 0, 0, 0, 0, 1, 0), 3: (0, 0, 0, 0, 0, 0, 1, 1), 4: (0, 0, 0, 0, 0, 1, 0, 0), 5: (0, 0, 0, 0, 0, 1, 0, 1), 6: (0, 0, 0, 0, 0, 1, 1, 0), 7: (0, 0, 0, 0, 0, 1, 1, 1), 8: (0, 0, 0, 0, 1, 0, 0, 0), 9: (0, 0, 0, 0, 1, 0, 0, 1), 10: (0, 0, 0, 0, 1, 0, 1, 0), 11: (0, 0, 0, 0, 1, 0, 1, 1), 12: (0, 0, 0, 0, 1, 1, 0, 0), 13: (0, 0, 0, 0, 1, 1, 0, 1), 14: (0, 0, 0, 0, 1, 1, 1, 0), 15: (0, 0, 0, 0, 1, 1, 1, 1), 16: (0, 0, 0, 1, 0, 0, 0, 0), 17: (0, 0, 0, 1, 0, 0, 0, 1), 18: (0, 0, 0, 1, 0, 0, 1, 0), 19: (0, 0, 0, 1, 0, 0, 1, 1), 20: (0, 0, 0, 1, 0, 1, 0, 0), 21: (0, 0, 0, 1, 0, 1, 0, 1), 22: (0, 0, 0, 1, 0, 1, 1, 0), 23: (0, 0, 0, 1, 0, 1, 1, 1), 24: (0, 0, 0, 1, 1, 0, 0, 0), 25: (0, 0, 0, 1, 1, 0, 0, 1), 26: (0, 0, 0, 1, 1, 0, 1, 0), 27: (0, 0, 0, 1, 1, 0, 1, 1), 28: (0, 0, 0, 1, 1, 1, 0, 0), 29: (0, 0, 0, 1, 1, 1, 0, 1), 30: (0, 0, 0, 1, 1, 1, 1, 0), 31: (0, 0, 0, 1, 1, 1, 1, 1), 32: (0, 0, 1, 0, 0, 0, 0, 0), 33: (0, 0, 1, 0, 0, 0, 0, 1), 34: (0, 0, 1, 0, 0, 0, 1, 0), 35: (0, 0, 1, 0, 0, 0, 1, 1), 36: (0, 0, 1, 0, 0, 1, 0, 0), 37: (0, 0, 1, 0, 0, 1, 0, 1), 38: (0, 0, 1, 0, 0, 1, 1, 0), 39: (0, 0, 1, 0, 0, 1, 1, 1), 40: (0, 0, 1, 0, 1, 0, 0, 0), 41: (0, 0, 1, 0, 1, 0, 0, 1), 42: (0, 0, 1, 0, 1, 0, 1, 0), 43: (0, 0, 1, 0, 1, 0, 1, 1), 44: (0, 0, 1, 0, 1, 1, 0, 0), 45: (0, 0, 1, 0, 1, 1, 0, 1), 46: (0, 0, 1, 0, 1, 1, 1, 0), 47: (0, 0, 1, 0, 1, 1, 1, 1), 48: (0, 0, 1, 1, 0, 0, 0, 0), 49: (0, 0, 1, 1, 0, 0, 0, 1), 50: (0, 0, 1, 1, 0, 0, 1, 0), 51: (0, 0, 1, 1, 0, 0, 1, 1), 52: (0, 0, 1, 1, 0, 1, 0, 0), 53: (0, 0, 1, 1, 0, 1, 0, 1), 54: (0, 0, 1, 1, 0, 1, 1, 0), 55: (0, 0, 1, 1, 0, 1, 1, 1), 56: (0, 0, 1, 1, 1, 0, 0, 0), 57: (0, 0, 1, 1, 1, 0, 0, 1), 58: (0, 0, 1, 1, 1, 0, 1, 0), 59: (0, 0, 1, 1, 1, 0, 1, 1), 60: (0, 0, 1, 1, 1, 1, 0, 0), 61: (0, 0, 1, 1, 1, 1, 0, 1), 62: (0, 0, 1, 1, 1, 1, 1, 0), 63: (0, 0, 1, 1, 1, 1, 1, 1), 64: (0, 1, 0, 0, 0, 0, 0, 0), 65: (0, 1, 0, 0, 0, 0, 0, 1), 66: (0, 1, 0, 0, 0, 0, 1, 0), 67: (0, 1, 0, 0, 0, 0, 1, 1), 68: (0, 1, 0, 0, 0, 1, 0, 0), 69: (0, 1, 0, 0, 0, 1, 0, 1), 70: (0, 1, 0, 0, 0, 1, 1, 0), 71: (0, 1, 0, 0, 0, 1, 1, 1), 72: (0, 1, 0, 0, 1, 0, 0, 0), 73: (0, 1, 0, 0, 1, 0, 0, 1), 74: (0, 1, 0, 0, 1, 0, 1, 0), 75: (0, 1, 0, 0, 1, 0, 1, 1), 76: (0, 1, 0, 0, 1, 1, 0, 0), 77: (0, 1, 0, 0, 1, 1, 0, 1), 78: (0, 1, 0, 0, 1, 1, 1, 0), 79: (0, 1, 0, 0, 1, 1, 1, 1), 80: (0, 1, 0, 1, 0, 0, 0, 0), 81: (0, 1, 0, 1, 0, 0, 0, 1), 82: (0, 1, 0, 1, 0, 0, 1, 0), 83: (0, 1, 0, 1, 0, 0, 1, 1), 84: (0, 1, 0, 1, 0, 1, 0, 0), 85: (0, 1, 0, 1, 0, 1, 0, 1), 86: (0, 1, 0, 1, 0, 1, 1, 0), 87: (0, 1, 0, 1, 0, 1, 1, 1), 88: (0, 1, 0, 1, 1, 0, 0, 0), 89: (0, 1, 0, 1, 1, 0, 0, 1), 90: (0, 1, 0, 1, 1, 0, 1, 0), 91: (0, 1, 0, 1, 1, 0, 1, 1), 92: (0, 1, 0, 1, 1, 1, 0, 0), 93: (0, 1, 0, 1, 1, 1, 0, 1), 94: (0, 1, 0, 1, 1, 1, 1, 0), 95: (0, 1, 0, 1, 1, 1, 1, 1), 96: (0, 1, 1, 0, 0, 0, 0, 0), 97: (0, 1, 1, 0, 0, 0, 0, 1), 98: (0, 1, 1, 0, 0, 0, 1, 0), 99: (0, 1, 1, 0, 0, 0, 1, 1), 100: (0, 1, 1, 0, 0, 1, 0, 0), 101: (0, 1, 1, 0, 0, 1, 0, 1), 102: (0, 1, 1, 0, 0, 1, 1, 0), 103: (0, 1, 1, 0, 0, 1, 1, 1), 104: (0, 1, 1, 0, 1, 0, 0, 0), 105: (0, 1, 1, 0, 1, 0, 0, 1), 106: (0, 1, 1, 0, 1, 0, 1, 0), 107: (0, 1, 1, 0, 1, 0, 1, 1), 108: (0, 1, 1, 0, 1, 1, 0, 0), 109: (0, 1, 1, 0, 1, 1, 0, 1), 110: (0, 1, 1, 0, 1, 1, 1, 0), 111: (0, 1, 1, 0, 1, 1, 1, 1), 112: (0, 1, 1, 1, 0, 0, 0, 0), 113: (0, 1, 1, 1, 0, 0, 0, 1), 114: (0, 1, 1, 1, 0, 0, 1, 0), 115: (0, 1, 1, 1, 0, 0, 1, 1), 116: (0, 1, 1, 1, 0, 1, 0, 0), 117: (0, 1, 1, 1, 0, 1, 0, 1), 118: (0, 1, 1, 1, 0, 1, 1, 0), 119: (0, 1, 1, 1, 0, 1, 1, 1), 120: (0, 1, 1, 1, 1, 0, 0, 0), 121: (0, 1, 1, 1, 1, 0, 0, 1), 122: (0, 1, 1, 1, 1, 0, 1, 0), 123: (0, 1, 1, 1, 1, 0, 1, 1), 124: (0, 1, 1, 1, 1, 1, 0, 0), 125: (0, 1, 1, 1, 1, 1, 0, 1), 126: (0, 1, 1, 1, 1, 1, 1, 0), 127: (0, 1, 1, 1, 1, 1, 1, 1), 128: (1, 0, 0, 0, 0, 0, 0, 0), 129: (1, 0, 0, 0, 0, 0, 0, 1), 130: (1, 0, 0, 0, 0, 0, 1, 0), 131: (1, 0, 0, 0, 0, 0, 1, 1), 132: (1, 0, 0, 0, 0, 1, 0, 0), 133: (1, 0, 0, 0, 0, 1, 0, 1), 134: (1, 0, 0, 0, 0, 1, 1, 0), 135: (1, 0, 0, 0, 0, 1, 1, 1), 136: (1, 0, 0, 0, 1, 0, 0, 0), 137: (1, 0, 0, 0, 1, 0, 0, 1), 138: (1, 0, 0, 0, 1, 0, 1, 0), 139: (1, 0, 0, 0, 1, 0, 1, 1), 140: (1, 0, 0, 0, 1, 1, 0, 0), 141: (1, 0, 0, 0, 1, 1, 0, 1), 142: (1, 0, 0, 0, 1, 1, 1, 0), 143: (1, 0, 0, 0, 1, 1, 1, 1), 144: (1, 0, 0, 1, 0, 0, 0, 0), 145: (1, 0, 0, 1, 0, 0, 0, 1), 146: (1, 0, 0, 1, 0, 0, 1, 0), 147: (1, 0, 0, 1, 0, 0, 1, 1), 148: (1, 0, 0, 1, 0, 1, 0, 0), 149: (1, 0, 0, 1, 0, 1, 0, 1), 150: (1, 0, 0, 1, 0, 1, 1, 0), 151: (1, 0, 0, 1, 0, 1, 1, 1), 152: (1, 0, 0, 1, 1, 0, 0, 0), 153: (1, 0, 0, 1, 1, 0, 0, 1), 154: (1, 0, 0, 1, 1, 0, 1, 0), 155: (1, 0, 0, 1, 1, 0, 1, 1), 156: (1, 0, 0, 1, 1, 1, 0, 0), 157: (1, 0, 0, 1, 1, 1, 0, 1), 158: (1, 0, 0, 1, 1, 1, 1, 0), 159: (1, 0, 0, 1, 1, 1, 1, 1), 160: (1, 0, 1, 0, 0, 0, 0, 0), 161: (1, 0, 1, 0, 0, 0, 0, 1), 162: (1, 0, 1, 0, 0, 0, 1, 0), 163: (1, 0, 1, 0, 0, 0, 1, 1), 164: (1, 0, 1, 0, 0, 1, 0, 0), 165: (1, 0, 1, 0, 0, 1, 0, 1), 166: (1, 0, 1, 0, 0, 1, 1, 0), 167: (1, 0, 1, 0, 0, 1, 1, 1), 168: (1, 0, 1, 0, 1, 0, 0, 0), 169: (1, 0, 1, 0, 1, 0, 0, 1), 170: (1, 0, 1, 0, 1, 0, 1, 0), 171: (1, 0, 1, 0, 1, 0, 1, 1), 172: (1, 0, 1, 0, 1, 1, 0, 0), 173: (1, 0, 1, 0, 1, 1, 0, 1), 174: (1, 0, 1, 0, 1, 1, 1, 0), 175: (1, 0, 1, 0, 1, 1, 1, 1), 176: (1, 0, 1, 1, 0, 0, 0, 0), 177: (1, 0, 1, 1, 0, 0, 0, 1), 178: (1, 0, 1, 1, 0, 0, 1, 0), 179: (1, 0, 1, 1, 0, 0, 1, 1), 180: (1, 0, 1, 1, 0, 1, 0, 0), 181: (1, 0, 1, 1, 0, 1, 0, 1), 182: (1, 0, 1, 1, 0, 1, 1, 0), 183: (1, 0, 1, 1, 0, 1, 1, 1), 184: (1, 0, 1, 1, 1, 0, 0, 0), 185: (1, 0, 1, 1, 1, 0, 0, 1), 186: (1, 0, 1, 1, 1, 0, 1, 0), 187: (1, 0, 1, 1, 1, 0, 1, 1), 188: (1, 0, 1, 1, 1, 1, 0, 0), 189: (1, 0, 1, 1, 1, 1, 0, 1), 190: (1, 0, 1, 1, 1, 1, 1, 0), 191: (1, 0, 1, 1, 1, 1, 1, 1), 192: (1, 1, 0, 0, 0, 0, 0, 0), 193: (1, 1, 0, 0, 0, 0, 0, 1), 194: (1, 1, 0, 0, 0, 0, 1, 0), 195: (1, 1, 0, 0, 0, 0, 1, 1), 196: (1, 1, 0, 0, 0, 1, 0, 0), 197: (1, 1, 0, 0, 0, 1, 0, 1), 198: (1, 1, 0, 0, 0, 1, 1, 0), 199: (1, 1, 0, 0, 0, 1, 1, 1), 200: (1, 1, 0, 0, 1, 0, 0, 0), 201: (1, 1, 0, 0, 1, 0, 0, 1), 202: (1, 1, 0, 0, 1, 0, 1, 0), 203: (1, 1, 0, 0, 1, 0, 1, 1), 204: (1, 1, 0, 0, 1, 1, 0, 0), 205: (1, 1, 0, 0, 1, 1, 0, 1), 206: (1, 1, 0, 0, 1, 1, 1, 0), 207: (1, 1, 0, 0, 1, 1, 1, 1), 208: (1, 1, 0, 1, 0, 0, 0, 0), 209: (1, 1, 0, 1, 0, 0, 0, 1), 210: (1, 1, 0, 1, 0, 0, 1, 0), 211: (1, 1, 0, 1, 0, 0, 1, 1), 212: (1, 1, 0, 1, 0, 1, 0, 0), 213: (1, 1, 0, 1, 0, 1, 0, 1), 214: (1, 1, 0, 1, 0, 1, 1, 0), 215: (1, 1, 0, 1, 0, 1, 1, 1), 216: (1, 1, 0, 1, 1, 0, 0, 0), 217: (1, 1, 0, 1, 1, 0, 0, 1), 218: (1, 1, 0, 1, 1, 0, 1, 0), 219: (1, 1, 0, 1, 1, 0, 1, 1), 220: (1, 1, 0, 1, 1, 1, 0, 0), 221: (1, 1, 0, 1, 1, 1, 0, 1), 222: (1, 1, 0, 1, 1, 1, 1, 0), 223: (1, 1, 0, 1, 1, 1, 1, 1), 224: (1, 1, 1, 0, 0, 0, 0, 0), 225: (1, 1, 1, 0, 0, 0, 0, 1), 226: (1, 1, 1, 0, 0, 0, 1, 0), 227: (1, 1, 1, 0, 0, 0, 1, 1), 228: (1, 1, 1, 0, 0, 1, 0, 0), 229: (1, 1, 1, 0, 0, 1, 0, 1), 230: (1, 1, 1, 0, 0, 1, 1, 0), 231: (1, 1, 1, 0, 0, 1, 1, 1), 232: (1, 1, 1, 0, 1, 0, 0, 0), 233: (1, 1, 1, 0, 1, 0, 0, 1), 234: (1, 1, 1, 0, 1, 0, 1, 0), 235: (1, 1, 1, 0, 1, 0, 1, 1), 236: (1, 1, 1, 0, 1, 1, 0, 0), 237: (1, 1, 1, 0, 1, 1, 0, 1), 238: (1, 1, 1, 0, 1, 1, 1, 0), 239: (1, 1, 1, 0, 1, 1, 1, 1), 240: (1, 1, 1, 1, 0, 0, 0, 0), 241: (1, 1, 1, 1, 0, 0, 0, 1), 242: (1, 1, 1, 1, 0, 0, 1, 0), 243: (1, 1, 1, 1, 0, 0, 1, 1), 244: (1, 1, 1, 1, 0, 1, 0, 0), 245: (1, 1, 1, 1, 0, 1, 0, 1), 246: (1, 1, 1, 1, 0, 1, 1, 0), 247: (1, 1, 1, 1, 0, 1, 1, 1), 248: (1, 1, 1, 1, 1, 0, 0, 0), 249: (1, 1, 1, 1, 1, 0, 0, 1), 250: (1, 1, 1, 1, 1, 0, 1, 0), 251: (1, 1, 1, 1, 1, 0, 1, 1), 252: (1, 1, 1, 1, 1, 1, 0, 0), 253: (1, 1, 1, 1, 1, 1, 0, 1), 254: (1, 1, 1, 1, 1, 1, 1, 0), 255: (1, 1, 1, 1, 1, 1, 1, 1) } BYTETOBIT_LUT = { b'\x00': (0, 0, 0, 0, 0, 0, 0, 0), b'\x01': (0, 0, 0, 0, 0, 0, 0, 1), b'\x02': (0, 0, 0, 0, 0, 0, 1, 0), b'\x03': (0, 0, 0, 0, 0, 0, 1, 1), b'\x04': (0, 0, 0, 0, 0, 1, 0, 0), b'\x05': (0, 0, 0, 0, 0, 1, 0, 1), b'\x06': (0, 0, 0, 0, 0, 1, 1, 0), b'\x07': (0, 0, 0, 0, 0, 1, 1, 1), b'\x08': (0, 0, 0, 0, 1, 0, 0, 0), b'\t': (0, 0, 0, 0, 1, 0, 0, 1), b'\n': (0, 0, 0, 0, 1, 0, 1, 0), b'\x0b': (0, 0, 0, 0, 1, 0, 1, 1), b'\x0c': (0, 0, 0, 0, 1, 1, 0, 0), b'\r': (0, 0, 0, 0, 1, 1, 0, 1), b'\x0e': (0, 0, 0, 0, 1, 1, 1, 0), b'\x0f': (0, 0, 0, 0, 1, 1, 1, 1), b'\x10': (0, 0, 0, 1, 0, 0, 0, 0), b'\x11': (0, 0, 0, 1, 0, 0, 0, 1), b'\x12': (0, 0, 0, 1, 0, 0, 1, 0), b'\x13': (0, 0, 0, 1, 0, 0, 1, 1), b'\x14': (0, 0, 0, 1, 0, 1, 0, 0), b'\x15': (0, 0, 0, 1, 0, 1, 0, 1), b'\x16': (0, 0, 0, 1, 0, 1, 1, 0), b'\x17': (0, 0, 0, 1, 0, 1, 1, 1), b'\x18': (0, 0, 0, 1, 1, 0, 0, 0), b'\x19': (0, 0, 0, 1, 1, 0, 0, 1), b'\x1a': (0, 0, 0, 1, 1, 0, 1, 0), b'\x1b': (0, 0, 0, 1, 1, 0, 1, 1), b'\x1c': (0, 0, 0, 1, 1, 1, 0, 0), b'\x1d': (0, 0, 0, 1, 1, 1, 0, 1), b'\x1e': (0, 0, 0, 1, 1, 1, 1, 0), b'\x1f': (0, 0, 0, 1, 1, 1, 1, 1), b' ': (0, 0, 1, 0, 0, 0, 0, 0), b'!': (0, 0, 1, 0, 0, 0, 0, 1), b'"': (0, 0, 1, 0, 0, 0, 1, 0), b'#': (0, 0, 1, 0, 0, 0, 1, 1), b'$': (0, 0, 1, 0, 0, 1, 0, 0), b'%': (0, 0, 1, 0, 0, 1, 0, 1), b'&': (0, 0, 1, 0, 0, 1, 1, 0), b"'": (0, 0, 1, 0, 0, 1, 1, 1), b'(': (0, 0, 1, 0, 1, 0, 0, 0), b')': (0, 0, 1, 0, 1, 0, 0, 1), b'*': (0, 0, 1, 0, 1, 0, 1, 0), b'+': (0, 0, 1, 0, 1, 0, 1, 1), b',': (0, 0, 1, 0, 1, 1, 0, 0), b'-': (0, 0, 1, 0, 1, 1, 0, 1), b'.': (0, 0, 1, 0, 1, 1, 1, 0), b'/': (0, 0, 1, 0, 1, 1, 1, 1), b'0': (0, 0, 1, 1, 0, 0, 0, 0), b'1': (0, 0, 1, 1, 0, 0, 0, 1), b'2': (0, 0, 1, 1, 0, 0, 1, 0), b'3': (0, 0, 1, 1, 0, 0, 1, 1), b'4': (0, 0, 1, 1, 0, 1, 0, 0), b'5': (0, 0, 1, 1, 0, 1, 0, 1), b'6': (0, 0, 1, 1, 0, 1, 1, 0), b'7': (0, 0, 1, 1, 0, 1, 1, 1), b'8': (0, 0, 1, 1, 1, 0, 0, 0), b'9': (0, 0, 1, 1, 1, 0, 0, 1), b':': (0, 0, 1, 1, 1, 0, 1, 0), b';': (0, 0, 1, 1, 1, 0, 1, 1), b'<': (0, 0, 1, 1, 1, 1, 0, 0), b'=': (0, 0, 1, 1, 1, 1, 0, 1), b'>': (0, 0, 1, 1, 1, 1, 1, 0), b'?': (0, 0, 1, 1, 1, 1, 1, 1), b'@': (0, 1, 0, 0, 0, 0, 0, 0), b'A': (0, 1, 0, 0, 0, 0, 0, 1), b'B': (0, 1, 0, 0, 0, 0, 1, 0), b'C': (0, 1, 0, 0, 0, 0, 1, 1), b'D': (0, 1, 0, 0, 0, 1, 0, 0), b'E': (0, 1, 0, 0, 0, 1, 0, 1), b'F': (0, 1, 0, 0, 0, 1, 1, 0), b'G': (0, 1, 0, 0, 0, 1, 1, 1), b'H': (0, 1, 0, 0, 1, 0, 0, 0), b'I': (0, 1, 0, 0, 1, 0, 0, 1), b'J': (0, 1, 0, 0, 1, 0, 1, 0), b'K': (0, 1, 0, 0, 1, 0, 1, 1), b'L': (0, 1, 0, 0, 1, 1, 0, 0), b'M': (0, 1, 0, 0, 1, 1, 0, 1), b'N': (0, 1, 0, 0, 1, 1, 1, 0), b'O': (0, 1, 0, 0, 1, 1, 1, 1), b'P': (0, 1, 0, 1, 0, 0, 0, 0), b'Q': (0, 1, 0, 1, 0, 0, 0, 1), b'R': (0, 1, 0, 1, 0, 0, 1, 0), b'S': (0, 1, 0, 1, 0, 0, 1, 1), b'T': (0, 1, 0, 1, 0, 1, 0, 0), b'U': (0, 1, 0, 1, 0, 1, 0, 1), b'V': (0, 1, 0, 1, 0, 1, 1, 0), b'W': (0, 1, 0, 1, 0, 1, 1, 1), b'X': (0, 1, 0, 1, 1, 0, 0, 0), b'Y': (0, 1, 0, 1, 1, 0, 0, 1), b'Z': (0, 1, 0, 1, 1, 0, 1, 0), b'[': (0, 1, 0, 1, 1, 0, 1, 1), b'\\': (0, 1, 0, 1, 1, 1, 0, 0), b']': (0, 1, 0, 1, 1, 1, 0, 1), b'^': (0, 1, 0, 1, 1, 1, 1, 0), b'_': (0, 1, 0, 1, 1, 1, 1, 1), b'`': (0, 1, 1, 0, 0, 0, 0, 0), b'a': (0, 1, 1, 0, 0, 0, 0, 1), b'b': (0, 1, 1, 0, 0, 0, 1, 0), b'c': (0, 1, 1, 0, 0, 0, 1, 1), b'd': (0, 1, 1, 0, 0, 1, 0, 0), b'e': (0, 1, 1, 0, 0, 1, 0, 1), b'f': (0, 1, 1, 0, 0, 1, 1, 0), b'g': (0, 1, 1, 0, 0, 1, 1, 1), b'h': (0, 1, 1, 0, 1, 0, 0, 0), b'i': (0, 1, 1, 0, 1, 0, 0, 1), b'j': (0, 1, 1, 0, 1, 0, 1, 0), b'k': (0, 1, 1, 0, 1, 0, 1, 1), b'l': (0, 1, 1, 0, 1, 1, 0, 0), b'm': (0, 1, 1, 0, 1, 1, 0, 1), b'n': (0, 1, 1, 0, 1, 1, 1, 0), b'o': (0, 1, 1, 0, 1, 1, 1, 1), b'p': (0, 1, 1, 1, 0, 0, 0, 0), b'q': (0, 1, 1, 1, 0, 0, 0, 1), b'r': (0, 1, 1, 1, 0, 0, 1, 0), b's': (0, 1, 1, 1, 0, 0, 1, 1), b't': (0, 1, 1, 1, 0, 1, 0, 0), b'u': (0, 1, 1, 1, 0, 1, 0, 1), b'v': (0, 1, 1, 1, 0, 1, 1, 0), b'w': (0, 1, 1, 1, 0, 1, 1, 1), b'x': (0, 1, 1, 1, 1, 0, 0, 0), b'y': (0, 1, 1, 1, 1, 0, 0, 1), b'z': (0, 1, 1, 1, 1, 0, 1, 0), b'{': (0, 1, 1, 1, 1, 0, 1, 1), b'|': (0, 1, 1, 1, 1, 1, 0, 0), b'}': (0, 1, 1, 1, 1, 1, 0, 1), b'~': (0, 1, 1, 1, 1, 1, 1, 0), b'\x7f': (0, 1, 1, 1, 1, 1, 1, 1), b'\x80': (1, 0, 0, 0, 0, 0, 0, 0), b'\x81': (1, 0, 0, 0, 0, 0, 0, 1), b'\x82': (1, 0, 0, 0, 0, 0, 1, 0), b'\x83': (1, 0, 0, 0, 0, 0, 1, 1), b'\x84': (1, 0, 0, 0, 0, 1, 0, 0), b'\x85': (1, 0, 0, 0, 0, 1, 0, 1), b'\x86': (1, 0, 0, 0, 0, 1, 1, 0), b'\x87': (1, 0, 0, 0, 0, 1, 1, 1), b'\x88': (1, 0, 0, 0, 1, 0, 0, 0), b'\x89': (1, 0, 0, 0, 1, 0, 0, 1), b'\x8a': (1, 0, 0, 0, 1, 0, 1, 0), b'\x8b': (1, 0, 0, 0, 1, 0, 1, 1), b'\x8c': (1, 0, 0, 0, 1, 1, 0, 0), b'\x8d': (1, 0, 0, 0, 1, 1, 0, 1), b'\x8e': (1, 0, 0, 0, 1, 1, 1, 0), b'\x8f': (1, 0, 0, 0, 1, 1, 1, 1), b'\x90': (1, 0, 0, 1, 0, 0, 0, 0), b'\x91': (1, 0, 0, 1, 0, 0, 0, 1), b'\x92': (1, 0, 0, 1, 0, 0, 1, 0), b'\x93': (1, 0, 0, 1, 0, 0, 1, 1), b'\x94': (1, 0, 0, 1, 0, 1, 0, 0), b'\x95': (1, 0, 0, 1, 0, 1, 0, 1), b'\x96': (1, 0, 0, 1, 0, 1, 1, 0), b'\x97': (1, 0, 0, 1, 0, 1, 1, 1), b'\x98': (1, 0, 0, 1, 1, 0, 0, 0), b'\x99': (1, 0, 0, 1, 1, 0, 0, 1), b'\x9a': (1, 0, 0, 1, 1, 0, 1, 0), b'\x9b': (1, 0, 0, 1, 1, 0, 1, 1), b'\x9c': (1, 0, 0, 1, 1, 1, 0, 0), b'\x9d': (1, 0, 0, 1, 1, 1, 0, 1), b'\x9e': (1, 0, 0, 1, 1, 1, 1, 0), b'\x9f': (1, 0, 0, 1, 1, 1, 1, 1), b'\xa0': (1, 0, 1, 0, 0, 0, 0, 0), b'\xa1': (1, 0, 1, 0, 0, 0, 0, 1), b'\xa2': (1, 0, 1, 0, 0, 0, 1, 0), b'\xa3': (1, 0, 1, 0, 0, 0, 1, 1), b'\xa4': (1, 0, 1, 0, 0, 1, 0, 0), b'\xa5': (1, 0, 1, 0, 0, 1, 0, 1), b'\xa6': (1, 0, 1, 0, 0, 1, 1, 0), b'\xa7': (1, 0, 1, 0, 0, 1, 1, 1), b'\xa8': (1, 0, 1, 0, 1, 0, 0, 0), b'\xa9': (1, 0, 1, 0, 1, 0, 0, 1), b'\xaa': (1, 0, 1, 0, 1, 0, 1, 0), b'\xab': (1, 0, 1, 0, 1, 0, 1, 1), b'\xac': (1, 0, 1, 0, 1, 1, 0, 0), b'\xad': (1, 0, 1, 0, 1, 1, 0, 1), b'\xae': (1, 0, 1, 0, 1, 1, 1, 0), b'\xaf': (1, 0, 1, 0, 1, 1, 1, 1), b'\xb0': (1, 0, 1, 1, 0, 0, 0, 0), b'\xb1': (1, 0, 1, 1, 0, 0, 0, 1), b'\xb2': (1, 0, 1, 1, 0, 0, 1, 0), b'\xb3': (1, 0, 1, 1, 0, 0, 1, 1), b'\xb4': (1, 0, 1, 1, 0, 1, 0, 0), b'\xb5': (1, 0, 1, 1, 0, 1, 0, 1), b'\xb6': (1, 0, 1, 1, 0, 1, 1, 0), b'\xb7': (1, 0, 1, 1, 0, 1, 1, 1), b'\xb8': (1, 0, 1, 1, 1, 0, 0, 0), b'\xb9': (1, 0, 1, 1, 1, 0, 0, 1), b'\xba': (1, 0, 1, 1, 1, 0, 1, 0), b'\xbb': (1, 0, 1, 1, 1, 0, 1, 1), b'\xbc': (1, 0, 1, 1, 1, 1, 0, 0), b'\xbd': (1, 0, 1, 1, 1, 1, 0, 1), b'\xbe': (1, 0, 1, 1, 1, 1, 1, 0), b'\xbf': (1, 0, 1, 1, 1, 1, 1, 1), b'\xc0': (1, 1, 0, 0, 0, 0, 0, 0), b'\xc1': (1, 1, 0, 0, 0, 0, 0, 1), b'\xc2': (1, 1, 0, 0, 0, 0, 1, 0), b'\xc3': (1, 1, 0, 0, 0, 0, 1, 1), b'\xc4': (1, 1, 0, 0, 0, 1, 0, 0), b'\xc5': (1, 1, 0, 0, 0, 1, 0, 1), b'\xc6': (1, 1, 0, 0, 0, 1, 1, 0), b'\xc7': (1, 1, 0, 0, 0, 1, 1, 1), b'\xc8': (1, 1, 0, 0, 1, 0, 0, 0), b'\xc9': (1, 1, 0, 0, 1, 0, 0, 1), b'\xca': (1, 1, 0, 0, 1, 0, 1, 0), b'\xcb': (1, 1, 0, 0, 1, 0, 1, 1), b'\xcc': (1, 1, 0, 0, 1, 1, 0, 0), b'\xcd': (1, 1, 0, 0, 1, 1, 0, 1), b'\xce': (1, 1, 0, 0, 1, 1, 1, 0), b'\xcf': (1, 1, 0, 0, 1, 1, 1, 1), b'\xd0': (1, 1, 0, 1, 0, 0, 0, 0), b'\xd1': (1, 1, 0, 1, 0, 0, 0, 1), b'\xd2': (1, 1, 0, 1, 0, 0, 1, 0), b'\xd3': (1, 1, 0, 1, 0, 0, 1, 1), b'\xd4': (1, 1, 0, 1, 0, 1, 0, 0), b'\xd5': (1, 1, 0, 1, 0, 1, 0, 1), b'\xd6': (1, 1, 0, 1, 0, 1, 1, 0), b'\xd7': (1, 1, 0, 1, 0, 1, 1, 1), b'\xd8': (1, 1, 0, 1, 1, 0, 0, 0), b'\xd9': (1, 1, 0, 1, 1, 0, 0, 1), b'\xda': (1, 1, 0, 1, 1, 0, 1, 0), b'\xdb': (1, 1, 0, 1, 1, 0, 1, 1), b'\xdc': (1, 1, 0, 1, 1, 1, 0, 0), b'\xdd': (1, 1, 0, 1, 1, 1, 0, 1), b'\xde': (1, 1, 0, 1, 1, 1, 1, 0), b'\xdf': (1, 1, 0, 1, 1, 1, 1, 1), b'\xe0': (1, 1, 1, 0, 0, 0, 0, 0), b'\xe1': (1, 1, 1, 0, 0, 0, 0, 1), b'\xe2': (1, 1, 1, 0, 0, 0, 1, 0), b'\xe3': (1, 1, 1, 0, 0, 0, 1, 1), b'\xe4': (1, 1, 1, 0, 0, 1, 0, 0), b'\xe5': (1, 1, 1, 0, 0, 1, 0, 1), b'\xe6': (1, 1, 1, 0, 0, 1, 1, 0), b'\xe7': (1, 1, 1, 0, 0, 1, 1, 1), b'\xe8': (1, 1, 1, 0, 1, 0, 0, 0), b'\xe9': (1, 1, 1, 0, 1, 0, 0, 1), b'\xea': (1, 1, 1, 0, 1, 0, 1, 0), b'\xeb': (1, 1, 1, 0, 1, 0, 1, 1), b'\xec': (1, 1, 1, 0, 1, 1, 0, 0), b'\xed': (1, 1, 1, 0, 1, 1, 0, 1), b'\xee': (1, 1, 1, 0, 1, 1, 1, 0), b'\xef': (1, 1, 1, 0, 1, 1, 1, 1), b'\xf0': (1, 1, 1, 1, 0, 0, 0, 0), b'\xf1': (1, 1, 1, 1, 0, 0, 0, 1), b'\xf2': (1, 1, 1, 1, 0, 0, 1, 0), b'\xf3': (1, 1, 1, 1, 0, 0, 1, 1), b'\xf4': (1, 1, 1, 1, 0, 1, 0, 0), b'\xf5': (1, 1, 1, 1, 0, 1, 0, 1), b'\xf6': (1, 1, 1, 1, 0, 1, 1, 0), b'\xf7': (1, 1, 1, 1, 0, 1, 1, 1), b'\xf8': (1, 1, 1, 1, 1, 0, 0, 0), b'\xf9': (1, 1, 1, 1, 1, 0, 0, 1), b'\xfa': (1, 1, 1, 1, 1, 0, 1, 0), b'\xfb': (1, 1, 1, 1, 1, 0, 1, 1), b'\xfc': (1, 1, 1, 1, 1, 1, 0, 0), b'\xfd': (1, 1, 1, 1, 1, 1, 0, 1), b'\xfe': (1, 1, 1, 1, 1, 1, 1, 0), b'\xff': (1, 1, 1, 1, 1, 1, 1, 1) } BITTOARR_LUT = { (0, 0, 0, 0, 0, 0, 0, 0) : 0, (0, 0, 0, 0, 0, 0, 0, 1) : 1, (0, 0, 0, 0, 0, 0, 1, 0) : 2, (0, 0, 0, 0, 0, 0, 1, 1) : 3, (0, 0, 0, 0, 0, 1, 0, 0) : 4, (0, 0, 0, 0, 0, 1, 0, 1) : 5, (0, 0, 0, 0, 0, 1, 1, 0) : 6, (0, 0, 0, 0, 0, 1, 1, 1) : 7, (0, 0, 0, 0, 1, 0, 0, 0) : 8, (0, 0, 0, 0, 1, 0, 0, 1) : 9, (0, 0, 0, 0, 1, 0, 1, 0) : 10, (0, 0, 0, 0, 1, 0, 1, 1) : 11, (0, 0, 0, 0, 1, 1, 0, 0) : 12, (0, 0, 0, 0, 1, 1, 0, 1) : 13, (0, 0, 0, 0, 1, 1, 1, 0) : 14, (0, 0, 0, 0, 1, 1, 1, 1) : 15, (0, 0, 0, 1, 0, 0, 0, 0) : 16, (0, 0, 0, 1, 0, 0, 0, 1) : 17, (0, 0, 0, 1, 0, 0, 1, 0) : 18, (0, 0, 0, 1, 0, 0, 1, 1) : 19, (0, 0, 0, 1, 0, 1, 0, 0) : 20, (0, 0, 0, 1, 0, 1, 0, 1) : 21, (0, 0, 0, 1, 0, 1, 1, 0) : 22, (0, 0, 0, 1, 0, 1, 1, 1) : 23, (0, 0, 0, 1, 1, 0, 0, 0) : 24, (0, 0, 0, 1, 1, 0, 0, 1) : 25, (0, 0, 0, 1, 1, 0, 1, 0) : 26, (0, 0, 0, 1, 1, 0, 1, 1) : 27, (0, 0, 0, 1, 1, 1, 0, 0) : 28, (0, 0, 0, 1, 1, 1, 0, 1) : 29, (0, 0, 0, 1, 1, 1, 1, 0) : 30, (0, 0, 0, 1, 1, 1, 1, 1) : 31, (0, 0, 1, 0, 0, 0, 0, 0) : 32, (0, 0, 1, 0, 0, 0, 0, 1) : 33, (0, 0, 1, 0, 0, 0, 1, 0) : 34, (0, 0, 1, 0, 0, 0, 1, 1) : 35, (0, 0, 1, 0, 0, 1, 0, 0) : 36, (0, 0, 1, 0, 0, 1, 0, 1) : 37, (0, 0, 1, 0, 0, 1, 1, 0) : 38, (0, 0, 1, 0, 0, 1, 1, 1) : 39, (0, 0, 1, 0, 1, 0, 0, 0) : 40, (0, 0, 1, 0, 1, 0, 0, 1) : 41, (0, 0, 1, 0, 1, 0, 1, 0) : 42, (0, 0, 1, 0, 1, 0, 1, 1) : 43, (0, 0, 1, 0, 1, 1, 0, 0) : 44, (0, 0, 1, 0, 1, 1, 0, 1) : 45, (0, 0, 1, 0, 1, 1, 1, 0) : 46, (0, 0, 1, 0, 1, 1, 1, 1) : 47, (0, 0, 1, 1, 0, 0, 0, 0) : 48, (0, 0, 1, 1, 0, 0, 0, 1) : 49, (0, 0, 1, 1, 0, 0, 1, 0) : 50, (0, 0, 1, 1, 0, 0, 1, 1) : 51, (0, 0, 1, 1, 0, 1, 0, 0) : 52, (0, 0, 1, 1, 0, 1, 0, 1) : 53, (0, 0, 1, 1, 0, 1, 1, 0) : 54, (0, 0, 1, 1, 0, 1, 1, 1) : 55, (0, 0, 1, 1, 1, 0, 0, 0) : 56, (0, 0, 1, 1, 1, 0, 0, 1) : 57, (0, 0, 1, 1, 1, 0, 1, 0) : 58, (0, 0, 1, 1, 1, 0, 1, 1) : 59, (0, 0, 1, 1, 1, 1, 0, 0) : 60, (0, 0, 1, 1, 1, 1, 0, 1) : 61, (0, 0, 1, 1, 1, 1, 1, 0) : 62, (0, 0, 1, 1, 1, 1, 1, 1) : 63, (0, 1, 0, 0, 0, 0, 0, 0) : 64, (0, 1, 0, 0, 0, 0, 0, 1) : 65, (0, 1, 0, 0, 0, 0, 1, 0) : 66, (0, 1, 0, 0, 0, 0, 1, 1) : 67, (0, 1, 0, 0, 0, 1, 0, 0) : 68, (0, 1, 0, 0, 0, 1, 0, 1) : 69, (0, 1, 0, 0, 0, 1, 1, 0) : 70, (0, 1, 0, 0, 0, 1, 1, 1) : 71, (0, 1, 0, 0, 1, 0, 0, 0) : 72, (0, 1, 0, 0, 1, 0, 0, 1) : 73, (0, 1, 0, 0, 1, 0, 1, 0) : 74, (0, 1, 0, 0, 1, 0, 1, 1) : 75, (0, 1, 0, 0, 1, 1, 0, 0) : 76, (0, 1, 0, 0, 1, 1, 0, 1) : 77, (0, 1, 0, 0, 1, 1, 1, 0) : 78, (0, 1, 0, 0, 1, 1, 1, 1) : 79, (0, 1, 0, 1, 0, 0, 0, 0) : 80, (0, 1, 0, 1, 0, 0, 0, 1) : 81, (0, 1, 0, 1, 0, 0, 1, 0) : 82, (0, 1, 0, 1, 0, 0, 1, 1) : 83, (0, 1, 0, 1, 0, 1, 0, 0) : 84, (0, 1, 0, 1, 0, 1, 0, 1) : 85, (0, 1, 0, 1, 0, 1, 1, 0) : 86, (0, 1, 0, 1, 0, 1, 1, 1) : 87, (0, 1, 0, 1, 1, 0, 0, 0) : 88, (0, 1, 0, 1, 1, 0, 0, 1) : 89, (0, 1, 0, 1, 1, 0, 1, 0) : 90, (0, 1, 0, 1, 1, 0, 1, 1) : 91, (0, 1, 0, 1, 1, 1, 0, 0) : 92, (0, 1, 0, 1, 1, 1, 0, 1) : 93, (0, 1, 0, 1, 1, 1, 1, 0) : 94, (0, 1, 0, 1, 1, 1, 1, 1) : 95, (0, 1, 1, 0, 0, 0, 0, 0) : 96, (0, 1, 1, 0, 0, 0, 0, 1) : 97, (0, 1, 1, 0, 0, 0, 1, 0) : 98, (0, 1, 1, 0, 0, 0, 1, 1) : 99, (0, 1, 1, 0, 0, 1, 0, 0) : 100, (0, 1, 1, 0, 0, 1, 0, 1) : 101, (0, 1, 1, 0, 0, 1, 1, 0) : 102, (0, 1, 1, 0, 0, 1, 1, 1) : 103, (0, 1, 1, 0, 1, 0, 0, 0) : 104, (0, 1, 1, 0, 1, 0, 0, 1) : 105, (0, 1, 1, 0, 1, 0, 1, 0) : 106, (0, 1, 1, 0, 1, 0, 1, 1) : 107, (0, 1, 1, 0, 1, 1, 0, 0) : 108, (0, 1, 1, 0, 1, 1, 0, 1) : 109, (0, 1, 1, 0, 1, 1, 1, 0) : 110, (0, 1, 1, 0, 1, 1, 1, 1) : 111, (0, 1, 1, 1, 0, 0, 0, 0) : 112, (0, 1, 1, 1, 0, 0, 0, 1) : 113, (0, 1, 1, 1, 0, 0, 1, 0) : 114, (0, 1, 1, 1, 0, 0, 1, 1) : 115, (0, 1, 1, 1, 0, 1, 0, 0) : 116, (0, 1, 1, 1, 0, 1, 0, 1) : 117, (0, 1, 1, 1, 0, 1, 1, 0) : 118, (0, 1, 1, 1, 0, 1, 1, 1) : 119, (0, 1, 1, 1, 1, 0, 0, 0) : 120, (0, 1, 1, 1, 1, 0, 0, 1) : 121, (0, 1, 1, 1, 1, 0, 1, 0) : 122, (0, 1, 1, 1, 1, 0, 1, 1) : 123, (0, 1, 1, 1, 1, 1, 0, 0) : 124, (0, 1, 1, 1, 1, 1, 0, 1) : 125, (0, 1, 1, 1, 1, 1, 1, 0) : 126, (0, 1, 1, 1, 1, 1, 1, 1) : 127, (1, 0, 0, 0, 0, 0, 0, 0) : 128, (1, 0, 0, 0, 0, 0, 0, 1) : 129, (1, 0, 0, 0, 0, 0, 1, 0) : 130, (1, 0, 0, 0, 0, 0, 1, 1) : 131, (1, 0, 0, 0, 0, 1, 0, 0) : 132, (1, 0, 0, 0, 0, 1, 0, 1) : 133, (1, 0, 0, 0, 0, 1, 1, 0) : 134, (1, 0, 0, 0, 0, 1, 1, 1) : 135, (1, 0, 0, 0, 1, 0, 0, 0) : 136, (1, 0, 0, 0, 1, 0, 0, 1) : 137, (1, 0, 0, 0, 1, 0, 1, 0) : 138, (1, 0, 0, 0, 1, 0, 1, 1) : 139, (1, 0, 0, 0, 1, 1, 0, 0) : 140, (1, 0, 0, 0, 1, 1, 0, 1) : 141, (1, 0, 0, 0, 1, 1, 1, 0) : 142, (1, 0, 0, 0, 1, 1, 1, 1) : 143, (1, 0, 0, 1, 0, 0, 0, 0) : 144, (1, 0, 0, 1, 0, 0, 0, 1) : 145, (1, 0, 0, 1, 0, 0, 1, 0) : 146, (1, 0, 0, 1, 0, 0, 1, 1) : 147, (1, 0, 0, 1, 0, 1, 0, 0) : 148, (1, 0, 0, 1, 0, 1, 0, 1) : 149, (1, 0, 0, 1, 0, 1, 1, 0) : 150, (1, 0, 0, 1, 0, 1, 1, 1) : 151, (1, 0, 0, 1, 1, 0, 0, 0) : 152, (1, 0, 0, 1, 1, 0, 0, 1) : 153, (1, 0, 0, 1, 1, 0, 1, 0) : 154, (1, 0, 0, 1, 1, 0, 1, 1) : 155, (1, 0, 0, 1, 1, 1, 0, 0) : 156, (1, 0, 0, 1, 1, 1, 0, 1) : 157, (1, 0, 0, 1, 1, 1, 1, 0) : 158, (1, 0, 0, 1, 1, 1, 1, 1) : 159, (1, 0, 1, 0, 0, 0, 0, 0) : 160, (1, 0, 1, 0, 0, 0, 0, 1) : 161, (1, 0, 1, 0, 0, 0, 1, 0) : 162, (1, 0, 1, 0, 0, 0, 1, 1) : 163, (1, 0, 1, 0, 0, 1, 0, 0) : 164, (1, 0, 1, 0, 0, 1, 0, 1) : 165, (1, 0, 1, 0, 0, 1, 1, 0) : 166, (1, 0, 1, 0, 0, 1, 1, 1) : 167, (1, 0, 1, 0, 1, 0, 0, 0) : 168, (1, 0, 1, 0, 1, 0, 0, 1) : 169, (1, 0, 1, 0, 1, 0, 1, 0) : 170, (1, 0, 1, 0, 1, 0, 1, 1) : 171, (1, 0, 1, 0, 1, 1, 0, 0) : 172, (1, 0, 1, 0, 1, 1, 0, 1) : 173, (1, 0, 1, 0, 1, 1, 1, 0) : 174, (1, 0, 1, 0, 1, 1, 1, 1) : 175, (1, 0, 1, 1, 0, 0, 0, 0) : 176, (1, 0, 1, 1, 0, 0, 0, 1) : 177, (1, 0, 1, 1, 0, 0, 1, 0) : 178, (1, 0, 1, 1, 0, 0, 1, 1) : 179, (1, 0, 1, 1, 0, 1, 0, 0) : 180, (1, 0, 1, 1, 0, 1, 0, 1) : 181, (1, 0, 1, 1, 0, 1, 1, 0) : 182, (1, 0, 1, 1, 0, 1, 1, 1) : 183, (1, 0, 1, 1, 1, 0, 0, 0) : 184, (1, 0, 1, 1, 1, 0, 0, 1) : 185, (1, 0, 1, 1, 1, 0, 1, 0) : 186, (1, 0, 1, 1, 1, 0, 1, 1) : 187, (1, 0, 1, 1, 1, 1, 0, 0) : 188, (1, 0, 1, 1, 1, 1, 0, 1) : 189, (1, 0, 1, 1, 1, 1, 1, 0) : 190, (1, 0, 1, 1, 1, 1, 1, 1) : 191, (1, 1, 0, 0, 0, 0, 0, 0) : 192, (1, 1, 0, 0, 0, 0, 0, 1) : 193, (1, 1, 0, 0, 0, 0, 1, 0) : 194, (1, 1, 0, 0, 0, 0, 1, 1) : 195, (1, 1, 0, 0, 0, 1, 0, 0) : 196, (1, 1, 0, 0, 0, 1, 0, 1) : 197, (1, 1, 0, 0, 0, 1, 1, 0) : 198, (1, 1, 0, 0, 0, 1, 1, 1) : 199, (1, 1, 0, 0, 1, 0, 0, 0) : 200, (1, 1, 0, 0, 1, 0, 0, 1) : 201, (1, 1, 0, 0, 1, 0, 1, 0) : 202, (1, 1, 0, 0, 1, 0, 1, 1) : 203, (1, 1, 0, 0, 1, 1, 0, 0) : 204, (1, 1, 0, 0, 1, 1, 0, 1) : 205, (1, 1, 0, 0, 1, 1, 1, 0) : 206, (1, 1, 0, 0, 1, 1, 1, 1) : 207, (1, 1, 0, 1, 0, 0, 0, 0) : 208, (1, 1, 0, 1, 0, 0, 0, 1) : 209, (1, 1, 0, 1, 0, 0, 1, 0) : 210, (1, 1, 0, 1, 0, 0, 1, 1) : 211, (1, 1, 0, 1, 0, 1, 0, 0) : 212, (1, 1, 0, 1, 0, 1, 0, 1) : 213, (1, 1, 0, 1, 0, 1, 1, 0) : 214, (1, 1, 0, 1, 0, 1, 1, 1) : 215, (1, 1, 0, 1, 1, 0, 0, 0) : 216, (1, 1, 0, 1, 1, 0, 0, 1) : 217, (1, 1, 0, 1, 1, 0, 1, 0) : 218, (1, 1, 0, 1, 1, 0, 1, 1) : 219, (1, 1, 0, 1, 1, 1, 0, 0) : 220, (1, 1, 0, 1, 1, 1, 0, 1) : 221, (1, 1, 0, 1, 1, 1, 1, 0) : 222, (1, 1, 0, 1, 1, 1, 1, 1) : 223, (1, 1, 1, 0, 0, 0, 0, 0) : 224, (1, 1, 1, 0, 0, 0, 0, 1) : 225, (1, 1, 1, 0, 0, 0, 1, 0) : 226, (1, 1, 1, 0, 0, 0, 1, 1) : 227, (1, 1, 1, 0, 0, 1, 0, 0) : 228, (1, 1, 1, 0, 0, 1, 0, 1) : 229, (1, 1, 1, 0, 0, 1, 1, 0) : 230, (1, 1, 1, 0, 0, 1, 1, 1) : 231, (1, 1, 1, 0, 1, 0, 0, 0) : 232, (1, 1, 1, 0, 1, 0, 0, 1) : 233, (1, 1, 1, 0, 1, 0, 1, 0) : 234, (1, 1, 1, 0, 1, 0, 1, 1) : 235, (1, 1, 1, 0, 1, 1, 0, 0) : 236, (1, 1, 1, 0, 1, 1, 0, 1) : 237, (1, 1, 1, 0, 1, 1, 1, 0) : 238, (1, 1, 1, 0, 1, 1, 1, 1) : 239, (1, 1, 1, 1, 0, 0, 0, 0) : 240, (1, 1, 1, 1, 0, 0, 0, 1) : 241, (1, 1, 1, 1, 0, 0, 1, 0) : 242, (1, 1, 1, 1, 0, 0, 1, 1) : 243, (1, 1, 1, 1, 0, 1, 0, 0) : 244, (1, 1, 1, 1, 0, 1, 0, 1) : 245, (1, 1, 1, 1, 0, 1, 1, 0) : 246, (1, 1, 1, 1, 0, 1, 1, 1) : 247, (1, 1, 1, 1, 1, 0, 0, 0) : 248, (1, 1, 1, 1, 1, 0, 0, 1) : 249, (1, 1, 1, 1, 1, 0, 1, 0) : 250, (1, 1, 1, 1, 1, 0, 1, 1) : 251, (1, 1, 1, 1, 1, 1, 0, 0) : 252, (1, 1, 1, 1, 1, 1, 0, 1) : 253, (1, 1, 1, 1, 1, 1, 1, 0) : 254, (1, 1, 1, 1, 1, 1, 1, 1) : 255 } BITTOBYTE_LUT = { (0, 0, 0, 0, 0, 0, 0, 0): b'\x00', (0, 0, 0, 0, 0, 0, 0, 1): b'\x01', (0, 0, 0, 0, 0, 0, 1, 0): b'\x02', (0, 0, 0, 0, 0, 0, 1, 1): b'\x03', (0, 0, 0, 0, 0, 1, 0, 0): b'\x04', (0, 0, 0, 0, 0, 1, 0, 1): b'\x05', (0, 0, 0, 0, 0, 1, 1, 0): b'\x06', (0, 0, 0, 0, 0, 1, 1, 1): b'\x07', (0, 0, 0, 0, 1, 0, 0, 0): b'\x08', (0, 0, 0, 0, 1, 0, 0, 1): b'\t', (0, 0, 0, 0, 1, 0, 1, 0): b'\n', (0, 0, 0, 0, 1, 0, 1, 1): b'\x0b', (0, 0, 0, 0, 1, 1, 0, 0): b'\x0c', (0, 0, 0, 0, 1, 1, 0, 1): b'\r', (0, 0, 0, 0, 1, 1, 1, 0): b'\x0e', (0, 0, 0, 0, 1, 1, 1, 1): b'\x0f', (0, 0, 0, 1, 0, 0, 0, 0): b'\x10', (0, 0, 0, 1, 0, 0, 0, 1): b'\x11', (0, 0, 0, 1, 0, 0, 1, 0): b'\x12', (0, 0, 0, 1, 0, 0, 1, 1): b'\x13', (0, 0, 0, 1, 0, 1, 0, 0): b'\x14', (0, 0, 0, 1, 0, 1, 0, 1): b'\x15', (0, 0, 0, 1, 0, 1, 1, 0): b'\x16', (0, 0, 0, 1, 0, 1, 1, 1): b'\x17', (0, 0, 0, 1, 1, 0, 0, 0): b'\x18', (0, 0, 0, 1, 1, 0, 0, 1): b'\x19', (0, 0, 0, 1, 1, 0, 1, 0): b'\x1a', (0, 0, 0, 1, 1, 0, 1, 1): b'\x1b', (0, 0, 0, 1, 1, 1, 0, 0): b'\x1c', (0, 0, 0, 1, 1, 1, 0, 1): b'\x1d', (0, 0, 0, 1, 1, 1, 1, 0): b'\x1e', (0, 0, 0, 1, 1, 1, 1, 1): b'\x1f', (0, 0, 1, 0, 0, 0, 0, 0): b' ', (0, 0, 1, 0, 0, 0, 0, 1): b'!', (0, 0, 1, 0, 0, 0, 1, 0): b'"', (0, 0, 1, 0, 0, 0, 1, 1): b'#', (0, 0, 1, 0, 0, 1, 0, 0): b'$', (0, 0, 1, 0, 0, 1, 0, 1): b'%', (0, 0, 1, 0, 0, 1, 1, 0): b'&', (0, 0, 1, 0, 0, 1, 1, 1): b"'", (0, 0, 1, 0, 1, 0, 0, 0): b'(', (0, 0, 1, 0, 1, 0, 0, 1): b')', (0, 0, 1, 0, 1, 0, 1, 0): b'*', (0, 0, 1, 0, 1, 0, 1, 1): b'+', (0, 0, 1, 0, 1, 1, 0, 0): b',', (0, 0, 1, 0, 1, 1, 0, 1): b'-', (0, 0, 1, 0, 1, 1, 1, 0): b'.', (0, 0, 1, 0, 1, 1, 1, 1): b'/', (0, 0, 1, 1, 0, 0, 0, 0): b'0', (0, 0, 1, 1, 0, 0, 0, 1): b'1', (0, 0, 1, 1, 0, 0, 1, 0): b'2', (0, 0, 1, 1, 0, 0, 1, 1): b'3', (0, 0, 1, 1, 0, 1, 0, 0): b'4', (0, 0, 1, 1, 0, 1, 0, 1): b'5', (0, 0, 1, 1, 0, 1, 1, 0): b'6', (0, 0, 1, 1, 0, 1, 1, 1): b'7', (0, 0, 1, 1, 1, 0, 0, 0): b'8', (0, 0, 1, 1, 1, 0, 0, 1): b'9', (0, 0, 1, 1, 1, 0, 1, 0): b':', (0, 0, 1, 1, 1, 0, 1, 1): b';', (0, 0, 1, 1, 1, 1, 0, 0): b'<', (0, 0, 1, 1, 1, 1, 0, 1): b'=', (0, 0, 1, 1, 1, 1, 1, 0): b'>', (0, 0, 1, 1, 1, 1, 1, 1): b'?', (0, 1, 0, 0, 0, 0, 0, 0): b'@', (0, 1, 0, 0, 0, 0, 0, 1): b'A', (0, 1, 0, 0, 0, 0, 1, 0): b'B', (0, 1, 0, 0, 0, 0, 1, 1): b'C', (0, 1, 0, 0, 0, 1, 0, 0): b'D', (0, 1, 0, 0, 0, 1, 0, 1): b'E', (0, 1, 0, 0, 0, 1, 1, 0): b'F', (0, 1, 0, 0, 0, 1, 1, 1): b'G', (0, 1, 0, 0, 1, 0, 0, 0): b'H', (0, 1, 0, 0, 1, 0, 0, 1): b'I', (0, 1, 0, 0, 1, 0, 1, 0): b'J', (0, 1, 0, 0, 1, 0, 1, 1): b'K', (0, 1, 0, 0, 1, 1, 0, 0): b'L', (0, 1, 0, 0, 1, 1, 0, 1): b'M', (0, 1, 0, 0, 1, 1, 1, 0): b'N', (0, 1, 0, 0, 1, 1, 1, 1): b'O', (0, 1, 0, 1, 0, 0, 0, 0): b'P', (0, 1, 0, 1, 0, 0, 0, 1): b'Q', (0, 1, 0, 1, 0, 0, 1, 0): b'R', (0, 1, 0, 1, 0, 0, 1, 1): b'S', (0, 1, 0, 1, 0, 1, 0, 0): b'T', (0, 1, 0, 1, 0, 1, 0, 1): b'U', (0, 1, 0, 1, 0, 1, 1, 0): b'V', (0, 1, 0, 1, 0, 1, 1, 1): b'W', (0, 1, 0, 1, 1, 0, 0, 0): b'X', (0, 1, 0, 1, 1, 0, 0, 1): b'Y', (0, 1, 0, 1, 1, 0, 1, 0): b'Z', (0, 1, 0, 1, 1, 0, 1, 1): b'[', (0, 1, 0, 1, 1, 1, 0, 0): b'\\', (0, 1, 0, 1, 1, 1, 0, 1): b']', (0, 1, 0, 1, 1, 1, 1, 0): b'^', (0, 1, 0, 1, 1, 1, 1, 1): b'_', (0, 1, 1, 0, 0, 0, 0, 0): b'`', (0, 1, 1, 0, 0, 0, 0, 1): b'a', (0, 1, 1, 0, 0, 0, 1, 0): b'b', (0, 1, 1, 0, 0, 0, 1, 1): b'c', (0, 1, 1, 0, 0, 1, 0, 0): b'd', (0, 1, 1, 0, 0, 1, 0, 1): b'e', (0, 1, 1, 0, 0, 1, 1, 0): b'f', (0, 1, 1, 0, 0, 1, 1, 1): b'g', (0, 1, 1, 0, 1, 0, 0, 0): b'h', (0, 1, 1, 0, 1, 0, 0, 1): b'i', (0, 1, 1, 0, 1, 0, 1, 0): b'j', (0, 1, 1, 0, 1, 0, 1, 1): b'k', (0, 1, 1, 0, 1, 1, 0, 0): b'l', (0, 1, 1, 0, 1, 1, 0, 1): b'm', (0, 1, 1, 0, 1, 1, 1, 0): b'n', (0, 1, 1, 0, 1, 1, 1, 1): b'o', (0, 1, 1, 1, 0, 0, 0, 0): b'p', (0, 1, 1, 1, 0, 0, 0, 1): b'q', (0, 1, 1, 1, 0, 0, 1, 0): b'r', (0, 1, 1, 1, 0, 0, 1, 1): b's', (0, 1, 1, 1, 0, 1, 0, 0): b't', (0, 1, 1, 1, 0, 1, 0, 1): b'u', (0, 1, 1, 1, 0, 1, 1, 0): b'v', (0, 1, 1, 1, 0, 1, 1, 1): b'w', (0, 1, 1, 1, 1, 0, 0, 0): b'x', (0, 1, 1, 1, 1, 0, 0, 1): b'y', (0, 1, 1, 1, 1, 0, 1, 0): b'z', (0, 1, 1, 1, 1, 0, 1, 1): b'{', (0, 1, 1, 1, 1, 1, 0, 0): b'|', (0, 1, 1, 1, 1, 1, 0, 1): b'}', (0, 1, 1, 1, 1, 1, 1, 0): b'~', (0, 1, 1, 1, 1, 1, 1, 1): b'\x7f', (1, 0, 0, 0, 0, 0, 0, 0): b'\x80', (1, 0, 0, 0, 0, 0, 0, 1): b'\x81', (1, 0, 0, 0, 0, 0, 1, 0): b'\x82', (1, 0, 0, 0, 0, 0, 1, 1): b'\x83', (1, 0, 0, 0, 0, 1, 0, 0): b'\x84', (1, 0, 0, 0, 0, 1, 0, 1): b'\x85', (1, 0, 0, 0, 0, 1, 1, 0): b'\x86', (1, 0, 0, 0, 0, 1, 1, 1): b'\x87', (1, 0, 0, 0, 1, 0, 0, 0): b'\x88', (1, 0, 0, 0, 1, 0, 0, 1): b'\x89', (1, 0, 0, 0, 1, 0, 1, 0): b'\x8a', (1, 0, 0, 0, 1, 0, 1, 1): b'\x8b', (1, 0, 0, 0, 1, 1, 0, 0): b'\x8c', (1, 0, 0, 0, 1, 1, 0, 1): b'\x8d', (1, 0, 0, 0, 1, 1, 1, 0): b'\x8e', (1, 0, 0, 0, 1, 1, 1, 1): b'\x8f', (1, 0, 0, 1, 0, 0, 0, 0): b'\x90', (1, 0, 0, 1, 0, 0, 0, 1): b'\x91', (1, 0, 0, 1, 0, 0, 1, 0): b'\x92', (1, 0, 0, 1, 0, 0, 1, 1): b'\x93', (1, 0, 0, 1, 0, 1, 0, 0): b'\x94', (1, 0, 0, 1, 0, 1, 0, 1): b'\x95', (1, 0, 0, 1, 0, 1, 1, 0): b'\x96', (1, 0, 0, 1, 0, 1, 1, 1): b'\x97', (1, 0, 0, 1, 1, 0, 0, 0): b'\x98', (1, 0, 0, 1, 1, 0, 0, 1): b'\x99', (1, 0, 0, 1, 1, 0, 1, 0): b'\x9a', (1, 0, 0, 1, 1, 0, 1, 1): b'\x9b', (1, 0, 0, 1, 1, 1, 0, 0): b'\x9c', (1, 0, 0, 1, 1, 1, 0, 1): b'\x9d', (1, 0, 0, 1, 1, 1, 1, 0): b'\x9e', (1, 0, 0, 1, 1, 1, 1, 1): b'\x9f', (1, 0, 1, 0, 0, 0, 0, 0): b'\xa0', (1, 0, 1, 0, 0, 0, 0, 1): b'\xa1', (1, 0, 1, 0, 0, 0, 1, 0): b'\xa2', (1, 0, 1, 0, 0, 0, 1, 1): b'\xa3', (1, 0, 1, 0, 0, 1, 0, 0): b'\xa4', (1, 0, 1, 0, 0, 1, 0, 1): b'\xa5', (1, 0, 1, 0, 0, 1, 1, 0): b'\xa6', (1, 0, 1, 0, 0, 1, 1, 1): b'\xa7', (1, 0, 1, 0, 1, 0, 0, 0): b'\xa8', (1, 0, 1, 0, 1, 0, 0, 1): b'\xa9', (1, 0, 1, 0, 1, 0, 1, 0): b'\xaa', (1, 0, 1, 0, 1, 0, 1, 1): b'\xab', (1, 0, 1, 0, 1, 1, 0, 0): b'\xac', (1, 0, 1, 0, 1, 1, 0, 1): b'\xad', (1, 0, 1, 0, 1, 1, 1, 0): b'\xae', (1, 0, 1, 0, 1, 1, 1, 1): b'\xaf', (1, 0, 1, 1, 0, 0, 0, 0): b'\xb0', (1, 0, 1, 1, 0, 0, 0, 1): b'\xb1', (1, 0, 1, 1, 0, 0, 1, 0): b'\xb2', (1, 0, 1, 1, 0, 0, 1, 1): b'\xb3', (1, 0, 1, 1, 0, 1, 0, 0): b'\xb4', (1, 0, 1, 1, 0, 1, 0, 1): b'\xb5', (1, 0, 1, 1, 0, 1, 1, 0): b'\xb6', (1, 0, 1, 1, 0, 1, 1, 1): b'\xb7', (1, 0, 1, 1, 1, 0, 0, 0): b'\xb8', (1, 0, 1, 1, 1, 0, 0, 1): b'\xb9', (1, 0, 1, 1, 1, 0, 1, 0): b'\xba', (1, 0, 1, 1, 1, 0, 1, 1): b'\xbb', (1, 0, 1, 1, 1, 1, 0, 0): b'\xbc', (1, 0, 1, 1, 1, 1, 0, 1): b'\xbd', (1, 0, 1, 1, 1, 1, 1, 0): b'\xbe', (1, 0, 1, 1, 1, 1, 1, 1): b'\xbf', (1, 1, 0, 0, 0, 0, 0, 0): b'\xc0', (1, 1, 0, 0, 0, 0, 0, 1): b'\xc1', (1, 1, 0, 0, 0, 0, 1, 0): b'\xc2', (1, 1, 0, 0, 0, 0, 1, 1): b'\xc3', (1, 1, 0, 0, 0, 1, 0, 0): b'\xc4', (1, 1, 0, 0, 0, 1, 0, 1): b'\xc5', (1, 1, 0, 0, 0, 1, 1, 0): b'\xc6', (1, 1, 0, 0, 0, 1, 1, 1): b'\xc7', (1, 1, 0, 0, 1, 0, 0, 0): b'\xc8', (1, 1, 0, 0, 1, 0, 0, 1): b'\xc9', (1, 1, 0, 0, 1, 0, 1, 0): b'\xca', (1, 1, 0, 0, 1, 0, 1, 1): b'\xcb', (1, 1, 0, 0, 1, 1, 0, 0): b'\xcc', (1, 1, 0, 0, 1, 1, 0, 1): b'\xcd', (1, 1, 0, 0, 1, 1, 1, 0): b'\xce', (1, 1, 0, 0, 1, 1, 1, 1): b'\xcf', (1, 1, 0, 1, 0, 0, 0, 0): b'\xd0', (1, 1, 0, 1, 0, 0, 0, 1): b'\xd1', (1, 1, 0, 1, 0, 0, 1, 0): b'\xd2', (1, 1, 0, 1, 0, 0, 1, 1): b'\xd3', (1, 1, 0, 1, 0, 1, 0, 0): b'\xd4', (1, 1, 0, 1, 0, 1, 0, 1): b'\xd5', (1, 1, 0, 1, 0, 1, 1, 0): b'\xd6', (1, 1, 0, 1, 0, 1, 1, 1): b'\xd7', (1, 1, 0, 1, 1, 0, 0, 0): b'\xd8', (1, 1, 0, 1, 1, 0, 0, 1): b'\xd9', (1, 1, 0, 1, 1, 0, 1, 0): b'\xda', (1, 1, 0, 1, 1, 0, 1, 1): b'\xdb', (1, 1, 0, 1, 1, 1, 0, 0): b'\xdc', (1, 1, 0, 1, 1, 1, 0, 1): b'\xdd', (1, 1, 0, 1, 1, 1, 1, 0): b'\xde', (1, 1, 0, 1, 1, 1, 1, 1): b'\xdf', (1, 1, 1, 0, 0, 0, 0, 0): b'\xe0', (1, 1, 1, 0, 0, 0, 0, 1): b'\xe1', (1, 1, 1, 0, 0, 0, 1, 0): b'\xe2', (1, 1, 1, 0, 0, 0, 1, 1): b'\xe3', (1, 1, 1, 0, 0, 1, 0, 0): b'\xe4', (1, 1, 1, 0, 0, 1, 0, 1): b'\xe5', (1, 1, 1, 0, 0, 1, 1, 0): b'\xe6', (1, 1, 1, 0, 0, 1, 1, 1): b'\xe7', (1, 1, 1, 0, 1, 0, 0, 0): b'\xe8', (1, 1, 1, 0, 1, 0, 0, 1): b'\xe9', (1, 1, 1, 0, 1, 0, 1, 0): b'\xea', (1, 1, 1, 0, 1, 0, 1, 1): b'\xeb', (1, 1, 1, 0, 1, 1, 0, 0): b'\xec', (1, 1, 1, 0, 1, 1, 0, 1): b'\xed', (1, 1, 1, 0, 1, 1, 1, 0): b'\xee', (1, 1, 1, 0, 1, 1, 1, 1): b'\xef', (1, 1, 1, 1, 0, 0, 0, 0): b'\xf0', (1, 1, 1, 1, 0, 0, 0, 1): b'\xf1', (1, 1, 1, 1, 0, 0, 1, 0): b'\xf2', (1, 1, 1, 1, 0, 0, 1, 1): b'\xf3', (1, 1, 1, 1, 0, 1, 0, 0): b'\xf4', (1, 1, 1, 1, 0, 1, 0, 1): b'\xf5', (1, 1, 1, 1, 0, 1, 1, 0): b'\xf6', (1, 1, 1, 1, 0, 1, 1, 1): b'\xf7', (1, 1, 1, 1, 1, 0, 0, 0): b'\xf8', (1, 1, 1, 1, 1, 0, 0, 1): b'\xf9', (1, 1, 1, 1, 1, 0, 1, 0): b'\xfa', (1, 1, 1, 1, 1, 0, 1, 1): b'\xfb', (1, 1, 1, 1, 1, 1, 0, 0): b'\xfc', (1, 1, 1, 1, 1, 1, 0, 1): b'\xfd', (1, 1, 1, 1, 1, 1, 1, 0): b'\xfe', (1, 1, 1, 1, 1, 1, 1, 1): b'\xff' } def bytes_to_bitlist(buf): """Convert a bytes string to a list of bits -0 or 1- Args: buf (bytes) : bytes string Returns: bitlist (list of integer) : list of 0 and 1 Raises: KeyError : if `s' is not bytes """ bitlist = [] [bitlist.extend(BYTETOBIT_LUT[val]) for val in buf] return bitlist def bitlist_to_bytes(bitlist): """Convert an iterable of bits -0 or 1- to a bytes string Args: bitlist (iterable of integer) : iterable of 0 and 1 Returns: buf (bytes) : bytes string Raises: KeyError : if bitlist contains invalid values """ buf = [] # cast the iterable to a tuple for dict LU bitlist = tuple(bitlist) trail = len(bitlist) % 8 if trail: [buf.append(BITTOBYTE_LUT[bitlist[i:i+8]]) \ for i in range(0, len(bitlist)-trail, 8)] buf.append(BITTOBYTE_LUT[bitlist[-trail:] + (8-trail) * (0, )] ) return b''.join(buf) else: [buf.append(BITTOBYTE_LUT[bitlist[i:i+8]]) \ for i in range(0, len(bitlist), 8)] return b''.join(buf) #------------------------------------------------------------------------------# # bytes buffer functions #------------------------------------------------------------------------------# def bytes_lshift(buf=b'', bitlen=0): """Shift left a bytes buffer of `bitlen' bits Args: buf (bytes) : bytes string bitlen (int) : length in bits Returns: buf_sh (bytes) : shifted bytes string """ if bitlen > 8*len(buf): bitlen = 8*len(buf) byte_len, bit_len = bitlen>>3, bitlen%8 # full byte shifting buf_sh = buf[byte_len:] bl = 8 * len(buf_sh) # bit shifting if bitlen: return uint_to_bytes((bytes_to_uint(buf_sh, bl) << bit_len) & \ ((1<>3, bitlen%8 if len_bit: if len(buf) < len_byte + 1: raise(PycrateErr('bytes buffer not long enough')) else: return int(hexlify(buf[:len_byte+1]), 16) >> (8-len_bit) else: if len(buf) < len_byte: raise(PycrateErr('bytes buffer not long enough')) elif len_byte == 1: return ord(buf[0]) elif len_byte == 2: return unpack('>H', buf[:2])[0] elif len_byte == 4: return unpack('>I', buf[:4])[0] elif len_byte == 8: return unpack('>Q', buf[:8])[0] else: return int(hexlify(buf[:len_byte]), 16) def uint_to_bytes(val, bitlen=1): """Convert an unsigned integer to a bytes buffer of given length in bits, uint with most significant bit leftmost Args: val (integer) : unsigned integer bitlen (integer) : length in bits Returns: buf (bytes) : bytes string Raises: PycrateErr : if `bitlen' is not strictly positive """ # Python2 built-in conversion: hex to str decoding if bitlen <= 0: raise(PycrateErr('bitlen must be strictly positive')) len_byte, len_bit = bitlen>>3, bitlen % 8 # if len_bit, need padding bits appended rightmost if val >= (1<H', val) elif len_byte == 4: return pack('>I', val) elif len_byte == 8: return pack('>Q', val) else: len_nib = len_byte * 2 else: val <<= (8-len_bit) len_nib = (len_byte + 1) * 2 h = hex(val)[2:] if h[-1] == 'L': h= h[:-1] if len(h) < len_nib: h = (len_nib - len(h)) * '0' + h return unhexlify(h) def bytes_to_uint_le(buf, bitlen=1): """Convert the leftmost bits of a bytes buffer to an unsigned integer in little endian format (least significant byte leftmost) Args: buf (bytes) : bytes string bitlen (integer) : length in bits, must be a multiple of 8 Returns: uint (integer) : unsigned integer value Raises: PycrateErr : if `bitlen' is not strictly positive or not byte-aligned or if `buf' is not long enough """ # leverage Python2 built-in conversion: str to hex encoding if bitlen <= 0 or bitlen%8: raise(PycrateErr('invalid bitlen for little endian uint: {0}'\ .format(bitlen))) len_byte = bitlen>>3 # if len(buf) < len_byte: raise(PycrateErr('bytes buffer not long enough')) elif len_byte == 1: return ord(buf[0]) elif len_byte == 2: return unpack('>3 # if val >= (1< [a, b, c, d ...] where Y = a + (b << X) + (c << 2X) + (d << 3X) ... or decompose_uint(X', Y) -> [a, b, c, d ...] where Y = a + b * X' + c * X'^2 + d*X'^3 ... Args: mul (integer) : unsigned integer used as factor val (integer) : unsigned integer to be factored Returns: dec (list of integer) : list of factors """ # benefit from Python built-in int() which is pretty fast if mul == 2: dec = map(int, bin(val)[2:]) dec.reverse() return dec elif mul == 16 and val >= 10000000000: h = hex(val)[2:] if h[-1] == 'L': h = h[:-1] dec = map(int, h, len(h)*[16]) dec.reverse() return dec # decompose simply by iterative division else: dec = [ int(val % mul) ] while val >= mul: val //= mul dec.append( int(val % mul) ) return dec def swap_uint(uint, bitlen): """Swap the endianness of the unsigned integer uint of length bitlen Args: uint (unsigned integer) bitlen (unsigned integer) Returns: uint (unsigned integer) """ if bitlen < 0 or bitlen % 8: raise(PycrateErr('invalid bitlen of little endian uint: {0}'\ .format(bitlen))) len_byte, ret = bitlen>>3, [] for i in range(len_byte>>1): bi = 8*i rbi = bitlen-8-bi ret.append( (uint & (0xff<> (rbi-bi) ) if len_byte % 2: ret.append( uint & (0xff<<(8*(len_byte>>1))) ) return sum(ret) #------------------------------------------------------------------------------# # concatenation #------------------------------------------------------------------------------# def bytes_lshift_bnd(buf, buflen=8, shlen=1): """Shift left of `shlen' bits the bytes buffer `buf' of length in bits `buflen' with 0 < shlen < 8 provide the heading value of `shlen' bits that leaves the buffer the shifted buffer, fully byte-aligned (can be of size 0) the trailing value of remaining bits (can be None) Args: buf (bytes) : bytes string buflen (integer) : length in bits of the bytes buffer shlen (integer) : value of the shift, between 1 and 7 Returns: tuple of (integer, bytes, integer or None) """ if buflen <= shlen: # only heading bits head = (ord(buf[0]) & (0x100 - (1<<(8-buflen)))) >> (8-shlen) return head, b'', None elif buflen < 8 + shlen: # only heading and trailing bits head = ord(buf[0]) >> (8-shlen) buf = bytes_lshift(buf, shlen) trail = ord(buf[0]) & (0x100 - (1<<(8-buflen+shlen))) return head, b'', trail # head = ord(buf[0])>>(8-shlen) buf = bytes_lshift(buf, shlen) restlen = buflen % 8 if restlen == 0: trail = ord(buf[-1]) buf = buf[:-1] elif restlen < shlen: trail = ord(buf[-2]) & (0x100 - (1<<(shlen-restlen))) buf = buf[:-2] elif restlen == shlen: trail = None buf = buf[:-1] else: trail = ord(buf[-1]) & (0x100 - (1<<(8+shlen-restlen))) buf = buf[:-1] return head, buf, trail TYPE_BYTES = 1 TYPE_UINT = 2 TYPE_INT = 3 TYPE_UINT_LE = 12 TYPE_INT_LE = 13 # FMT_INT = { 8 : 'b', 16: 'h', 32: 'i', 64: 'q' } FMT_UINT = { 8 : 'B', 16: 'H', 32: 'I', 64: 'Q' } FMT_LUT = { 2: FMT_UINT, 3: FMT_INT, 12: FMT_UINT, 13: FMT_INT } # PACK_FMT_BE = 0 PACK_FMT_LE = 1 def pack_val(*val): """Packs heterogenous bytes buffer and (un)signed integers, all with a given length in bits, to a resulting bytes buffer Args: val (tuple) : tuple of (type, value, bitlen) type must be TYPE_BYTES, TYPE_UINT or TYPE_INT value must be a bytes string or an integer, according to type bitlen must be an integer over 0 warning: for TYPE_UINT_LE and TYPE_INT_LE, bitlen must be a multiple of 8 (hence the value will be byte-aligned) Returns: buf (tuple of (bytes, integer)) : a tuple containing the actual resulting bytes string and the length in bits Example: pack_val( (TYPE_BYTES, 'AAAA\xC0', 34), (TYPE_UINT, 2500, 32), (TYPE_UINT, 10000000000, 64), (TYPE_INT, -1, 8), (TYPE_BYTES, 'bbbbbb', 48), (TYPE_INT, -2000, 54), (TYPE_UINT, 1, 2), (TYPE_BYTES, '\0', 7) ) -> (b'AAAA\xc0\x00\x02q\x00\x00\x00\x00\x95\x02\xf9\x00?'\ '\xd8\x98\x98\x98\x98\x98?\xff\xff\xff\xff\xf80@\x00', 249) """ # global resulting byte buffer concat, len_bit = [], 0 # junction byte when unaligned values are concatenated junc = None # cumulative processing for int / uint pack_fmt, pack_val, pack_end, pack_len = None, None, PACK_FMT_BE, 0 for v in val: #print('val : {0}, {1}, {2}'.format(*v)) #print('pack : fmt {0}, val {1}'.format(pack_fmt, pack_val)) #print('junc : {0}'.format(junc)) #print('len_bit : {0}'.format(len_bit)) #print('concat : {0}'.format(concat)) #print('') # rest_bit = len_bit%8 # # 0) bypass null field if v[2] == 0: pass # # 1) cumulative processing for 8/16/32/64 bits big endian (u)int elif v[0] in (TYPE_INT, TYPE_UINT) and v[2] in (8, 16, 32, 64): if pack_end == PACK_FMT_LE and pack_fmt is not None: # a) append previous integers that were little endian pack_buf = pack(''.join(pack_fmt), *pack_val) if rest_bit == 0: # a.a) aligned access assert( junc is None ) concat.append(pack_buf) len_bit += pack_len else: # a.b) unaligned access assert( 0 <= junc < 256 ) head, buf, trail = bytes_lshift_bnd(pack_buf, pack_len, 8-rest_bit) # complete the junction byte and append it # with the shifted buffer len_bit += pack_len if buf: # heading bits, buffer and potential trailing bits concat.extend( (chr(junc + head), buf) ) junc = trail elif trail is not None: # heading bits and potential trailing bits concat.append( chr(junc + head) ) junc = trail elif not len_bit % 8: # heading bits only concat.append( chr(junc + head) ) junc = None else: # no buf and no trailing bits junc += head pack_fmt, pack_val, pack_end, pack_len = None, None, PACK_FMT_BE, 0 # # b) accumulate value into pack_val if pack_fmt is None: pack_fmt = ['>', FMT_LUT[v[0]][v[2]]] pack_val = [v[1]] else: pack_fmt.append( FMT_LUT[v[0]][v[2]] ) pack_val.append( v[1] ) pack_len += v[2] # # 2) cumulative processing for 8/16/32/64 bits little endian (u)int elif v[0] in (TYPE_INT_LE, TYPE_UINT_LE) and v[2] in (8, 16, 32, 64): # a) append previous integers if were big endian if pack_end == PACK_FMT_BE and pack_fmt is not None: pack_buf = pack(''.join(pack_fmt), *pack_val) if rest_bit == 0: # a.a) aligned access assert( junc is None ) concat.append(pack_buf) len_bit += pack_len else: # a.b) unaligned access assert( 0 <= junc < 256 ) head, buf, trail = bytes_lshift_bnd(pack_buf, pack_len, 8-rest_bit) # complete the junction byte and append it # with the shifted buffer len_bit += pack_len if buf: # heading bits, buffer and potential trailing bits concat.extend( (chr(junc + head), buf) ) junc = trail elif trail is not None: # heading bits and potential trailing bits concat.append( chr(junc + head) ) junc = trail elif not len_bit % 8: # heading bits only concat.append( chr(junc + head) ) junc = None else: # no buf and no trailing bits junc += head pack_fmt, pack_val, pack_end, pack_len = None, None, PACK_FMT_BE, 0 # # b) accumulate value into pack_val if pack_fmt is None: pack_end = PACK_FMT_LE pack_fmt = ['<', FMT_LUT[v[0]][v[2]]] pack_val = [v[1]] else: pack_fmt.append( FMT_LUT[v[0]][v[2]] ) pack_val.append( v[1] ) pack_len += v[2] # # 3) standard processing for bytes buffer elif v[0] == TYPE_BYTES: # a) append pack_val first, if exist if pack_fmt is not None: pack_buf = pack(''.join(pack_fmt), *pack_val) if rest_bit == 0: # a.a) aligned access assert( junc is None ) concat.append(pack_buf) len_bit += pack_len # concat.append(v[1][:v[2]>>3]) if v[2]%8: # remaining bits goes to junction byte junc = ord(v[1][v[2]>>3]) & (0x100 - (1<<(8-v[2]%8))) len_bit += v[2] # else: # a.b) unaligned access assert( 0 <= junc < 256 ) if v[2] % 8: buf = pack_buf + v[1][:1+(v[2]>>3)] else: buf = pack_buf + v[1][:v[2]>>3] buflen = pack_len + v[2] head, buf, trail = bytes_lshift_bnd(buf, buflen, 8-rest_bit) # complete the junction byte and append it # with the shifted buffer len_bit += buflen if buf: # heading bits, buffer and potential trailing bits concat.extend( (chr(junc + head), buf) ) junc = trail elif trail is not None: # heading bits and potential trailing bits concat.append( chr(junc + head) ) junc = trail elif not len_bit % 8: # heading bits only concat.append( chr(junc + head) ) junc = None else: # no buf and no trailing bits junc += head # pack_fmt, pack_val, pack_end, pack_len = None, None, PACK_FMT_BE, 0 # # b) nothing to pack elif rest_bit == 0: # b.a) aligned access assert( junc is None ) if v[2] < 8: junc = ord(v[1][0]) & (0x100 - (1<<(8-v[2]))) else: concat.append( v[1][:v[2]>>3] ) if v[2] % 8: # remaining bits goes to junction byte junc = ord(v[1][v[2]>>3]) & (0x100 - (1<<(8-v[2]%8))) len_bit += v[2] # else: # b.b) unaligned access assert( 0 <= junc < 256 ) if v[2] % 8: head, buf, trail = bytes_lshift_bnd(v[1][:1+(v[2]>>3)], v[2], 8-rest_bit) else: head, buf, trail = bytes_lshift_bnd(v[1][:v[2]>>3], v[2], 8-rest_bit) # complete the junction byte and append it # with the shifted buffer len_bit += v[2] if buf: # heading bits, buffer and potential trailing bits concat.extend( (chr(junc + head), buf) ) junc = trail elif trail is not None: # heading bits and potential trailing bits concat.append( chr(junc + head) ) junc = trail elif not len_bit % 8: # heading bits only concat.append( chr(junc + head) ) junc = None else: # no buf and no trailing bits junc += head # # 4) standard processing for uint elif v[0] == TYPE_UINT: # a) append pack_val first, if exist if pack_fmt is not None: pack_buf = pack(''.join(pack_fmt), *pack_val) if rest_bit == 0: # a.a) aligned access assert( junc is None ) concat.append(pack_buf) len_bit += pack_len # buf = uint_to_bytes(v[1], v[2]) concat.append(buf[:v[2]>>3]) if v[2]%8: # remaining bits goes to junction byte junc = ord(buf[v[2]>>3]) len_bit += v[2] # else: # a.b) unaligned access assert( 0 <= junc < 256 ) # first shift the existing packed buffer # TODO: this may be faster to shift integer values before # packing them; however, this will break their format and # cause me more headache head, buf, trail = bytes_lshift_bnd(pack_buf, pack_len, 8-rest_bit) if buf: concat.extend( (chr(junc + head), buf) ) else: concat.append( chr(junc + head) ) # pack_buf is always byte-aligned, # so there are always trailing bits junc = trail u = v[1] & ((1<>lb)) ) if lb >= 8: # body of the uint value lt = lb%8 if lt == 0: # no trailing bits concat.append( uint_to_bytes(u&((1<>lt, lb-lt) ) junc = (u&((1<= (1<>3]) if v[2]%8: # remaining bits goes to junction byte junc = ord(buf[v[2]>>3]) len_bit += v[2] # else: # b.b) unaligned access assert( 0 <= junc < 256 ) u = v[1] & ((1<>lb)) ) if lb >= 8: # body of the uint value lt = lb%8 if lt == 0: # no trailing bits concat.append( uint_to_bytes(u&((1<>lt, lb-lt) ) junc = (u&((1<= 0: u = v[1]&((1<>3]) if v[2]%8: # remaining bits goes to junction byte junc = ord(buf[v[2]>>3]) len_bit += v[2] # else: # a.b) unaligned access assert( 0 <= junc < 256 ) # first shift the existing packed buffer # TODO: this may be faster to shift integer values before # packing them; however, this will break their format and # cause me more headache head, buf, trail = bytes_lshift_bnd(pack_buf, pack_len, 8-rest_bit) if buf: concat.extend( (chr(junc + head), buf) ) else: concat.append( chr(junc + head) ) # pack_buf is always byte-aligned, # so there are always trailing bits junc = trail # # heading bits from the uint value to pack if v[2] < 8-rest_bit: junc += u << (8-rest_bit-v[2]) elif v[2] == 8-rest_bit: concat.append( chr(junc + u) ) junc = None else: lb = v[2]-8+rest_bit concat.append( chr(junc + (u>>lb)) ) if lb >= 8: # body of the uint value lt = lb%8 if lt == 0: # no trailing bits concat.append( uint_to_bytes(u&((1<>lt, lb-lt) ) junc = (u&((1<>3]) if v[2]%8: # remaining bits goes to junction byte junc = ord(buf[v[2]>>3]) len_bit += v[2] # else: # b.b) unaligned access assert( 0 <= junc < 256 ) # heading bits from the uint value to pack if v[2] < 8-rest_bit: junc += u << (8-rest_bit-v[2]) elif v[2] == 8-rest_bit: concat.append( chr(junc + u) ) junc = None else: lb = v[2]-8+rest_bit concat.append( chr(junc + (u>>lb)) ) if lb >= 8: # body of the uint value lt = lb%8 if lt == 0: # no trailing bits concat.append( uint_to_bytes(u&((1<>lt, lb-lt) ) junc = (u&((1<= 0: u = v[1]&((1<