# -*- coding: utf-8 -*- from mylibs.constant import * # ecl: Error Correction Level(L,M,Q,H) def encode(ecl, str): mode_encoding = { 'numeric': numeric_encoding, 'alphanumeric': alphanumeric_encoding, 'byte': byte_encoding, 'kanji': kanji_encoding } ver, mode = analyse(ecl, str) code = mode_indicator[mode] + get_cci(ver, mode, str) + mode_encoding[mode](str) # Add a Terminator rqbits = 8 * required_bytes[ver-1][lindex[ecl]] b = rqbits - len(code) code += '0000' if b >= 4 else '0' * b # Make the Length a Multiple of 8 while len(code) % 8 != 0: code += '0' # Add Pad Bytes if the String is Still too Short while len(code) < rqbits: code += '1110110000010001' if rqbits - len(code) >= 16 else '11101100' data_code = [code[i:i+8] for i in range(len(code)) if i%8 == 0] data_code = [int(i,2) for i in data_code] g = grouping_list[ver-1][lindex[ecl]] data_codewords, i = [], 0 for n in range(g[0]): data_codewords.append(data_code[i:i+g[1]]) i += g[1] for n in range(g[2]): data_codewords.append(data_code[i:i+g[3]]) i += g[3] return ver, data_codewords def analyse(ecl, str): if all(i in num_list for i in str): mode = 'numeric' elif all(i in alphanum_list for i in str): mode = 'alphanumeric' elif all(ord(i.encode('iso-8859-1')) for i in str): mode = 'byte' m = mindex[mode] l = len(str) for i in range(40): if char_cap[ecl][i][m] > l: ver = i + 1 break return ver, mode def numeric_encoding(str): str_list = [str[i:i+3] for i in range(len(str)) if i%3 == 0] code_list = [bin(int(i)) for i in str_list] code = '' for i in code_list: code += i[2:] return code def alphanumeric_encoding(str): code_list = [alphanum_list.index(i) for i in str] code = '' for i in range(1, len(code_list), 2): c = bin(code_list[i-1] * 45 + code_list[i])[2:] c = '0'*(11-len(c)) + c code += c if i != len(code_list) - 1: c = bin(code_list[-1])[2:] c = '0'*(6-len(c)) + c code += c return code def byte_encoding(str): code = '' for i in str: c = bin(ord(i.encode('iso-8859-1')))[2:] c = '0'*(8-len(c)) + c code += c return code def kanji_encoding(str): pass # cci: character count indicator def get_cci(ver, mode, str): if 1 <= ver <= 9: cci_len = (10, 9, 8, 8)[mindex[mode]] elif 10 <= ver <= 26: cci_len = (12, 11, 16, 10)[mindex[mode]] else: cci_len = (14, 13, 16, 12)[mindex[mode]] cci = bin(len(str))[2:] cci = '0' * (cci_len - len(cci)) + cci return cci if __name__ == '__main__': # test: c,m = encode('M', 'HELLO WORLD') print(c,m) print(bool(m=='00100000010110110000101101111000110100010111001011011100010011010100001101000000111011000001000111101100')) print(len(m)) print(all(grouping_list[v][l][3]==0 or grouping_list[v][l][3]-1==grouping_list[v][l][1] for v in range(40) for l in range(4)))