You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

827 lines
25 KiB

  1. #
  2. # QR Code Generator for Python
  3. #
  4. # Copyright (c) 2012 Kazuhiko Arase
  5. #
  6. # URL: http://www.d-project.com/
  7. #
  8. # Licensed under the MIT license:
  9. # http://www.opensource.org/licenses/mit-license.php
  10. #
  11. # The word 'QR Code' is registered trademark of
  12. # DENSO WAVE INCORPORATED
  13. # http://www.denso-wave.com/qrcode/faqpatent-e.html
  14. #
  15. """QR Code Generator for Python
  16. from qrcode import QRCode, ErrorCorrectLevel
  17. # generate with explicit type number
  18. qr = QRCode()
  19. qr.setTypeNumber(4)
  20. qr.setErrorCorrectLevel(ErrorCorrectLevel.M)
  21. qr.addData('here comes qr!')
  22. qr.make()
  23. # generate with auto type number
  24. # qr = QRCode.getMinimumQRCode('here comes qr!', ErrorCorrectLevel.M)
  25. # create an image
  26. for r in range(qr.getModuleCount() ):
  27. for c in range(qr.getModuleCount() ):
  28. color = black if qr.isDark(r, c) else white
  29. # set pixel ...
  30. """
  31. class QRCode:
  32. PAD0 = 0xEC
  33. PAD1 = 0x11
  34. def __init__(self):
  35. self.typeNumber = 1
  36. self.errorCorrectLevel = ErrorCorrectLevel.H
  37. self.qrDataList = []
  38. self.modules = []
  39. self.moduleCount = 0
  40. def getTypeNumber(self):
  41. return self.typeNumber
  42. def setTypeNumber(self, typeNumber):
  43. self.typeNumber = typeNumber
  44. def getErrorCorrectLevel(self):
  45. return self.errorCorrectLevel
  46. def setErrorCorrectLevel(self, errorCorrectLevel):
  47. self.errorCorrectLevel = errorCorrectLevel
  48. def clearData(self):
  49. self.qrDataList = []
  50. def addData(self, data):
  51. self.qrDataList.append(QR8BitByte(data) )
  52. def getDataCount(self):
  53. return len(self.qrDataList)
  54. def getData(self, index):
  55. return self.qrDataList[index]
  56. def isDark(self, row, col):
  57. return (self.modules[row][col] if self.modules[row][col] != None
  58. else False)
  59. def getModuleCount(self):
  60. return self.moduleCount
  61. def make(self):
  62. self._make(False, self._getBestMaskPattern() )
  63. def _getBestMaskPattern(self):
  64. minLostPoint = 0
  65. pattern = 0
  66. for i in range(8):
  67. self._make(True, i)
  68. lostPoint = QRUtil.getLostPoint(self)
  69. if i == 0 or minLostPoint > lostPoint:
  70. minLostPoint = lostPoint
  71. pattern = i
  72. return pattern
  73. def _make(self, test, maskPattern):
  74. self.moduleCount = self.typeNumber * 4 + 17
  75. self.modules = [[None] * self.moduleCount
  76. for i in range(self.moduleCount)]
  77. self._setupPositionProbePattern(0, 0)
  78. self._setupPositionProbePattern(self.moduleCount - 7, 0)
  79. self._setupPositionProbePattern(0, self.moduleCount - 7)
  80. self._setupPositionAdjustPattern()
  81. self._setupTimingPattern()
  82. self._setupTypeInfo(test, maskPattern)
  83. if self.typeNumber >= 7:
  84. self._setupTypeNumber(test)
  85. data = QRCode._createData(
  86. self.typeNumber,
  87. self.errorCorrectLevel,
  88. self.qrDataList)
  89. self._mapData(data, maskPattern)
  90. def _mapData(self, data, maskPattern):
  91. rows = list(range(self.moduleCount) )
  92. cols = [col - 1 if col <= 6 else col
  93. for col in range(self.moduleCount - 1, 0, -2)]
  94. maskFunc = QRUtil.getMaskFunction(maskPattern)
  95. byteIndex = 0
  96. bitIndex = 7
  97. for col in cols:
  98. rows.reverse()
  99. for row in rows:
  100. for c in range(2):
  101. if self.modules[row][col - c] == None:
  102. dark = False
  103. if byteIndex < len(data):
  104. dark = ( (data[byteIndex] >> bitIndex) & 1) == 1
  105. if maskFunc(row, col - c):
  106. dark = not dark
  107. self.modules[row][col - c] = dark
  108. bitIndex -= 1
  109. if bitIndex == -1:
  110. byteIndex += 1
  111. bitIndex = 7
  112. def _setupPositionAdjustPattern(self):
  113. pos = QRUtil.getPatternPosition(self.typeNumber)
  114. for row in pos:
  115. for col in pos:
  116. if self.modules[row][col] != None:
  117. continue
  118. for r in range(-2, 3):
  119. for c in range(-2, 3):
  120. self.modules[row + r][col + c] = (
  121. r == -2 or r == 2 or c == -2 or c == 2
  122. or (r == 0 and c == 0) )
  123. def _setupPositionProbePattern(self, row, col):
  124. for r in range(-1, 8):
  125. for c in range(-1, 8):
  126. if (row + r <= -1 or self.moduleCount <= row + r
  127. or col + c <= -1 or self.moduleCount <= col + c):
  128. continue
  129. self.modules[row + r][col + c] = (
  130. (0 <= r and r <= 6 and (c == 0 or c == 6) )
  131. or (0 <= c and c <= 6 and (r == 0 or r == 6) )
  132. or (2 <= r and r <= 4 and 2 <= c and c <= 4) )
  133. def _setupTimingPattern(self):
  134. for r in range(8, self.moduleCount - 8):
  135. if self.modules[r][6] != None:
  136. continue
  137. self.modules[r][6] = r % 2 == 0
  138. for c in range(8, self.moduleCount - 8):
  139. if self.modules[6][c] != None:
  140. continue
  141. self.modules[6][c] = c % 2 == 0
  142. def _setupTypeNumber(self, test):
  143. bits = QRUtil.getBCHTypeNumber(self.typeNumber)
  144. for i in range(18):
  145. self.modules[i // 3][i % 3 + self.moduleCount - 8 - 3] = (
  146. not test and ( (bits >> i) & 1) == 1)
  147. for i in range(18):
  148. self.modules[i % 3 + self.moduleCount - 8 - 3][i // 3] = (
  149. not test and ( (bits >> i) & 1) == 1)
  150. def _setupTypeInfo(self, test, maskPattern):
  151. data = (self.errorCorrectLevel << 3) | maskPattern
  152. bits = QRUtil.getBCHTypeInfo(data)
  153. # vertical
  154. for i in range(15):
  155. mod = not test and ( (bits >> i) & 1) == 1
  156. if i < 6:
  157. self.modules[i][8] = mod
  158. elif i < 8:
  159. self.modules[i + 1][8] = mod
  160. else:
  161. self.modules[self.moduleCount - 15 + i][8] = mod
  162. # horizontal
  163. for i in range(15):
  164. mod = not test and ( (bits >> i) & 1) == 1
  165. if i < 8:
  166. self.modules[8][self.moduleCount - i - 1] = mod
  167. elif i < 9:
  168. self.modules[8][15 - i - 1 + 1] = mod
  169. else:
  170. self.modules[8][15 - i - 1] = mod
  171. # fixed
  172. self.modules[self.moduleCount - 8][8] = not test
  173. @staticmethod
  174. def _createData(typeNumber, errorCorrectLevel, dataArray):
  175. rsBlocks = RSBlock.getRSBlocks(typeNumber, errorCorrectLevel)
  176. buffer = BitBuffer()
  177. for data in dataArray:
  178. buffer.put(data.getMode(), 4)
  179. buffer.put(data.getLength(), data.getLengthInBits(typeNumber) )
  180. data.write(buffer)
  181. totalDataCount = sum(rsBlock.getDataCount()
  182. for rsBlock in rsBlocks)
  183. if buffer.getLengthInBits() > totalDataCount * 8:
  184. raise Exception('code length overflow. (%s > %s)' %
  185. (buffer.getLengthInBits(), totalDataCount * 8) )
  186. # end code
  187. if buffer.getLengthInBits() + 4 <= totalDataCount * 8:
  188. buffer.put(0, 4)
  189. # padding
  190. while buffer.getLengthInBits() % 8 != 0:
  191. buffer.put(False)
  192. # padding
  193. while True:
  194. if buffer.getLengthInBits() >= totalDataCount * 8:
  195. break
  196. buffer.put(QRCode.PAD0, 8)
  197. if buffer.getLengthInBits() >= totalDataCount * 8:
  198. break
  199. buffer.put(QRCode.PAD1, 8)
  200. return QRCode._createBytes(buffer, rsBlocks)
  201. @staticmethod
  202. def _createBytes(buffer, rsBlocks):
  203. offset = 0
  204. maxDcCount = 0
  205. maxEcCount = 0
  206. dcdata = [None] * len(rsBlocks)
  207. ecdata = [None] * len(rsBlocks)
  208. for r in range(len(rsBlocks) ):
  209. dcCount = rsBlocks[r].getDataCount()
  210. ecCount = rsBlocks[r].getTotalCount() - dcCount
  211. maxDcCount = max(maxDcCount, dcCount)
  212. maxEcCount = max(maxEcCount, ecCount)
  213. dcdata[r] = [0] * dcCount
  214. for i in range(len(dcdata[r] ) ):
  215. dcdata[r][i] = 0xff & buffer.getBuffer()[i + offset]
  216. offset += dcCount
  217. rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount)
  218. rawPoly = Polynomial(dcdata[r], rsPoly.getLength() - 1)
  219. modPoly = rawPoly.mod(rsPoly)
  220. ecdata[r] = [0] * (rsPoly.getLength() - 1)
  221. for i in range(len(ecdata[r]) ):
  222. modIndex = i + modPoly.getLength() - len(ecdata[r])
  223. ecdata[r][i] = modPoly.get(modIndex) if modIndex >= 0 else 0
  224. totalCodeCount = sum(rsBlock.getTotalCount()
  225. for rsBlock in rsBlocks)
  226. data = [0] * totalCodeCount
  227. index = 0
  228. for i in range(maxDcCount):
  229. for r in range(len(rsBlocks) ):
  230. if i < len(dcdata[r] ):
  231. data[index] = dcdata[r][i]
  232. index += 1
  233. for i in range(maxEcCount):
  234. for r in range(len(rsBlocks) ):
  235. if i < len(ecdata[r] ):
  236. data[index] = ecdata[r][i]
  237. index += 1
  238. return data
  239. @staticmethod
  240. def getMinimumQRCode(data, errorCorrectLevel):
  241. mode = Mode.MODE_8BIT_BYTE # fixed to 8bit byte
  242. qr = QRCode()
  243. qr.setErrorCorrectLevel(errorCorrectLevel)
  244. qr.addData(data)
  245. length = qr.getData(0).getLength()
  246. for typeNumber in range(1, 11):
  247. if length <= QRUtil.getMaxLength(
  248. typeNumber, mode, errorCorrectLevel):
  249. qr.setTypeNumber(typeNumber)
  250. break
  251. qr.make()
  252. return qr
  253. class Mode:
  254. MODE_NUMBER = 1 << 0
  255. MODE_ALPHA_NUM = 1 << 1
  256. MODE_8BIT_BYTE = 1 << 2
  257. MODE_KANJI = 1 << 3
  258. class ErrorCorrectLevel:
  259. L = 1 # 7%
  260. M = 0 # 15%
  261. Q = 3 # 25%
  262. H = 2 # 30%
  263. class MaskPattern:
  264. PATTERN000 = 0
  265. PATTERN001 = 1
  266. PATTERN010 = 2
  267. PATTERN011 = 3
  268. PATTERN100 = 4
  269. PATTERN101 = 5
  270. PATTERN110 = 6
  271. PATTERN111 = 7
  272. class QRUtil:
  273. @staticmethod
  274. def getPatternPosition(typeNumber):
  275. return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]
  276. PATTERN_POSITION_TABLE = [
  277. [],
  278. [6, 18],
  279. [6, 22],
  280. [6, 26],
  281. [6, 30],
  282. [6, 34],
  283. [6, 22, 38],
  284. [6, 24, 42],
  285. [6, 26, 46],
  286. [6, 28, 50],
  287. [6, 30, 54],
  288. [6, 32, 58],
  289. [6, 34, 62],
  290. [6, 26, 46, 66],
  291. [6, 26, 48, 70],
  292. [6, 26, 50, 74],
  293. [6, 30, 54, 78],
  294. [6, 30, 56, 82],
  295. [6, 30, 58, 86],
  296. [6, 34, 62, 90],
  297. [6, 28, 50, 72, 94],
  298. [6, 26, 50, 74, 98],
  299. [6, 30, 54, 78, 102],
  300. [6, 28, 54, 80, 106],
  301. [6, 32, 58, 84, 110],
  302. [6, 30, 58, 86, 114],
  303. [6, 34, 62, 90, 118],
  304. [6, 26, 50, 74, 98, 122],
  305. [6, 30, 54, 78, 102, 126],
  306. [6, 26, 52, 78, 104, 130],
  307. [6, 30, 56, 82, 108, 134],
  308. [6, 34, 60, 86, 112, 138],
  309. [6, 30, 58, 86, 114, 142],
  310. [6, 34, 62, 90, 118, 146],
  311. [6, 30, 54, 78, 102, 126, 150],
  312. [6, 24, 50, 76, 102, 128, 154],
  313. [6, 28, 54, 80, 106, 132, 158],
  314. [6, 32, 58, 84, 110, 136, 162],
  315. [6, 26, 54, 82, 110, 138, 166],
  316. [6, 30, 58, 86, 114, 142, 170]
  317. ]
  318. MAX_LENGTH = [
  319. [ [41, 25, 17, 10], [34, 20, 14, 8], [27, 16, 11, 7], [17, 10, 7, 4] ],
  320. [ [77, 47, 32, 20], [63, 38, 26, 16], [48, 29, 20, 12], [34, 20, 14, 8] ],
  321. [ [127, 77, 53, 32], [101, 61, 42, 26], [77, 47, 32, 20], [58, 35, 24, 15] ],
  322. [ [187, 114, 78, 48], [149, 90, 62, 38], [111, 67, 46, 28], [82, 50, 34, 21] ],
  323. [ [255, 154, 106, 65], [202, 122, 84, 52], [144, 87, 60, 37], [106, 64, 44, 27] ],
  324. [ [322, 195, 134, 82], [255, 154, 106, 65], [178, 108, 74, 45], [139, 84, 58, 36] ],
  325. [ [370, 224, 154, 95], [293, 178, 122, 75], [207, 125, 86, 53], [154, 93, 64, 39] ],
  326. [ [461, 279, 192, 118], [365, 221, 152, 93], [259, 157, 108, 66], [202, 122, 84, 52] ],
  327. [ [552, 335, 230, 141], [432, 262, 180, 111], [312, 189, 130, 80], [235, 143, 98, 60] ],
  328. [ [652, 395, 271, 167], [513, 311, 213, 131], [364, 221, 151, 93], [288, 174, 119, 74] ]
  329. ]
  330. @staticmethod
  331. def getMaxLength(typeNumber, mode, errorCorrectLevel):
  332. t = typeNumber - 1
  333. e = {
  334. ErrorCorrectLevel.L: 0,
  335. ErrorCorrectLevel.M: 1,
  336. ErrorCorrectLevel.Q: 2,
  337. ErrorCorrectLevel.H: 3
  338. }[errorCorrectLevel]
  339. m = {
  340. Mode.MODE_NUMBER: 0,
  341. Mode.MODE_ALPHA_NUM: 1,
  342. Mode.MODE_8BIT_BYTE: 2,
  343. Mode.MODE_KANJI: 3
  344. }[mode]
  345. return QRUtil.MAX_LENGTH[t][e][m]
  346. @staticmethod
  347. def getErrorCorrectPolynomial(errorCorrectLength):
  348. a = Polynomial([1])
  349. for i in range(errorCorrectLength):
  350. a = a.multiply(Polynomial([1, QRMath.gexp(i)]) )
  351. return a
  352. @staticmethod
  353. def getMaskFunction(maskPattern):
  354. return {
  355. MaskPattern.PATTERN000:
  356. lambda i, j: (i + j) % 2 == 0,
  357. MaskPattern.PATTERN001:
  358. lambda i, j: i % 2 == 0,
  359. MaskPattern.PATTERN010:
  360. lambda i, j: j % 3 == 0,
  361. MaskPattern.PATTERN011:
  362. lambda i, j: (i + j) % 3 == 0,
  363. MaskPattern.PATTERN100:
  364. lambda i, j: (i // 2 + j // 3) % 2 == 0,
  365. MaskPattern.PATTERN101:
  366. lambda i, j: (i * j) % 2 + (i * j) % 3 == 0,
  367. MaskPattern.PATTERN110:
  368. lambda i, j: ( (i * j) % 2 + (i * j) % 3) % 2 == 0,
  369. MaskPattern.PATTERN111:
  370. lambda i, j: ( (i * j) % 3 + (i + j) % 2) % 2 == 0
  371. }[maskPattern]
  372. @staticmethod
  373. def getLostPoint(qrcode):
  374. moduleCount = qrcode.getModuleCount()
  375. lostPoint = 0
  376. # LEVEL1
  377. for row in range(moduleCount):
  378. for col in range(moduleCount):
  379. sameCount = 0
  380. dark = qrcode.isDark(row, col)
  381. for r in range(-1, 2):
  382. if row + r < 0 or moduleCount <= row + r:
  383. continue
  384. for c in range(-1, 2):
  385. if col + c < 0 or moduleCount <= col + c:
  386. continue
  387. if r == 0 and c == 0:
  388. continue
  389. if dark == qrcode.isDark(row + r, col + c):
  390. sameCount += 1
  391. if sameCount > 5:
  392. lostPoint += (3 + sameCount - 5)
  393. # LEVEL2
  394. for row in range(moduleCount - 1):
  395. for col in range(moduleCount - 1):
  396. count = 0
  397. if qrcode.isDark(row, col):
  398. count += 1
  399. if qrcode.isDark(row + 1, col):
  400. count += 1
  401. if qrcode.isDark(row, col + 1):
  402. count += 1
  403. if qrcode.isDark(row + 1, col + 1):
  404. count += 1
  405. if count == 0 or count == 4:
  406. lostPoint += 3
  407. # LEVEL3
  408. for row in range(moduleCount):
  409. for col in range(moduleCount - 6):
  410. if (qrcode.isDark(row, col)
  411. and not qrcode.isDark(row, col + 1)
  412. and qrcode.isDark(row, col + 2)
  413. and qrcode.isDark(row, col + 3)
  414. and qrcode.isDark(row, col + 4)
  415. and not qrcode.isDark(row, col + 5)
  416. and qrcode.isDark(row, col + 6) ):
  417. lostPoint += 40
  418. for col in range(moduleCount):
  419. for row in range(moduleCount - 6):
  420. if (qrcode.isDark(row, col)
  421. and not qrcode.isDark(row + 1, col)
  422. and qrcode.isDark(row + 2, col)
  423. and qrcode.isDark(row + 3, col)
  424. and qrcode.isDark(row + 4, col)
  425. and not qrcode.isDark(row + 5, col)
  426. and qrcode.isDark(row + 6, col) ):
  427. lostPoint += 40
  428. # LEVEL4
  429. darkCount = 0
  430. for col in range(moduleCount):
  431. for row in range(moduleCount):
  432. if qrcode.isDark(row, col):
  433. darkCount += 1
  434. ratio = abs(100 * darkCount // moduleCount // moduleCount - 50) // 5
  435. lostPoint += ratio * 10
  436. return lostPoint
  437. G15 = ( (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) |
  438. (1 << 2) | (1 << 1) | (1 << 0) )
  439. G18 = ( (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) |
  440. (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0) )
  441. G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1)
  442. @staticmethod
  443. def getBCHTypeInfo(data):
  444. d = data << 10
  445. while QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0:
  446. d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) -
  447. QRUtil.getBCHDigit(QRUtil.G15) ) )
  448. return ( (data << 10) | d) ^ QRUtil.G15_MASK
  449. @staticmethod
  450. def getBCHTypeNumber(data):
  451. d = data << 12
  452. while QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0:
  453. d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) -
  454. QRUtil.getBCHDigit(QRUtil.G18) ) )
  455. return (data << 12) | d
  456. @staticmethod
  457. def getBCHDigit(data):
  458. digit = 0
  459. while data != 0:
  460. digit += 1
  461. data >>= 1
  462. return digit
  463. @staticmethod
  464. def stringToBytes(s):
  465. return [ord(c) & 0xff for c in s]
  466. class QR8BitByte:
  467. def __init__(self, data):
  468. self.mode = Mode.MODE_8BIT_BYTE
  469. self.data = data
  470. def getMode(self):
  471. return self.mode
  472. def getData(self):
  473. return self.data
  474. '''
  475. def write(self, buffer): raise Exception('not implemented.')
  476. def getLength(self): raise Exception('not implemented.')
  477. '''
  478. def write(self, buffer):
  479. data = QRUtil.stringToBytes(self.getData() )
  480. for d in data:
  481. buffer.put(d, 8)
  482. def getLength(self):
  483. return len(QRUtil.stringToBytes(self.getData() ) )
  484. def getLengthInBits(self, type):
  485. if 1 <= type and type < 10: # 1 - 9
  486. return {
  487. Mode.MODE_NUMBER: 10,
  488. Mode.MODE_ALPHA_NUM: 9,
  489. Mode.MODE_8BIT_BYTE: 8,
  490. Mode.MODE_KANJI: 8
  491. }[self.mode]
  492. elif type < 27: # 10 - 26
  493. return {
  494. Mode.MODE_NUMBER: 12,
  495. Mode.MODE_ALPHA_NUM: 11,
  496. Mode.MODE_8BIT_BYTE: 16,
  497. Mode.MODE_KANJI: 10
  498. }[self.mode]
  499. elif type < 41: # 27 - 40
  500. return {
  501. Mode.MODE_NUMBER: 14,
  502. Mode.MODE_ALPHA_NUM: 13,
  503. Mode.MODE_8BIT_BYTE: 16,
  504. Mode.MODE_KANJI: 12
  505. }[self.mode]
  506. else:
  507. raise Exception('type:%s' % type)
  508. class QRMath:
  509. EXP_TABLE = None
  510. LOG_TABLE = None
  511. @staticmethod
  512. def _init():
  513. QRMath.EXP_TABLE = [0] * 256
  514. for i in range(256):
  515. QRMath.EXP_TABLE[i] = (1 << i if i < 8 else
  516. QRMath.EXP_TABLE[i - 4] ^ QRMath.EXP_TABLE[i - 5] ^
  517. QRMath.EXP_TABLE[i - 6] ^ QRMath.EXP_TABLE[i - 8])
  518. QRMath.LOG_TABLE = [0] * 256
  519. for i in range(255):
  520. QRMath.LOG_TABLE[QRMath.EXP_TABLE[i] ] = i
  521. @staticmethod
  522. def glog(n):
  523. if n < 1:
  524. raise Exception('log(%s)' % n)
  525. return QRMath.LOG_TABLE[n]
  526. @staticmethod
  527. def gexp(n):
  528. while n < 0:
  529. n += 255
  530. while n >= 256:
  531. n -= 255
  532. return QRMath.EXP_TABLE[n]
  533. # initialize statics
  534. QRMath._init()
  535. class Polynomial:
  536. def __init__(self, num, shift=0):
  537. offset = 0
  538. length = len(num)
  539. while offset < length and num[offset] == 0:
  540. offset += 1
  541. self.num = num[offset:] + [0] * shift
  542. def get(self, index):
  543. return self.num[index]
  544. def getLength(self):
  545. return len(self.num)
  546. def __repr__(self):
  547. return ','.join( [str(self.get(i) )
  548. for i in range(self.getLength() ) ] )
  549. def toLogString(self):
  550. return ','.join( [str(QRMath.glog(self.get(i) ) )
  551. for i in range(self.getLength() ) ] )
  552. def multiply(self, e):
  553. num = [0] * (self.getLength() + e.getLength() - 1)
  554. for i in range(self.getLength() ):
  555. for j in range(e.getLength() ):
  556. num[i + j] ^= QRMath.gexp(QRMath.glog(self.get(i) ) +
  557. QRMath.glog(e.get(j) ) )
  558. return Polynomial(num)
  559. def mod(self, e):
  560. if self.getLength() - e.getLength() < 0:
  561. return self
  562. ratio = QRMath.glog(self.get(0) ) - QRMath.glog(e.get(0) )
  563. num = self.num[:]
  564. for i in range(e.getLength() ):
  565. num[i] ^= QRMath.gexp(QRMath.glog(e.get(i) ) + ratio)
  566. return Polynomial(num).mod(e)
  567. class RSBlock:
  568. RS_BLOCK_TABLE = [
  569. # L
  570. # M
  571. # Q
  572. # H
  573. # 1
  574. [1, 26, 19],
  575. [1, 26, 16],
  576. [1, 26, 13],
  577. [1, 26, 9],
  578. # 2
  579. [1, 44, 34],
  580. [1, 44, 28],
  581. [1, 44, 22],
  582. [1, 44, 16],
  583. # 3
  584. [1, 70, 55],
  585. [1, 70, 44],
  586. [2, 35, 17],
  587. [2, 35, 13],
  588. # 4
  589. [1, 100, 80],
  590. [2, 50, 32],
  591. [2, 50, 24],
  592. [4, 25, 9],
  593. # 5
  594. [1, 134, 108],
  595. [2, 67, 43],
  596. [2, 33, 15, 2, 34, 16],
  597. [2, 33, 11, 2, 34, 12],
  598. # 6
  599. [2, 86, 68],
  600. [4, 43, 27],
  601. [4, 43, 19],
  602. [4, 43, 15],
  603. # 7
  604. [2, 98, 78],
  605. [4, 49, 31],
  606. [2, 32, 14, 4, 33, 15],
  607. [4, 39, 13, 1, 40, 14],
  608. # 8
  609. [2, 121, 97],
  610. [2, 60, 38, 2, 61, 39],
  611. [4, 40, 18, 2, 41, 19],
  612. [4, 40, 14, 2, 41, 15],
  613. # 9
  614. [2, 146, 116],
  615. [3, 58, 36, 2, 59, 37],
  616. [4, 36, 16, 4, 37, 17],
  617. [4, 36, 12, 4, 37, 13],
  618. # 10
  619. [2, 86, 68, 2, 87, 69],
  620. [4, 69, 43, 1, 70, 44],
  621. [6, 43, 19, 2, 44, 20],
  622. [6, 43, 15, 2, 44, 16]
  623. ]
  624. def __init__(self, totalCount, dataCount):
  625. self.totalCount = totalCount
  626. self.dataCount = dataCount
  627. def getDataCount(self):
  628. return self.dataCount
  629. def getTotalCount(self):
  630. return self.totalCount
  631. def __repr__(self):
  632. return ('(total=%s,data=%s)' % (self.totalCount, self.dataCount) )
  633. @staticmethod
  634. def getRSBlocks(typeNumber, errorCorrectLevel):
  635. rsBlock = RSBlock.getRsBlockTable(typeNumber, errorCorrectLevel)
  636. length = len(rsBlock) // 3
  637. list = []
  638. for i in range(length):
  639. count = rsBlock[i * 3 + 0]
  640. totalCount = rsBlock[i * 3 + 1]
  641. dataCount = rsBlock[i * 3 + 2]
  642. list += [RSBlock(totalCount, dataCount)] * count
  643. return list
  644. @staticmethod
  645. def getRsBlockTable(typeNumber, errorCorrectLevel):
  646. return {
  647. ErrorCorrectLevel.L:
  648. RSBlock.RS_BLOCK_TABLE[ (typeNumber - 1) * 4 + 0],
  649. ErrorCorrectLevel.M:
  650. RSBlock.RS_BLOCK_TABLE[ (typeNumber - 1) * 4 + 1],
  651. ErrorCorrectLevel.Q:
  652. RSBlock.RS_BLOCK_TABLE[ (typeNumber - 1) * 4 + 2],
  653. ErrorCorrectLevel.H:
  654. RSBlock.RS_BLOCK_TABLE[ (typeNumber - 1) * 4 + 3]
  655. }[errorCorrectLevel]
  656. class BitBuffer:
  657. def __init__(self, inclements=32):
  658. self.inclements = inclements
  659. self.buffer = [0] * self.inclements
  660. self.length = 0
  661. def getBuffer(self):
  662. return self.buffer
  663. def getLengthInBits(self):
  664. return self.length
  665. def get(self, index):
  666. return ( (self.buffer[index // 8] >> (7 - index % 8) ) & 1) == 1
  667. def putBit(self, bit):
  668. if self.length == len(self.buffer) * 8:
  669. self.buffer += [0] * self.inclements
  670. if bit:
  671. self.buffer[self.length // 8] |= (0x80 >> (self.length % 8) )
  672. self.length += 1
  673. def put(self, num, length):
  674. for i in range(length):
  675. self.putBit( ( (num >> (length - i - 1) ) & 1) == 1)
  676. def __repr__(self):
  677. return ''.join('1' if self.get(i) else '0'
  678. for i in range(self.getLengthInBits() ) )