You've already forked amazing-qr
mirror of
https://github.com/x-hw/amazing-qr.git
synced 2025-07-09 01:05:34 +02:00
117 lines
3.2 KiB
Python
117 lines
3.2 KiB
Python
# -*- 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))) |