3 #from PIL import Image, ImageDraw
7 #Ported from the Javascript library by Sam Curren
10 #http://d-project.googlecode.com/svn/trunk/misc/qrcode/js/qrcode.js
12 #Copyright (c) 2009 Kazuhiko Arase
14 #URL: http://www.d-project.com/
16 #Licensed under the MIT license:
17 # http://www.opensource.org/licenses/mit-license.php
19 # The word "QR Code" is registered trademark of
20 # DENSO WAVE INCORPORATED
21 # http://www.denso-wave.com/qrcode/faqpatent-e.html
26 def __init__(self, data):
27 self.mode = QRMode.MODE_8BIT_BYTE
33 def write(self, buffer):
34 for i in range(len(self.data)):
36 buffer.put(ord(self.data[i]), 8)
41 def __init__(self, typeNumber, errorCorrectLevel):
42 self.typeNumber = typeNumber
43 self.errorCorrectLevel = errorCorrectLevel
48 def addData(self, data):
49 newData = QR8bitByte(data)
50 self.dataList.append(newData)
52 def isDark(self, row, col):
53 if (row < 0 or self.moduleCount <= row or col < 0 or self.moduleCount <= col):
54 raise Exception("%s,%s - %s" % (row, col, self.moduleCount))
55 return self.modules[row][col]
56 def getModuleCount(self):
57 return self.moduleCount
59 self.makeImpl(False, self.getBestMaskPattern() )
60 def makeImpl(self, test, maskPattern):
62 self.moduleCount = self.typeNumber * 4 + 17
63 self.modules = [None for x in range(self.moduleCount)]
65 for row in range(self.moduleCount):
67 self.modules[row] = [None for x in range(self.moduleCount)]
69 for col in range(self.moduleCount):
70 self.modules[row][col] = None #//(col + row) % 3;
72 self.setupPositionProbePattern(0, 0)
73 self.setupPositionProbePattern(self.moduleCount - 7, 0)
74 self.setupPositionProbePattern(0, self.moduleCount - 7)
75 self.setupPositionAdjustPattern()
76 self.setupTimingPattern()
77 self.setupTypeInfo(test, maskPattern)
79 if (self.typeNumber >= 7):
80 self.setupTypeNumber(test)
82 if (self.dataCache == None):
83 self.dataCache = QRCode.createData(self.typeNumber, self.errorCorrectLevel, self.dataList)
84 self.mapData(self.dataCache, maskPattern)
86 def setupPositionProbePattern(self, row, col):
88 for r in range(-1, 8):
90 if (row + r <= -1 or self.moduleCount <= row + r): continue
92 for c in range(-1, 8):
94 if (col + c <= -1 or self.moduleCount <= col + c): continue
96 if ( (0 <= r and r <= 6 and (c == 0 or c == 6) )
97 or (0 <= c and c <= 6 and (r == 0 or r == 6) )
98 or (2 <= r and r <= 4 and 2 <= c and c <= 4) ):
99 self.modules[row + r][col + c] = True;
101 self.modules[row + r][col + c] = False;
103 def getBestMaskPattern(self):
110 self.makeImpl(True, i);
112 lostPoint = QRUtil.getLostPoint(self);
114 if (i == 0 or minLostPoint > lostPoint):
115 minLostPoint = lostPoint
121 def setupTimingPattern(self):
123 for r in range(8, self.moduleCount - 8):
124 if (self.modules[r][6] != None):
126 self.modules[r][6] = (r % 2 == 0)
128 for c in range(8, self.moduleCount - 8):
129 if (self.modules[6][c] != None):
131 self.modules[6][c] = (c % 2 == 0)
133 def setupPositionAdjustPattern(self):
135 pos = QRUtil.getPatternPosition(self.typeNumber)
137 for i in range(len(pos)):
139 for j in range(len(pos)):
144 if (self.modules[row][col] != None):
147 for r in range(-2, 3):
149 for c in range(-2, 3):
151 if (r == -2 or r == 2 or c == -2 or c == 2 or (r == 0 and c == 0) ):
152 self.modules[row + r][col + c] = True
154 self.modules[row + r][col + c] = False
156 def setupTypeNumber(self, test):
158 bits = QRUtil.getBCHTypeNumber(self.typeNumber)
161 mod = (not test and ( (bits >> i) & 1) == 1)
162 self.modules[i // 3][i % 3 + self.moduleCount - 8 - 3] = mod;
165 mod = (not test and ( (bits >> i) & 1) == 1)
166 self.modules[i % 3 + self.moduleCount - 8 - 3][i // 3] = mod;
168 def setupTypeInfo(self, test, maskPattern):
170 data = (self.errorCorrectLevel << 3) | maskPattern
171 bits = QRUtil.getBCHTypeInfo(data)
176 mod = (not test and ( (bits >> i) & 1) == 1)
179 self.modules[i][8] = mod
181 self.modules[i + 1][8] = mod
183 self.modules[self.moduleCount - 15 + i][8] = mod
188 mod = (not test and ( (bits >> i) & 1) == 1);
191 self.modules[8][self.moduleCount - i - 1] = mod
193 self.modules[8][15 - i - 1 + 1] = mod
195 self.modules[8][15 - i - 1] = mod
198 self.modules[self.moduleCount - 8][8] = (not test)
200 def mapData(self, data, maskPattern):
203 row = self.moduleCount - 1
207 for col in range(self.moduleCount - 1, 0, -2):
209 if (col == 6): col-=1
215 if (self.modules[row][col - c] == None):
219 if (byteIndex < len(data)):
220 dark = ( ( (data[byteIndex] >> bitIndex) & 1) == 1)
222 mask = QRUtil.getMask(maskPattern, row, col - c)
227 self.modules[row][col - c] = dark
236 if (row < 0 or self.moduleCount <= row):
244 def createData(typeNumber, errorCorrectLevel, dataList):
246 rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel)
248 buffer = QRBitBuffer();
250 for i in range(len(dataList)):
252 buffer.put(data.mode, 4)
253 buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber) )
256 #// calc num max data.
258 for i in range(len(rsBlocks)):
259 totalDataCount += rsBlocks[i].dataCount
261 if (buffer.getLengthInBits() > totalDataCount * 8):
262 raise Exception("code length overflow. ("
263 + buffer.getLengthInBits()
269 if (buffer.getLengthInBits() + 4 <= totalDataCount * 8):
273 while (buffer.getLengthInBits() % 8 != 0):
279 if (buffer.getLengthInBits() >= totalDataCount * 8):
281 buffer.put(QRCode.PAD0, 8)
283 if (buffer.getLengthInBits() >= totalDataCount * 8):
285 buffer.put(QRCode.PAD1, 8)
287 return QRCode.createBytes(buffer, rsBlocks)
290 def createBytes(buffer, rsBlocks):
297 dcdata = [0 for x in range(len(rsBlocks))]
298 ecdata = [0 for x in range(len(rsBlocks))]
300 for r in range(len(rsBlocks)):
302 dcCount = rsBlocks[r].dataCount
303 ecCount = rsBlocks[r].totalCount - dcCount
305 maxDcCount = max(maxDcCount, dcCount)
306 maxEcCount = max(maxEcCount, ecCount)
308 dcdata[r] = [0 for x in range(dcCount)]
310 for i in range(len(dcdata[r])):
311 dcdata[r][i] = 0xff & buffer.buffer[i + offset]
314 rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount)
315 rawPoly = QRPolynomial(dcdata[r], rsPoly.getLength() - 1)
317 modPoly = rawPoly.mod(rsPoly)
318 ecdata[r] = [0 for x in range(rsPoly.getLength()-1)]
319 for i in range(len(ecdata[r])):
320 modIndex = i + modPoly.getLength() - len(ecdata[r])
322 ecdata[r][i] = modPoly.get(modIndex)
327 for i in range(len(rsBlocks)):
328 totalCodeCount += rsBlocks[i].totalCount
330 data = [None for x in range(totalCodeCount)]
333 for i in range(maxDcCount):
334 for r in range(len(rsBlocks)):
335 if (i < len(dcdata[r])):
336 data[index] = dcdata[r][i]
339 for i in range(maxEcCount):
340 for r in range(len(rsBlocks)):
341 if (i < len(ecdata[r])):
342 data[index] = ecdata[r][i]
350 MODE_ALPHA_NUM = 1 << 1
351 MODE_8BIT_BYTE = 1 << 2
354 class QRErrorCorrectLevel:
370 class QRUtil(object):
371 PATTERN_POSITION_TABLE = [
394 [6, 30, 54, 78, 102],
395 [6, 28, 54, 80, 106],
396 [6, 32, 58, 84, 110],
397 [6, 30, 58, 86, 114],
398 [6, 34, 62, 90, 118],
399 [6, 26, 50, 74, 98, 122],
400 [6, 30, 54, 78, 102, 126],
401 [6, 26, 52, 78, 104, 130],
402 [6, 30, 56, 82, 108, 134],
403 [6, 34, 60, 86, 112, 138],
404 [6, 30, 58, 86, 114, 142],
405 [6, 34, 62, 90, 118, 146],
406 [6, 30, 54, 78, 102, 126, 150],
407 [6, 24, 50, 76, 102, 128, 154],
408 [6, 28, 54, 80, 106, 132, 158],
409 [6, 32, 58, 84, 110, 136, 162],
410 [6, 26, 54, 82, 110, 138, 166],
411 [6, 30, 58, 86, 114, 142, 170]
414 G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0)
415 G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0)
416 G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1)
419 def getBCHTypeInfo(data):
421 while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0):
422 d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) ) )
424 return ( (data << 10) | d) ^ QRUtil.G15_MASK
426 def getBCHTypeNumber(data):
428 while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0):
429 d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) ) )
430 return (data << 12) | d
432 def getBCHDigit(data):
439 def getPatternPosition(typeNumber):
440 return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]
442 def getMask(maskPattern, i, j):
443 if maskPattern == QRMaskPattern.PATTERN000 : return (i + j) % 2 == 0
444 if maskPattern == QRMaskPattern.PATTERN001 : return i % 2 == 0
445 if maskPattern == QRMaskPattern.PATTERN010 : return j % 3 == 0
446 if maskPattern == QRMaskPattern.PATTERN011 : return (i + j) % 3 == 0
447 if maskPattern == QRMaskPattern.PATTERN100 : return (math.floor(i / 2) + math.floor(j / 3) ) % 2 == 0
448 if maskPattern == QRMaskPattern.PATTERN101 : return (i * j) % 2 + (i * j) % 3 == 0
449 if maskPattern == QRMaskPattern.PATTERN110 : return ( (i * j) % 2 + (i * j) % 3) % 2 == 0
450 if maskPattern == QRMaskPattern.PATTERN111 : return ( (i * j) % 3 + (i + j) % 2) % 2 == 0
451 raise Exception("bad maskPattern:" + maskPattern);
453 def getErrorCorrectPolynomial(errorCorrectLength):
454 a = QRPolynomial([1], 0);
455 for i in range(errorCorrectLength):
456 a = a.multiply(QRPolynomial([1, QRMath.gexp(i)], 0) )
459 def getLengthInBits(mode, type):
461 if 1 <= type and type < 10:
465 if mode == QRMode.MODE_NUMBER : return 10
466 if mode == QRMode.MODE_ALPHA_NUM : return 9
467 if mode == QRMode.MODE_8BIT_BYTE : return 8
468 if mode == QRMode.MODE_KANJI : return 8
469 raise Exception("mode:" + mode)
475 if mode == QRMode.MODE_NUMBER : return 12
476 if mode == QRMode.MODE_ALPHA_NUM : return 11
477 if mode == QRMode.MODE_8BIT_BYTE : return 16
478 if mode == QRMode.MODE_KANJI : return 10
479 raise Exception("mode:" + mode)
485 if mode == QRMode.MODE_NUMBER : return 14
486 if mode == QRMode.MODE_ALPHA_NUM : return 13
487 if mode == QRMode.MODE_8BIT_BYTE : return 16
488 if mode == QRMode.MODE_KANJI : return 12
489 raise Exception("mode:" + mode)
492 raise Exception("type:" + type)
494 def getLostPoint(qrCode):
496 moduleCount = qrCode.getModuleCount();
502 for row in range(moduleCount):
504 for col in range(moduleCount):
507 dark = qrCode.isDark(row, col);
509 for r in range(-1, 2):
511 if (row + r < 0 or moduleCount <= row + r):
514 for c in range(-1, 2):
516 if (col + c < 0 or moduleCount <= col + c):
518 if (r == 0 and c == 0):
521 if (dark == qrCode.isDark(row + r, col + c) ):
524 lostPoint += (3 + sameCount - 5)
528 for row in range(moduleCount - 1):
529 for col in range(moduleCount - 1):
531 if (qrCode.isDark(row, col ) ): count+=1
532 if (qrCode.isDark(row + 1, col ) ): count+=1
533 if (qrCode.isDark(row, col + 1) ): count+=1
534 if (qrCode.isDark(row + 1, col + 1) ): count+=1
535 if (count == 0 or count == 4):
540 for row in range(moduleCount):
541 for col in range(moduleCount - 6):
542 if (qrCode.isDark(row, col)
543 and not qrCode.isDark(row, col + 1)
544 and qrCode.isDark(row, col + 2)
545 and qrCode.isDark(row, col + 3)
546 and qrCode.isDark(row, col + 4)
547 and not qrCode.isDark(row, col + 5)
548 and qrCode.isDark(row, col + 6) ):
551 for col in range(moduleCount):
552 for row in range(moduleCount - 6):
553 if (qrCode.isDark(row, col)
554 and not qrCode.isDark(row + 1, col)
555 and qrCode.isDark(row + 2, col)
556 and qrCode.isDark(row + 3, col)
557 and qrCode.isDark(row + 4, col)
558 and not qrCode.isDark(row + 5, col)
559 and qrCode.isDark(row + 6, col) ):
566 for col in range(moduleCount):
567 for row in range(moduleCount):
568 if (qrCode.isDark(row, col) ):
571 ratio = abs(100 * darkCount / moduleCount / moduleCount - 50) / 5
572 lostPoint += ratio * 10
581 raise Exception("glog(" + n + ")")
591 EXP_TABLE = [x for x in range(256)]
593 LOG_TABLE = [x for x in range(256)]
596 EXP_TABLE[i] = 1 << i;
598 for i in range(8, 256):
599 EXP_TABLE[i] = EXP_TABLE[i - 4] ^ EXP_TABLE[i - 5] ^ EXP_TABLE[i - 6] ^ EXP_TABLE[i - 8]
602 LOG_TABLE[EXP_TABLE[i] ] = i
606 def __init__(self, num, shift):
609 raise Exception(num.length + "/" + shift)
613 while offset < len(num) and num[offset] == 0:
616 self.num = [0 for x in range(len(num)-offset+shift)]
617 for i in range(len(num) - offset):
618 self.num[i] = num[i + offset]
621 def get(self, index):
622 return self.num[index]
625 def multiply(self, e):
626 num = [0 for x in range(self.getLength() + e.getLength() - 1)];
628 for i in range(self.getLength()):
629 for j in range(e.getLength()):
630 num[i + j] ^= QRMath.gexp(QRMath.glog(self.get(i) ) + QRMath.glog(e.get(j) ) )
632 return QRPolynomial(num, 0);
635 if (self.getLength() - e.getLength() < 0):
638 ratio = QRMath.glog(self.get(0) ) - QRMath.glog(e.get(0) )
640 num = [0 for x in range(self.getLength())]
642 for i in range(self.getLength()):
643 num[i] = self.get(i);
645 for i in range(e.getLength()):
646 num[i] ^= QRMath.gexp(QRMath.glog(e.get(i) ) + ratio)
649 return QRPolynomial(num, 0).mod(e);
687 [2, 33, 15, 2, 34, 16],
688 [2, 33, 11, 2, 34, 12],
699 [2, 32, 14, 4, 33, 15],
700 [4, 39, 13, 1, 40, 14],
704 [2, 60, 38, 2, 61, 39],
705 [4, 40, 18, 2, 41, 19],
706 [4, 40, 14, 2, 41, 15],
710 [3, 58, 36, 2, 59, 37],
711 [4, 36, 16, 4, 37, 17],
712 [4, 36, 12, 4, 37, 13],
715 [2, 86, 68, 2, 87, 69],
716 [4, 69, 43, 1, 70, 44],
717 [6, 43, 19, 2, 44, 20],
718 [6, 43, 15, 2, 44, 16],
722 [1, 80, 50, 4, 81, 51],
723 [4, 50, 22, 4, 51, 23],
724 [3, 36, 12, 8, 37, 13],
727 [2, 116, 92, 2, 117, 93],
728 [6, 58, 36, 2, 59, 37],
729 [4, 46, 20, 6, 47, 21],
730 [7, 42, 14, 4, 43, 15],
734 [8, 59, 37, 1, 60, 38],
735 [8, 44, 20, 4, 45, 21],
736 [12, 33, 11, 4, 34, 12],
739 [3, 145, 115, 1, 146, 116],
740 [4, 64, 40, 5, 65, 41],
741 [11, 36, 16, 5, 37, 17],
742 [11, 36, 12, 5, 37, 13],
745 [5, 109, 87, 1, 110, 88],
746 [5, 65, 41, 5, 66, 42],
747 [5, 54, 24, 7, 55, 25],
751 [5, 122, 98, 1, 123, 99],
752 [7, 73, 45, 3, 74, 46],
753 [15, 43, 19, 2, 44, 20],
754 [3, 45, 15, 13, 46, 16],
757 [1, 135, 107, 5, 136, 108],
758 [10, 74, 46, 1, 75, 47],
759 [1, 50, 22, 15, 51, 23],
760 [2, 42, 14, 17, 43, 15],
763 [5, 150, 120, 1, 151, 121],
764 [9, 69, 43, 4, 70, 44],
765 [17, 50, 22, 1, 51, 23],
766 [2, 42, 14, 19, 43, 15],
769 [3, 141, 113, 4, 142, 114],
770 [3, 70, 44, 11, 71, 45],
771 [17, 47, 21, 4, 48, 22],
772 [9, 39, 13, 16, 40, 14],
775 [3, 135, 107, 5, 136, 108],
776 [3, 67, 41, 13, 68, 42],
777 [15, 54, 24, 5, 55, 25],
778 [15, 43, 15, 10, 44, 16],
781 [4, 144, 116, 4, 145, 117],
783 [17, 50, 22, 6, 51, 23],
784 [19, 46, 16, 6, 47, 17],
787 [2, 139, 111, 7, 140, 112],
789 [7, 54, 24, 16, 55, 25],
793 [4, 151, 121, 5, 152, 122],
794 [4, 75, 47, 14, 76, 48],
795 [11, 54, 24, 14, 55, 25],
796 [16, 45, 15, 14, 46, 16],
799 [6, 147, 117, 4, 148, 118],
800 [6, 73, 45, 14, 74, 46],
801 [11, 54, 24, 16, 55, 25],
802 [30, 46, 16, 2, 47, 17],
805 [8, 132, 106, 4, 133, 107],
806 [8, 75, 47, 13, 76, 48],
807 [7, 54, 24, 22, 55, 25],
808 [22, 45, 15, 13, 46, 16],
811 [10, 142, 114, 2, 143, 115],
812 [19, 74, 46, 4, 75, 47],
813 [28, 50, 22, 6, 51, 23],
814 [33, 46, 16, 4, 47, 17],
817 [8, 152, 122, 4, 153, 123],
818 [22, 73, 45, 3, 74, 46],
819 [8, 53, 23, 26, 54, 24],
820 [12, 45, 15, 28, 46, 16],
823 [3, 147, 117, 10, 148, 118],
824 [3, 73, 45, 23, 74, 46],
825 [4, 54, 24, 31, 55, 25],
826 [11, 45, 15, 31, 46, 16],
829 [7, 146, 116, 7, 147, 117],
830 [21, 73, 45, 7, 74, 46],
831 [1, 53, 23, 37, 54, 24],
832 [19, 45, 15, 26, 46, 16],
835 [5, 145, 115, 10, 146, 116],
836 [19, 75, 47, 10, 76, 48],
837 [15, 54, 24, 25, 55, 25],
838 [23, 45, 15, 25, 46, 16],
841 [13, 145, 115, 3, 146, 116],
842 [2, 74, 46, 29, 75, 47],
843 [42, 54, 24, 1, 55, 25],
844 [23, 45, 15, 28, 46, 16],
848 [10, 74, 46, 23, 75, 47],
849 [10, 54, 24, 35, 55, 25],
850 [19, 45, 15, 35, 46, 16],
853 [17, 145, 115, 1, 146, 116],
854 [14, 74, 46, 21, 75, 47],
855 [29, 54, 24, 19, 55, 25],
856 [11, 45, 15, 46, 46, 16],
859 [13, 145, 115, 6, 146, 116],
860 [14, 74, 46, 23, 75, 47],
861 [44, 54, 24, 7, 55, 25],
862 [59, 46, 16, 1, 47, 17],
865 [12, 151, 121, 7, 152, 122],
866 [12, 75, 47, 26, 76, 48],
867 [39, 54, 24, 14, 55, 25],
868 [22, 45, 15, 41, 46, 16],
871 [6, 151, 121, 14, 152, 122],
872 [6, 75, 47, 34, 76, 48],
873 [46, 54, 24, 10, 55, 25],
874 [2, 45, 15, 64, 46, 16],
877 [17, 152, 122, 4, 153, 123],
878 [29, 74, 46, 14, 75, 47],
879 [49, 54, 24, 10, 55, 25],
880 [24, 45, 15, 46, 46, 16],
883 [4, 152, 122, 18, 153, 123],
884 [13, 74, 46, 32, 75, 47],
885 [48, 54, 24, 14, 55, 25],
886 [42, 45, 15, 32, 46, 16],
889 [20, 147, 117, 4, 148, 118],
890 [40, 75, 47, 7, 76, 48],
891 [43, 54, 24, 22, 55, 25],
892 [10, 45, 15, 67, 46, 16],
895 [19, 148, 118, 6, 149, 119],
896 [18, 75, 47, 31, 76, 48],
897 [34, 54, 24, 34, 55, 25],
898 [20, 45, 15, 61, 46, 16]
902 def __init__(self, totalCount, dataCount):
903 self.totalCount = totalCount
904 self.dataCount = dataCount
907 def getRSBlocks(typeNumber, errorCorrectLevel):
908 rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);
910 raise Exception("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel)
912 length = len(rsBlock) / 3
916 for i in range(length):
918 count = rsBlock[i * 3 + 0]
919 totalCount = rsBlock[i * 3 + 1]
920 dataCount = rsBlock[i * 3 + 2]
922 for j in range(count):
923 list.append(QRRSBlock(totalCount, dataCount))
928 def getRsBlockTable(typeNumber, errorCorrectLevel):
929 if errorCorrectLevel == QRErrorCorrectLevel.L:
930 return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
931 elif errorCorrectLevel == QRErrorCorrectLevel.M:
932 return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
933 elif errorCorrectLevel == QRErrorCorrectLevel.Q:
934 return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
935 elif errorCorrectLevel == QRErrorCorrectLevel.H:
936 return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
945 return ".".join([str(n) for n in self.buffer])
946 def get(self, index):
947 bufIndex = math.floor(index / 8)
948 val = ( (self.buffer[bufIndex] >> (7 - index % 8) ) & 1) == 1
950 return ( (self.buffer[bufIndex] >> (7 - index % 8) ) & 1) == 1
951 def put(self, num, length):
952 for i in range(length):
953 self.putBit( ( (num >> (length - i - 1) ) & 1) == 1)
954 def getLengthInBits(self):
956 def putBit(self, bit):
957 bufIndex = self.length // 8
958 if len(self.buffer) <= bufIndex:
959 self.buffer.append(0)
961 self.buffer[bufIndex] |= (0x80 >> (self.length % 8) )