qrencoder.py 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130
  1. # QRCode for Python
  2. #
  3. # Support for Kanji, Hanzi, ECI, FNC1 and Structurded append,
  4. # and optimizations by Anders Hammarquist <iko@openend.se>
  5. #
  6. # Copyright (c) 2014 Open End AB http://www.openend.se/
  7. #
  8. # Ported from the Javascript library by Sam Curren
  9. #
  10. # QRCode for Javascript
  11. # http://d-project.googlecode.com/svn/trunk/misc/qrcode/js/qrcode.js
  12. #
  13. # Copyright (c) 2009 Kazuhiko Arase
  14. #
  15. # URL: http://www.d-project.com/
  16. #
  17. # Licensed under the MIT license:
  18. # http://www.opensource.org/licenses/mit-license.php
  19. #
  20. # The word "QR Code" is registered trademark of
  21. # DENSO WAVE INCORPORATED
  22. # http://www.denso-wave.com/qrcode/faqpatent-e.html
  23. import re
  24. import itertools
  25. try:
  26. from itertools import zip_longest
  27. except:
  28. from itertools import izip_longest as zip_longest
  29. try:
  30. unicode
  31. except NameError:
  32. # No unicode in Python 3
  33. unicode = str
  34. class QR:
  35. valid = None
  36. bits = None
  37. group = 0
  38. def __init__(self, data):
  39. if self.valid and not self.valid(data):
  40. raise ValueError
  41. self.data = data
  42. def __len__(self):
  43. return len(self.data)
  44. @property
  45. def bitlength(self):
  46. if self.bits is None:
  47. return 0
  48. q, r = divmod(len(self), len(self.bits))
  49. return q * sum(self.bits) + sum(self.bits[:r])
  50. def getLengthBits(self, ver):
  51. if 0 < ver < 10:
  52. return self.lengthbits[0]
  53. elif ver < 27:
  54. return self.lengthbits[1]
  55. elif ver < 41:
  56. return self.lengthbits[2]
  57. raise ValueError("Unknown version: " + ver)
  58. def getLength(self):
  59. return len(self.data)
  60. def __repr__(self):
  61. return repr(self.data)
  62. def write_header(self, buffer, version):
  63. buffer.put(self.mode, 4)
  64. lenbits = self.getLengthBits(version)
  65. if lenbits:
  66. buffer.put(len(self.data), lenbits )
  67. def write(self, buffer, version):
  68. self.write_header(buffer, version)
  69. for g in zip_longest(*[iter(self.data)] * self.group):
  70. bits = 0
  71. n = 0
  72. for i in range(self.group):
  73. if g[i] is not None:
  74. n *= len(self.chars)
  75. n += self.chars.index(g[i])
  76. bits += self.bits[i]
  77. buffer.put(n, bits)
  78. class QRNumber(QR):
  79. valid = re.compile(u'[0-9]*$').match
  80. chars = u'0123456789'
  81. bits = (4,3,3)
  82. group = 3
  83. mode = 0x1
  84. lengthbits = (10, 12, 14)
  85. class QRAlphaNum(QR):
  86. valid = re.compile(u'[-0-9A-Z $%*+./:]*$').match
  87. chars = u'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:'
  88. bits = (6,5)
  89. group = 2
  90. mode = 0x2
  91. lengthbits = (9, 11, 13)
  92. class QR8bitByte(QR):
  93. bits = (8,)
  94. group = 1
  95. mode = 0x4
  96. lengthbits = (8, 16, 16)
  97. def __init__(self, data):
  98. if isinstance(data, unicode):
  99. self.data = data.encode('utf-8') # XXX This really needs an ECI too
  100. else:
  101. self.data = data # It'd better be byte data
  102. def write(self, buffer, version):
  103. self.write_header(buffer, version)
  104. for c in self.data:
  105. if isinstance(c, str):
  106. c = ord(c)
  107. buffer.put(c, 8)
  108. class QRKanji(QR):
  109. bits = (13,)
  110. group = 1
  111. mode = 0x8
  112. lengthbits = (8, 10, 12)
  113. def __init__(self, data):
  114. try:
  115. self.data = self.unicode_to_qrkanji(data)
  116. except UnicodeEncodeError:
  117. raise ValueError('Not valid kanji')
  118. def unicode_to_qrkanji(self, data):
  119. codes = []
  120. for i,c in enumerate(data):
  121. try:
  122. c = c.encode('shift-jis')
  123. try:
  124. c,d = map(ord, c)
  125. except TypeError:
  126. # Python 3
  127. c,d = c
  128. except UnicodeEncodeError as e:
  129. raise UnicodeEncodeError('qrkanji', data, i, i+1, e.args[4])
  130. except ValueError:
  131. raise UnicodeEncodeError('qrkanji', data, i, i+1,
  132. 'illegal multibyte sequence')
  133. c = c << 8 | d
  134. if 0x8140 <= c <=0x9ffc:
  135. c -= 0x8140
  136. c = (((c & 0xff00) >> 8) * 0xc0) + (c & 0xff)
  137. elif 0xe040 <= c <= 0xebbf:
  138. c -= 0xc140
  139. c = (((c & 0xff00) >> 8) * 0xc0) + (c & 0xff)
  140. else:
  141. raise UnicodeEncodeError('qrkanji', data, i, i+1,
  142. 'illegal multibyte sequence')
  143. codes.append(c)
  144. return codes
  145. def write(self, buffer, version):
  146. self.write_header(buffer, version)
  147. for d in self.data:
  148. buffer.put(d, 13)
  149. class QRHanzi(QR):
  150. bits = (13,)
  151. group = 1
  152. mode = 0xD
  153. lengthbits = (8, 10, 12)
  154. def __init__(self, data):
  155. try:
  156. self.data = self.unicode_to_qrhanzi(data)
  157. except UnicodeEncodeError:
  158. raise ValueError('Not valid hanzi')
  159. def unicode_to_qrhanzi(self, data):
  160. codes = []
  161. for i,c in enumerate(data):
  162. try:
  163. c = c.encode('gb2312')
  164. try:
  165. c,d = map(ord, c)
  166. except TypeError:
  167. # Python 3
  168. c,d = c
  169. except UnicodeEncodeError as e:
  170. raise UnicodeEncodeError('qrhanzi', data, i, i+1, e.args[4])
  171. except ValueError:
  172. raise UnicodeEncodeError('qrhanzi', data, i, i+1,
  173. 'illegal multibyte sequence')
  174. c = c << 8 | d
  175. if 0xa1a1 <= c <=0xaafe:
  176. c -= 0xa1a1
  177. c = (((c & 0xff00) >> 8) * 0x60) + (c & 0xff)
  178. elif 0xb0a1 <= c <= 0xfafe:
  179. c -= 0xa6a1
  180. c = (((c & 0xff00) >> 8) * 0x60) + (c & 0xff)
  181. else:
  182. raise UnicodeEncodeError('qrhanzi', data, i, i+1,
  183. 'illegal multibyte sequence')
  184. codes.append(c)
  185. return codes
  186. def write_header(self, buffer, version):
  187. buffer.put(self.mode, 4)
  188. buffer.put(1, 4) # Subset 1: GB2312 encoding
  189. lenbits = self.getLengthBits(version)
  190. if lenbits:
  191. buffer.put(len(self.data), lenbits )
  192. def write(self, buffer, version):
  193. self.write_header(buffer, version)
  194. for d in self.data:
  195. buffer.put(d, 13)
  196. # Special modes
  197. class QRECI(QR):
  198. mode = 0x7
  199. lengthbits = (0, 0, 0)
  200. def __init__(self, data):
  201. if not 0 < data < 999999:
  202. # Spec says 999999, format supports up to 0x1fffff = 2097151
  203. raise ValueError("ECI out of range")
  204. self.data = data
  205. def write(self, buffer, version):
  206. self.write_header(buffer, version)
  207. if self.data <= 0x7f:
  208. buffer.put(self.data, 8)
  209. elif self.data <= 0x3fff:
  210. buffer.put(self.data | 0x8000, 16)
  211. elif self.data <= 0x1fffff:
  212. buffer.put(self.data | 0xC00000, 24)
  213. class QRStructAppend(QR):
  214. mode = 0x3
  215. lengthbits = (0, 0, 0)
  216. def __init__(self, part, total, parity):
  217. if not 0 < part <= 16:
  218. raise ValueError("part out of range [1,16]")
  219. if not 0 < total <= 16:
  220. raise ValueError("total out of range [1,16]")
  221. self.part = part
  222. self.total = total
  223. self.parity = parity
  224. def write(self, buffer, version):
  225. self.write_header(buffer, version)
  226. buffer.put(self.part, 4)
  227. buffer.put(self.total, 4)
  228. buffer.put(self.parity, 8)
  229. class QRFNC1First(QR):
  230. mode = 0x5
  231. lengthbits = (0, 0, 0)
  232. def __init__(self):
  233. pass
  234. def write(self, buffer, version):
  235. self.write_header(buffer, version)
  236. class QRFNC1Second(QR):
  237. valid = re.compile('^([A-Za-z]|[0-9][0-9])$').match
  238. mode = 0x9
  239. lengthbits = (0, 0, 0)
  240. def write(self, buffer, version):
  241. self.write_header(buffer, version)
  242. d = self.data
  243. if len(d) == 1:
  244. d = ord(d) + 100
  245. else:
  246. d = int(d)
  247. buffer.put(d, 8)
  248. class QRCode:
  249. def __init__(self, version, errorCorrectLevel):
  250. self.version = version
  251. self.errorCorrectLevel = errorCorrectLevel
  252. self.modules = None
  253. self.moduleCount = 0
  254. self.dataCache = None
  255. self.dataList = []
  256. def addData(self, data):
  257. if isinstance(data, QR):
  258. newData = data
  259. else:
  260. for conv in (QRNumber, QRAlphaNum, QRKanji, QR8bitByte):
  261. try:
  262. newData = conv(data)
  263. break
  264. except ValueError:
  265. pass
  266. else:
  267. raise ValueError
  268. self.dataList.append(newData)
  269. self.dataCache = None
  270. def isDark(self, row, col):
  271. return self.modules[row][col]
  272. def getModuleCount(self):
  273. return self.moduleCount
  274. def calculate_version(self):
  275. # Calculate version for data to fit the QR Code capacity
  276. for version in range(1, 40):
  277. rsBlocks = QRRSBlock.getRSBlocks(version, self.errorCorrectLevel)
  278. totalDataCount = sum(block.dataCount for block in rsBlocks)
  279. length = 0
  280. for data in self.dataList:
  281. length += 4
  282. length += data.getLengthBits(version)
  283. length += data.bitlength
  284. if length <= totalDataCount * 8:
  285. break
  286. return version
  287. def make(self):
  288. if self.version is None:
  289. self.version = self.calculate_version()
  290. self.makeImpl(False, self.getBestMaskPattern())
  291. def makeImpl(self, test, maskPattern):
  292. self.moduleCount = self.version * 4 + 17
  293. self.modules = [ [False] * self.moduleCount
  294. for x in range(self.moduleCount) ]
  295. self.setupPositionProbePattern(0, 0)
  296. self.setupPositionProbePattern(self.moduleCount - 7, 0)
  297. self.setupPositionProbePattern(0, self.moduleCount - 7)
  298. self.setupPositionAdjustPattern()
  299. self.setupTimingPattern()
  300. self.setupTypeInfo(test, maskPattern)
  301. if (self.version >= 7):
  302. self.setupTypeNumber(test)
  303. if (self.dataCache == None):
  304. self.dataCache = QRCode.createData(self.version,
  305. self.errorCorrectLevel,
  306. self.dataList)
  307. self.mapData(self.dataCache, maskPattern)
  308. _positionProbePattern = [
  309. [True, True, True, True, True, True, True],
  310. [True, False, False, False, False, False, True],
  311. [True, False, True, True, True, False, True],
  312. [True, False, True, True, True, False, True],
  313. [True, False, True, True, True, False, True],
  314. [True, False, False, False, False, False, True],
  315. [True, True, True, True, True, True, True],
  316. ]
  317. def setupPositionProbePattern(self, row, col):
  318. if row == 0:
  319. self.modules[row+7][col:col+7] = [False] * 7
  320. if col == 0:
  321. self.modules[row+7][col+7] = False
  322. else:
  323. self.modules[row+7][col-1] = False
  324. else:
  325. # col == 0
  326. self.modules[row-1][col:col+8] = [False] * 8
  327. for r, data in enumerate(self._positionProbePattern):
  328. self.modules[row+r][col:col+7] = data
  329. if col == 0:
  330. self.modules[row+r][col+7] = False
  331. else:
  332. self.modules[row+r][col-1] = False
  333. def getBestMaskPattern(self):
  334. minLostPoint = 0
  335. pattern = 0
  336. for i in range(8):
  337. self.makeImpl(True, i);
  338. lostPoint = QRUtil.getLostPoint(self);
  339. if (i == 0 or minLostPoint > lostPoint):
  340. minLostPoint = lostPoint
  341. pattern = i
  342. return pattern
  343. def setupTimingPattern(self):
  344. for r in range(8, self.moduleCount - 8):
  345. self.modules[r][6] = (r % 2 == 0)
  346. self.modules[6][8:self.moduleCount - 8] = itertools.islice(
  347. itertools.cycle([True, False]), self.moduleCount - 16)
  348. _positionAdjustPattern = [
  349. [True, True, True, True, True],
  350. [True, False, False, False, True],
  351. [True, False, True, False, True],
  352. [True, False, False, False, True],
  353. [True, True, True, True, True],
  354. ]
  355. def setupPositionAdjustPattern(self):
  356. pos = QRUtil.getPatternPosition(self.version)
  357. maxpos = self.moduleCount - 8
  358. for row, col in itertools.product(pos, pos):
  359. if col <= 8 and (row <= 8 or row >= maxpos):
  360. continue
  361. elif col >= maxpos and row <= 8:
  362. continue
  363. for r, data in enumerate(self._positionAdjustPattern):
  364. self.modules[row + r - 2][col-2:col+3] = data
  365. def setupTypeNumber(self, test):
  366. bits = QRUtil.getBCHTypeNumber(self.version)
  367. for i in range(18):
  368. mod = (not test and ( (bits >> i) & 1) == 1)
  369. self.modules[i // 3][i % 3 + self.moduleCount - 8 - 3] = mod;
  370. for i in range(18):
  371. mod = (not test and ( (bits >> i) & 1) == 1)
  372. self.modules[i % 3 + self.moduleCount - 8 - 3][i // 3] = mod;
  373. def setupTypeInfo(self, test, maskPattern):
  374. data = (self.errorCorrectLevel << 3) | maskPattern
  375. bits = QRUtil.getBCHTypeInfo(data)
  376. # vertical
  377. for i in range(15):
  378. mod = (not test and ( (bits >> i) & 1) == 1)
  379. if (i < 6):
  380. self.modules[i][8] = mod
  381. elif (i < 8):
  382. self.modules[i + 1][8] = mod
  383. else:
  384. self.modules[self.moduleCount - 15 + i][8] = mod
  385. # horizontal
  386. for i in range(15):
  387. mod = (not test and ( (bits >> i) & 1) == 1);
  388. if (i < 8):
  389. self.modules[8][self.moduleCount - i - 1] = mod
  390. elif (i < 9):
  391. self.modules[8][15 - i - 1 + 1] = mod
  392. else:
  393. self.modules[8][15 - i - 1] = mod
  394. # fixed module
  395. self.modules[self.moduleCount - 8][8] = (not test)
  396. def _dataPosIterator(self):
  397. cols = itertools.chain(range(self.moduleCount - 1, 6, -2),
  398. range(5, 0, -2))
  399. rows = (list(range(9, self.moduleCount - 8)),
  400. list(itertools.chain(range(6), range(7, self.moduleCount))),
  401. list(range(9, self.moduleCount)))
  402. rrows = tuple( list(reversed(r)) for r in rows)
  403. ppos = QRUtil.getPatternPosition(self.version)
  404. ppos = set(itertools.chain.from_iterable(
  405. (p-2, p-1, p, p+1, p+2) for p in ppos))
  406. maxpos = self.moduleCount - 11
  407. for col in cols:
  408. rows, rrows = rrows, rows
  409. if col <= 8: rowidx = 0
  410. elif col >= self.moduleCount - 8: rowidx = 2
  411. else: rowidx = 1
  412. for row in rows[rowidx]:
  413. for c in range(2):
  414. c = col - c
  415. if self.version >= 7:
  416. if row < 6 and c >= self.moduleCount - 11:
  417. continue
  418. elif col < 6 and row >= self.moduleCount - 11:
  419. continue
  420. if row in ppos and c in ppos:
  421. if not (row < 11 and (c < 11 or c > maxpos) or
  422. c < 11 and (row < 11 or row > maxpos)):
  423. continue
  424. yield (c, row)
  425. _dataPosList = None
  426. def dataPosIterator(self):
  427. if not self._dataPosList:
  428. self._dataPosList = list(self._dataPosIterator())
  429. return self._dataPosList
  430. def _dataBitIterator(self, data):
  431. for byte in data:
  432. for bit in [0x80, 0x40, 0x20, 0x10,
  433. 0x08, 0x04, 0x02, 0x01]:
  434. yield bool(byte & bit)
  435. _dataBitList = None
  436. def dataBitIterator(self, data):
  437. if not self._dataBitList:
  438. self._dataBitList = list(self._dataBitIterator(data))
  439. return iter(self._dataBitList)
  440. def mapData(self, data, maskPattern):
  441. bits = self.dataBitIterator(data)
  442. mask = QRUtil.getMask(maskPattern)
  443. for (col, row), dark in zip_longest(self.dataPosIterator(), bits,
  444. fillvalue=False):
  445. self.modules[row][col] = dark ^ mask(row, col)
  446. PAD0 = 0xEC
  447. PAD1 = 0x11
  448. @staticmethod
  449. def createData(version, errorCorrectLevel, dataList):
  450. rsBlocks = QRRSBlock.getRSBlocks(version, errorCorrectLevel)
  451. buffer = QRBitBuffer();
  452. for data in dataList:
  453. data.write(buffer, version)
  454. # calc num max data.
  455. totalDataCount = 0;
  456. for block in rsBlocks:
  457. totalDataCount += block.dataCount
  458. if (buffer.getLengthInBits() > totalDataCount * 8):
  459. raise Exception("code length overflow. (%d > %d)" %
  460. (buffer.getLengthInBits(), totalDataCount * 8))
  461. # end code
  462. if (buffer.getLengthInBits() + 4 <= totalDataCount * 8):
  463. buffer.put(0, 4)
  464. # padding
  465. while (buffer.getLengthInBits() % 8 != 0):
  466. buffer.putBit(False)
  467. # padding
  468. while (True):
  469. if (buffer.getLengthInBits() >= totalDataCount * 8):
  470. break
  471. buffer.put(QRCode.PAD0, 8)
  472. if (buffer.getLengthInBits() >= totalDataCount * 8):
  473. break
  474. buffer.put(QRCode.PAD1, 8)
  475. return QRCode.createBytes(buffer, rsBlocks)
  476. @staticmethod
  477. def createBytes(buffer, rsBlocks):
  478. offset = 0
  479. maxDcCount = 0
  480. maxEcCount = 0
  481. totalCodeCount = 0
  482. dcdata = []
  483. ecdata = []
  484. for block in rsBlocks:
  485. totalCodeCount += block.totalCount
  486. dcCount = block.dataCount
  487. ecCount = block.totalCount - dcCount
  488. maxDcCount = max(maxDcCount, dcCount)
  489. maxEcCount = max(maxEcCount, ecCount)
  490. dcdata.append(buffer.buffer[offset:offset+dcCount])
  491. offset += dcCount
  492. rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount)
  493. rawPoly = QRPolynomial(dcdata[-1], rsPoly.getLength() - 1)
  494. modPoly = rawPoly.mod(rsPoly)
  495. rLen = rsPoly.getLength() - 1
  496. mLen = modPoly.getLength()
  497. ecdata.append([ (modPoly.get(i) if i >= 0 else 0)
  498. for i in range(mLen - rLen, mLen) ])
  499. data = [ d for dd in itertools.chain(
  500. zip_longest(*dcdata), zip_longest(*ecdata))
  501. for d in dd if d is not None]
  502. return data
  503. class QRErrorCorrectLevel:
  504. L = 1
  505. M = 0
  506. Q = 3
  507. H = 2
  508. class QRMaskPattern:
  509. PATTERN000 = 0
  510. PATTERN001 = 1
  511. PATTERN010 = 2
  512. PATTERN011 = 3
  513. PATTERN100 = 4
  514. PATTERN101 = 5
  515. PATTERN110 = 6
  516. PATTERN111 = 7
  517. class QRUtil(object):
  518. PATTERN_POSITION_TABLE = [
  519. [],
  520. [6, 18],
  521. [6, 22],
  522. [6, 26],
  523. [6, 30],
  524. [6, 34],
  525. [6, 22, 38],
  526. [6, 24, 42],
  527. [6, 26, 46],
  528. [6, 28, 50],
  529. [6, 30, 54],
  530. [6, 32, 58],
  531. [6, 34, 62],
  532. [6, 26, 46, 66],
  533. [6, 26, 48, 70],
  534. [6, 26, 50, 74],
  535. [6, 30, 54, 78],
  536. [6, 30, 56, 82],
  537. [6, 30, 58, 86],
  538. [6, 34, 62, 90],
  539. [6, 28, 50, 72, 94],
  540. [6, 26, 50, 74, 98],
  541. [6, 30, 54, 78, 102],
  542. [6, 28, 54, 80, 106],
  543. [6, 32, 58, 84, 110],
  544. [6, 30, 58, 86, 114],
  545. [6, 34, 62, 90, 118],
  546. [6, 26, 50, 74, 98, 122],
  547. [6, 30, 54, 78, 102, 126],
  548. [6, 26, 52, 78, 104, 130],
  549. [6, 30, 56, 82, 108, 134],
  550. [6, 34, 60, 86, 112, 138],
  551. [6, 30, 58, 86, 114, 142],
  552. [6, 34, 62, 90, 118, 146],
  553. [6, 30, 54, 78, 102, 126, 150],
  554. [6, 24, 50, 76, 102, 128, 154],
  555. [6, 28, 54, 80, 106, 132, 158],
  556. [6, 32, 58, 84, 110, 136, 162],
  557. [6, 26, 54, 82, 110, 138, 166],
  558. [6, 30, 58, 86, 114, 142, 170]
  559. ]
  560. G15 = ((1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) |
  561. (1 << 0))
  562. G18 = ((1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) |
  563. (1 << 5) | (1 << 2) | (1 << 0))
  564. G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1)
  565. @staticmethod
  566. def getBCHTypeInfo(data):
  567. d = data << 10;
  568. while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0):
  569. d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) -
  570. QRUtil.getBCHDigit(QRUtil.G15) ) )
  571. return ( (data << 10) | d) ^ QRUtil.G15_MASK
  572. @staticmethod
  573. def getBCHTypeNumber(data):
  574. d = data << 12;
  575. while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0):
  576. d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) -
  577. QRUtil.getBCHDigit(QRUtil.G18) ) )
  578. return (data << 12) | d
  579. @staticmethod
  580. def getBCHDigit(data):
  581. digit = 0;
  582. while (data != 0):
  583. digit += 1
  584. data >>= 1
  585. return digit
  586. @staticmethod
  587. def getPatternPosition(version):
  588. return QRUtil.PATTERN_POSITION_TABLE[version - 1]
  589. maskPattern = {
  590. 0: lambda i,j: (i + j) % 2 == 0,
  591. 1: lambda i,j: i % 2 == 0,
  592. 2: lambda i,j: j % 3 == 0,
  593. 3: lambda i,j: (i + j) % 3 == 0,
  594. 4: lambda i,j: (i // 2 + j // 3) % 2 == 0,
  595. 5: lambda i,j: (i*j)%2 + (i*j)%3 == 0,
  596. 6: lambda i,j: ( (i * j) % 2 + (i * j) % 3) % 2 == 0,
  597. 7: lambda i,j: ( (i * j) % 3 + (i + j) % 2) % 2 == 0
  598. }
  599. @classmethod
  600. def getMask(cls, maskPattern):
  601. return cls.maskPattern[maskPattern]
  602. @staticmethod
  603. def getErrorCorrectPolynomial(errorCorrectLength):
  604. a = QRPolynomial([1], 0);
  605. for i in range(errorCorrectLength):
  606. a = a.multiply(QRPolynomial([1, QRMath.gexp(i)], 0) )
  607. return a
  608. @classmethod
  609. def maskScoreRule1vert(cls, modules):
  610. score = 0
  611. lastCount = [0]
  612. lastRow = None
  613. for row in modules:
  614. # Vertical patterns
  615. if lastRow:
  616. changed = [a ^ b for a,b in zip(row, lastRow)]
  617. scores = [a and (b-4+3) for a,b in
  618. zip_longest(changed, lastCount, fillvalue=0)
  619. if b >= 4]
  620. score += sum(scores)
  621. lastCount = [0 if a else b + 1
  622. for a,b in zip_longest(changed, lastCount,
  623. fillvalue=0)]
  624. lastRow = row
  625. score += sum([b-4+3 for b in lastCount if b >= 4]) # final counts
  626. return score
  627. @classmethod
  628. def maskScoreRule2(cls, modules):
  629. score = 0
  630. lastRow = modules[0]
  631. for row in modules[1:]:
  632. lastCol0, lastCol1 = row[0], lastRow[0]
  633. for col0, col1 in zip(row[1:], lastRow[1:]):
  634. if col0 == col1 == lastCol0 == lastCol1:
  635. score += 3
  636. lastCol0, lastCol1 = col0, col1
  637. lastRow = row
  638. return score
  639. @classmethod
  640. def maskScoreRule3hor(
  641. cls, modules,
  642. pattern = [True, False, True, True, True, False, True,
  643. False, False, False, False]):
  644. patternlen = len(pattern)
  645. score = 0
  646. for row in modules:
  647. j = 0
  648. maxj = len(row) - patternlen
  649. while j < maxj:
  650. if row[j:j+patternlen] == pattern:
  651. score += 40
  652. j += patternlen
  653. else:
  654. j += 1
  655. return score
  656. @classmethod
  657. def maskScoreRule4(cls, modules):
  658. cellCount = len(modules)**2
  659. count = sum(sum(row) for row in modules)
  660. return 10 * (abs(100 * count // cellCount - 50) // 5)
  661. @classmethod
  662. def getLostPoint(cls, qrCode):
  663. lostPoint = 0;
  664. # LEVEL1
  665. lostPoint += cls.maskScoreRule1vert(qrCode.modules)
  666. lostPoint += cls.maskScoreRule1vert(zip(*qrCode.modules))
  667. # LEVEL2
  668. lostPoint += cls.maskScoreRule2(qrCode.modules)
  669. # LEVEL3
  670. lostPoint += cls.maskScoreRule3hor(qrCode.modules)
  671. lostPoint += cls.maskScoreRule3hor(zip(*qrCode.modules))
  672. # LEVEL4
  673. lostPoint += cls.maskScoreRule4(qrCode.modules)
  674. return lostPoint
  675. class QRMath:
  676. @staticmethod
  677. def glog(n):
  678. if (n < 1):
  679. raise Exception("glog(" + n + ")")
  680. return LOG_TABLE[n];
  681. @staticmethod
  682. def gexp(n):
  683. while n < 0:
  684. n += 255
  685. while n >= 256:
  686. n -= 255
  687. return EXP_TABLE[n];
  688. EXP_TABLE = [x for x in range(256)]
  689. LOG_TABLE = [x for x in range(256)]
  690. for i in range(8):
  691. EXP_TABLE[i] = 1 << i;
  692. for i in range(8, 256):
  693. EXP_TABLE[i] = (EXP_TABLE[i - 4] ^ EXP_TABLE[i - 5] ^
  694. EXP_TABLE[i - 6] ^ EXP_TABLE[i - 8])
  695. for i in range(255):
  696. LOG_TABLE[EXP_TABLE[i] ] = i
  697. class QRPolynomial:
  698. def __init__(self, num, shift):
  699. if (len(num) == 0):
  700. raise Exception(len(num) + "/" + shift)
  701. offset = 0
  702. while offset < len(num) and num[offset] == 0:
  703. offset += 1
  704. self.num = num[offset:] + [0]*shift
  705. def get(self, index):
  706. return self.num[index]
  707. def getLength(self):
  708. return len(self.num)
  709. def multiply(self, e):
  710. num = [0] * (self.getLength() + e.getLength() - 1);
  711. for i in range(self.getLength()):
  712. for j in range(e.getLength()):
  713. num[i + j] ^= QRMath.gexp(QRMath.glog(self.get(i) ) +
  714. QRMath.glog(e.get(j) ) )
  715. return QRPolynomial(num, 0);
  716. def mod(self, e):
  717. if (self.getLength() < e.getLength()):
  718. return self;
  719. ratio = QRMath.glog(self.num[0] ) - QRMath.glog(e.num[0] )
  720. num = [nn ^ QRMath.gexp(QRMath.glog(en) + ratio)
  721. for nn,en in zip(self.num, e.num)]
  722. num += self.num[e.getLength():]
  723. # recursive call
  724. return QRPolynomial(num, 0).mod(e);
  725. class QRRSBlock:
  726. RS_BLOCK_TABLE = [
  727. # L
  728. # M
  729. # Q
  730. # H
  731. # 1
  732. [1, 26, 19],
  733. [1, 26, 16],
  734. [1, 26, 13],
  735. [1, 26, 9],
  736. # 2
  737. [1, 44, 34],
  738. [1, 44, 28],
  739. [1, 44, 22],
  740. [1, 44, 16],
  741. # 3
  742. [1, 70, 55],
  743. [1, 70, 44],
  744. [2, 35, 17],
  745. [2, 35, 13],
  746. # 4
  747. [1, 100, 80],
  748. [2, 50, 32],
  749. [2, 50, 24],
  750. [4, 25, 9],
  751. # 5
  752. [1, 134, 108],
  753. [2, 67, 43],
  754. [2, 33, 15, 2, 34, 16],
  755. [2, 33, 11, 2, 34, 12],
  756. # 6
  757. [2, 86, 68],
  758. [4, 43, 27],
  759. [4, 43, 19],
  760. [4, 43, 15],
  761. # 7
  762. [2, 98, 78],
  763. [4, 49, 31],
  764. [2, 32, 14, 4, 33, 15],
  765. [4, 39, 13, 1, 40, 14],
  766. # 8
  767. [2, 121, 97],
  768. [2, 60, 38, 2, 61, 39],
  769. [4, 40, 18, 2, 41, 19],
  770. [4, 40, 14, 2, 41, 15],
  771. # 9
  772. [2, 146, 116],
  773. [3, 58, 36, 2, 59, 37],
  774. [4, 36, 16, 4, 37, 17],
  775. [4, 36, 12, 4, 37, 13],
  776. # 10
  777. [2, 86, 68, 2, 87, 69],
  778. [4, 69, 43, 1, 70, 44],
  779. [6, 43, 19, 2, 44, 20],
  780. [6, 43, 15, 2, 44, 16],
  781. # 11
  782. [4, 101, 81],
  783. [1, 80, 50, 4, 81, 51],
  784. [4, 50, 22, 4, 51, 23],
  785. [3, 36, 12, 8, 37, 13],
  786. # 12
  787. [2, 116, 92, 2, 117, 93],
  788. [6, 58, 36, 2, 59, 37],
  789. [4, 46, 20, 6, 47, 21],
  790. [7, 42, 14, 4, 43, 15],
  791. # 13
  792. [4, 133, 107],
  793. [8, 59, 37, 1, 60, 38],
  794. [8, 44, 20, 4, 45, 21],
  795. [12, 33, 11, 4, 34, 12],
  796. # 14
  797. [3, 145, 115, 1, 146, 116],
  798. [4, 64, 40, 5, 65, 41],
  799. [11, 36, 16, 5, 37, 17],
  800. [11, 36, 12, 5, 37, 13],
  801. # 15
  802. [5, 109, 87, 1, 110, 88],
  803. [5, 65, 41, 5, 66, 42],
  804. [5, 54, 24, 7, 55, 25],
  805. [11, 36, 12],
  806. # 16
  807. [5, 122, 98, 1, 123, 99],
  808. [7, 73, 45, 3, 74, 46],
  809. [15, 43, 19, 2, 44, 20],
  810. [3, 45, 15, 13, 46, 16],
  811. # 17
  812. [1, 135, 107, 5, 136, 108],
  813. [10, 74, 46, 1, 75, 47],
  814. [1, 50, 22, 15, 51, 23],
  815. [2, 42, 14, 17, 43, 15],
  816. # 18
  817. [5, 150, 120, 1, 151, 121],
  818. [9, 69, 43, 4, 70, 44],
  819. [17, 50, 22, 1, 51, 23],
  820. [2, 42, 14, 19, 43, 15],
  821. # 19
  822. [3, 141, 113, 4, 142, 114],
  823. [3, 70, 44, 11, 71, 45],
  824. [17, 47, 21, 4, 48, 22],
  825. [9, 39, 13, 16, 40, 14],
  826. # 20
  827. [3, 135, 107, 5, 136, 108],
  828. [3, 67, 41, 13, 68, 42],
  829. [15, 54, 24, 5, 55, 25],
  830. [15, 43, 15, 10, 44, 16],
  831. # 21
  832. [4, 144, 116, 4, 145, 117],
  833. [17, 68, 42],
  834. [17, 50, 22, 6, 51, 23],
  835. [19, 46, 16, 6, 47, 17],
  836. # 22
  837. [2, 139, 111, 7, 140, 112],
  838. [17, 74, 46],
  839. [7, 54, 24, 16, 55, 25],
  840. [34, 37, 13],
  841. # 23
  842. [4, 151, 121, 5, 152, 122],
  843. [4, 75, 47, 14, 76, 48],
  844. [11, 54, 24, 14, 55, 25],
  845. [16, 45, 15, 14, 46, 16],
  846. # 24
  847. [6, 147, 117, 4, 148, 118],
  848. [6, 73, 45, 14, 74, 46],
  849. [11, 54, 24, 16, 55, 25],
  850. [30, 46, 16, 2, 47, 17],
  851. # 25
  852. [8, 132, 106, 4, 133, 107],
  853. [8, 75, 47, 13, 76, 48],
  854. [7, 54, 24, 22, 55, 25],
  855. [22, 45, 15, 13, 46, 16],
  856. # 26
  857. [10, 142, 114, 2, 143, 115],
  858. [19, 74, 46, 4, 75, 47],
  859. [28, 50, 22, 6, 51, 23],
  860. [33, 46, 16, 4, 47, 17],
  861. # 27
  862. [8, 152, 122, 4, 153, 123],
  863. [22, 73, 45, 3, 74, 46],
  864. [8, 53, 23, 26, 54, 24],
  865. [12, 45, 15, 28, 46, 16],
  866. # 28
  867. [3, 147, 117, 10, 148, 118],
  868. [3, 73, 45, 23, 74, 46],
  869. [4, 54, 24, 31, 55, 25],
  870. [11, 45, 15, 31, 46, 16],
  871. # 29
  872. [7, 146, 116, 7, 147, 117],
  873. [21, 73, 45, 7, 74, 46],
  874. [1, 53, 23, 37, 54, 24],
  875. [19, 45, 15, 26, 46, 16],
  876. # 30
  877. [5, 145, 115, 10, 146, 116],
  878. [19, 75, 47, 10, 76, 48],
  879. [15, 54, 24, 25, 55, 25],
  880. [23, 45, 15, 25, 46, 16],
  881. # 31
  882. [13, 145, 115, 3, 146, 116],
  883. [2, 74, 46, 29, 75, 47],
  884. [42, 54, 24, 1, 55, 25],
  885. [23, 45, 15, 28, 46, 16],
  886. # 32
  887. [17, 145, 115],
  888. [10, 74, 46, 23, 75, 47],
  889. [10, 54, 24, 35, 55, 25],
  890. [19, 45, 15, 35, 46, 16],
  891. # 33
  892. [17, 145, 115, 1, 146, 116],
  893. [14, 74, 46, 21, 75, 47],
  894. [29, 54, 24, 19, 55, 25],
  895. [11, 45, 15, 46, 46, 16],
  896. # 34
  897. [13, 145, 115, 6, 146, 116],
  898. [14, 74, 46, 23, 75, 47],
  899. [44, 54, 24, 7, 55, 25],
  900. [59, 46, 16, 1, 47, 17],
  901. # 35
  902. [12, 151, 121, 7, 152, 122],
  903. [12, 75, 47, 26, 76, 48],
  904. [39, 54, 24, 14, 55, 25],
  905. [22, 45, 15, 41, 46, 16],
  906. # 36
  907. [6, 151, 121, 14, 152, 122],
  908. [6, 75, 47, 34, 76, 48],
  909. [46, 54, 24, 10, 55, 25],
  910. [2, 45, 15, 64, 46, 16],
  911. # 37
  912. [17, 152, 122, 4, 153, 123],
  913. [29, 74, 46, 14, 75, 47],
  914. [49, 54, 24, 10, 55, 25],
  915. [24, 45, 15, 46, 46, 16],
  916. # 38
  917. [4, 152, 122, 18, 153, 123],
  918. [13, 74, 46, 32, 75, 47],
  919. [48, 54, 24, 14, 55, 25],
  920. [42, 45, 15, 32, 46, 16],
  921. # 39
  922. [20, 147, 117, 4, 148, 118],
  923. [40, 75, 47, 7, 76, 48],
  924. [43, 54, 24, 22, 55, 25],
  925. [10, 45, 15, 67, 46, 16],
  926. # 40
  927. [19, 148, 118, 6, 149, 119],
  928. [18, 75, 47, 31, 76, 48],
  929. [34, 54, 24, 34, 55, 25],
  930. [20, 45, 15, 61, 46, 16]
  931. ]
  932. def __init__(self, totalCount, dataCount):
  933. self.totalCount = totalCount
  934. self.dataCount = dataCount
  935. @staticmethod
  936. def getRSBlocks(version, errorCorrectLevel):
  937. rsBlock = QRRSBlock.getRsBlockTable(version, errorCorrectLevel);
  938. if rsBlock == None:
  939. raise Exception("bad rs block @ version:" + version +
  940. "/errorCorrectLevel:" + errorCorrectLevel)
  941. length = len(rsBlock) // 3
  942. list = []
  943. for i in range(length):
  944. count = rsBlock[i * 3 + 0]
  945. totalCount = rsBlock[i * 3 + 1]
  946. dataCount = rsBlock[i * 3 + 2]
  947. for j in range(count):
  948. list.append(QRRSBlock(totalCount, dataCount))
  949. return list;
  950. @staticmethod
  951. def getRsBlockTable(version, errorCorrectLevel):
  952. if errorCorrectLevel == QRErrorCorrectLevel.L:
  953. return QRRSBlock.RS_BLOCK_TABLE[(version - 1) * 4 + 0];
  954. elif errorCorrectLevel == QRErrorCorrectLevel.M:
  955. return QRRSBlock.RS_BLOCK_TABLE[(version - 1) * 4 + 1];
  956. elif errorCorrectLevel == QRErrorCorrectLevel.Q:
  957. return QRRSBlock.RS_BLOCK_TABLE[(version - 1) * 4 + 2];
  958. elif errorCorrectLevel == QRErrorCorrectLevel.H:
  959. return QRRSBlock.RS_BLOCK_TABLE[(version - 1) * 4 + 3];
  960. else:
  961. return None;
  962. class QRBitBuffer:
  963. def __init__(self):
  964. self.buffer = []
  965. self.length = 0
  966. def __repr__(self):
  967. return ".".join([str(n) for n in self.buffer])
  968. def get(self, index):
  969. bufIndex = index // 8
  970. return ( (self.buffer[bufIndex] >> (7 - index % 8) ) & 1) == 1
  971. def put(self, num, length):
  972. for i in range(length):
  973. self.putBit( ( (num >> (length - i - 1) ) & 1) == 1)
  974. def getLengthInBits(self):
  975. return self.length
  976. def putBit(self, bit):
  977. bufIndex = self.length // 8
  978. if len(self.buffer) <= bufIndex:
  979. self.buffer.append(0)
  980. if bit:
  981. self.buffer[bufIndex] |= (0x80 >> (self.length % 8) )
  982. self.length += 1