1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 """
34 This module can model common CRC algorithms given the set of defining
35 parameters. This is intended to be easy to use for experimentation
36 rather than optimized for speed. It is slow even for a native Python
37 CRC implementation.
38
39 Several common CRC algorithms are predefined in this module.
40
41 :authors: Ray Burr
42 :license: MIT License
43 :contact: http://www.nightmare.com/~ryb/
44
45 Examples
46 ========
47
48 >>> '%X' % CRC32.calcString('123456789')
49 'CBF43926'
50
51 This test function runs all of the defined algorithms on the test
52 input string '123456789':
53
54 >>> _printResults()
55 CRC-5-USB: 19
56 CRC-8-SMBUS: F4
57 CRC-15: 059E
58 CRC-16: BB3D
59 CRC-16-USB: B4C8
60 CRC-CCITT: 29B1
61 CRC-HDLC: 906E
62 CRC-24: 21CF02
63 CRC-32: CBF43926
64 CRC-32C: E3069283
65 CRC-64: 46A5A9388A5BEFFE
66 CRC-256: 79B96BDC0C519B239BE759EC0688C86FD25A3F4DF1E7F054AD1F923D0739DAC8
67
68 Calculating in parts:
69
70 >>> value = CRC32.calcString('1234')
71 >>> '%X' % CRC32.calcString('56789', value)
72 'CBF43926'
73
74 Or, done a different way:
75
76 >>> crc = CrcRegister(CRC32)
77 >>> crc.takeString('1234')
78 >>> crc.takeString('56789')
79 >>> '%X' % crc.getFinalValue()
80 'CBF43926'
81
82 Inversion of a CRC function:
83
84 >>> CRC_CCITT.reverse().reflect().calcWord(54321, 16, 0)
85 1648
86 >>> CRC_CCITT.calcWord(_, 16, 0)
87 54321
88
89 A 15-bit CRC is used in CAN protocols. The following sample CAN frame
90 (in binary here) is converted to hexadecimal for the calcWord call.
91 The bits after the 15-bit CRC are not included in the CRC::
92
93 0 11101000001 0 0 0 0001 00010010 011000010111011 1 1 1 1111111
94
95 This sample CAN frame was found in this paper:
96 <http://www.anthony-marino.com/documents/HDL_implementation_CAN.pdf>
97
98 >>> '%X' % CRC15.calcWord(0x3A08112, 27)
99 '30BB'
100
101 If the CRC is included, the remainder should always be zero:
102
103 >>> print CRC15.calcWord(0x1D0408930BB, 42)
104 0
105
106 A 5-bit CRC is used some kinds of USB packets. Here is a sample
107 start-of-frame packet:
108
109 10100101 01100111000 01111
110
111 (found at <http://www.nital.com/corporate/usb2snooper.html>)
112
113 The first field is the PID (not included in the CRC), the next 11-bit
114 field is the frame number (0xE6, LSb-first order), and the final five
115 bits are the CRC (0x1E, LSb-first order).
116
117 >>> '%X' % CRC5_USB.calcWord(0xE6, 11)
118 '1E'
119 """
120
121
122 __docformat__ = "restructuredtext en"
123
124 __version__ = "20070611"
125
127 """
128 Represents the parameters of a CRC algorithm.
129 """
130
131
132
133
134 - def __init__(self, width, polynomial, name=None, seed=0,
135 lsbFirst=False, lsbFirstData=None, xorMask=0):
136 """
137 :param width:
138
139 The number of bits in the CRC register, or equivalently, the
140 degree of the polynomial.
141
142 :type width:
143
144 an integer
145
146 :param polynomial:
147
148 The generator polynomial as a sequence of exponents
149
150 :type polynomial:
151
152 sequence or integer
153
154 :param name:
155
156 A name identifying algorithm.
157
158 :type name:
159
160 *str*
161
162 :param seed:
163
164 The initial value to load into the register. (This is the
165 value without *xorMask* applied.)
166
167 :type seed:
168
169 an integer
170
171 :param lsbFirst:
172
173 If ``true``, the register shifts toward the
174 least-significant bit (sometimes called the *reflected* or
175 *reversed* algorithim). Otherwise, the register shifts
176 toward the most-significant bit.
177
178 :type lsbFirst:
179
180 *bool*
181
182 :param lsbFirstData:
183
184 If ``true``, input data is taken least-significant bit
185 first. Otherwise, data is taken most-significant bit first.
186 If ``None`` or not given, the value of *lsbFirst* is used.
187
188 :type lsbFirstData:
189
190 *bool*
191
192 :param xorMask:
193
194 An integer mask indicating which bits should be inverted
195 when returning the final result. This is also used for the
196 input value if provided.
197
198 :type xorMask:
199
200 an integer
201 """
202
203 if width > 0:
204 try:
205 polyMask = long(polynomial)
206 except TypeError:
207
208 polynomial = list(polynomial)
209 polynomial.sort()
210 polynomial.reverse()
211 polynomial = tuple(polynomial)
212 else:
213
214 if lsbFirst:
215 polyMask = reflect(polyMask, width)
216 polynomial = (width,)
217 for i in range(width-1,-1,-1):
218 if (polyMask >> i) & 1:
219 polynomial += (i,)
220
221 if polynomial[:1] != (width,):
222 ValueError("mismatch between width and polynomial degree")
223
224 self.width = width
225 self.polynomial = polynomial
226 self.name = name
227 self.seed = seed
228 self.lsbFirst = lsbFirst
229 self.lsbFirstData = lsbFirstData
230 self.xorMask = xorMask
231
232 if not hasattr(width, "__rlshift__"):
233 raise ValueError
234
235
236
238 info = ""
239 if self.name is not None:
240 info = ' "%s"' % str(self.name)
241 result = "<%s.%s%s @ %#x>" % (
242 self.__class__.__module__,
243 self.__class__.__name__,
244 info, id(self))
245 return result
246
254
255 - def calcWord(self, word, width, value=None):
256 """
257 Calculate the CRC of the integer *word* as a sequence of
258 *width* bits.
259 """
260 r = CrcRegister(self, value)
261 r.takeWord(word, width)
262 return r.getFinalValue()
263
265 """
266 Return the algorithm with the bit-order reversed.
267 """
268 ca = CrcAlgorithm(0, 0)
269 ca._initFromOther(self)
270 ca.lsbFirst = not self.lsbFirst
271 if self.lsbFirstData is not None:
272 ca.lsbFirstData = not self.lsbFirstData
273 if ca.name:
274 ca.name += " reflected"
275 return ca
276
278 """
279 Return the algorithm with the reverse polynomial.
280 """
281 ca = CrcAlgorithm(0, 0)
282 ca._initFromOther(self)
283 ca.polynomial = [ (self.width - e) for e in self.polynomial ]
284 ca.polynomial.sort()
285 ca.polynomial.reverse()
286 ca.polynomial = tuple(ca.polynomial)
287 if ca.name:
288 ca.name += " reversed"
289 return ca
290
292 self.width = other.width
293 self.polynomial = other.polynomial
294 self.name = other.name
295 self.seed = other.seed
296 self.lsbFirst = other.lsbFirst
297 self.lsbFirstData = other.lsbFirstData
298 self.xorMask = other.xorMask
299
300
302 """
303 Holds the intermediate state of the CRC algorithm.
304 """
305
306 - def __init__(self, crcAlgorithm, value=None):
307 """
308 :param crcAlgorithm:
309
310 The CRC algorithm to use.
311
312 :type crcAlgorithm:
313
314 `CrcAlgorithm`
315
316 :param value:
317
318 The initial register value to use. The result previous of a
319 previous CRC calculation, can be used here to continue
320 calculation with more data. If this parameter is ``None``
321 or not given, the register will be initialized with
322 algorithm's default seed value.
323
324 :type value:
325
326 an integer
327 """
328
329 self.crcAlgorithm = crcAlgorithm
330 p = crcAlgorithm
331
332 self.bitMask = (1 << p.width) - 1
333
334 word = 0
335 for n in p.polynomial:
336 word |= 1 << n
337 self.polyMask = word & self.bitMask
338
339 if p.lsbFirst:
340 self.polyMask = reflect(self.polyMask, p.width)
341
342 if p.lsbFirst:
343 self.inBitMask = 1 << (p.width - 1)
344 self.outBitMask = 1
345 else:
346 self.inBitMask = 1
347 self.outBitMask = 1 << (p.width - 1)
348
349 if p.lsbFirstData is not None:
350 self.lsbFirstData = p.lsbFirstData
351 else:
352 self.lsbFirstData = p.lsbFirst
353
354 self.reset()
355
356 if value is not None:
357 self.value = value ^ p.xorMask
358
361
363 """
364 Reset the state of the register with the default seed value.
365 """
366 self.value = long(self.crcAlgorithm.seed)
367
369 """
370 Process a single input bit.
371 """
372 outBit = ((self.value & self.outBitMask) != 0)
373 if self.crcAlgorithm.lsbFirst:
374 self.value >>= 1
375 else:
376 self.value <<= 1
377 self.value &= self.bitMask
378 if outBit ^ bool(bit):
379 self.value ^= self.polyMask
380
382 """
383 Process a binary input word.
384
385 :param word:
386
387 The input word. Since this can be a Python ``long``, there
388 is no coded limit to the number of bits the word can
389 represent.
390
391 :type word:
392
393 an integer
394
395 :param width:
396
397 The number of bits *word* represents.
398
399 :type width:
400
401 an integer
402 """
403 if self.lsbFirstData:
404 bitList = range(0,width)
405 else:
406 bitList = range(width-1,-1,-1)
407 for n in bitList:
408 self.takeBit((word >> n) & 1)
409
411 """
412 Process a string as input. It is handled as a sequence of
413 8-bit integers.
414 """
415 for c in s:
416 self.takeWord(ord(c))
417
419 """
420 Return the current value of the register as an integer.
421 """
422 return self.value
423
425 """
426 Return the current value of the register as an integer with
427 *xorMask* applied. This can be used after all input data is
428 processed to obtain the final result.
429 """
430 p = self.crcAlgorithm
431 return self.value ^ p.xorMask
432
433
435 return sum(
436 ((value >> x) & 1) << (width - 1 - x)
437 for x in range(width))
438
442
443
444
445
446
447
448 CRC32 = CrcAlgorithm(
449 name = "CRC-32",
450 width = 32,
451 polynomial = (32, 26, 23, 22, 16, 12, 11, 10, 8, 7, 5, 4, 2, 1, 0),
452 seed = 0xFFFFFFFF,
453 lsbFirst = True,
454 xorMask = 0xFFFFFFFF)
455
456 CRC16 = CrcAlgorithm(
457 name = "CRC-16",
458 width = 16,
459 polynomial = (16, 15, 2, 0),
460 seed = 0x0000,
461 lsbFirst = True,
462 xorMask = 0x0000)
463
464
465 CRC16_USB = CrcAlgorithm(
466 name = "CRC-16-USB",
467 width = 16,
468 polynomial = (16, 15, 2, 0),
469 seed = 0xFFFF,
470 lsbFirst = True,
471 xorMask = 0xFFFF)
472
473 CRC_CCITT = CrcAlgorithm(
474 name = "CRC-CCITT",
475 width = 16,
476 polynomial = (16, 12, 5, 0),
477 seed = 0xFFFF,
478 lsbFirst = False,
479 xorMask = 0x0000)
480
481
482 CRC_HDLC = CrcAlgorithm(
483 name = "CRC-HDLC",
484 width = 16,
485 polynomial = (16, 12, 5, 0),
486 seed = 0xFFFF,
487 lsbFirst = True,
488 xorMask = 0xFFFF)
489
490
491 CRC8_SMBUS = CrcAlgorithm(
492 name = "CRC-8-SMBUS",
493 width = 8,
494 polynomial = (8, 2, 1, 0),
495 seed = 0,
496 lsbFirst = False,
497 xorMask = 0)
498
499
500 CRC24 = CrcAlgorithm(
501 name = "CRC-24",
502 width = 24,
503 polynomial = (24, 23, 18, 17, 14, 11, 10, 7, 6, 5, 4, 3, 1, 0),
504 seed = 0xB704CE,
505 lsbFirst = False,
506 xorMask = 0)
507
508
509 CRC15 = CrcAlgorithm(
510 name = "CRC-15",
511 width = 15,
512 polynomial = (15, 14, 10, 8, 7, 4, 3, 0),
513 seed = 0,
514 lsbFirst = False,
515 xorMask = 0)
516
517
518 CRC32C = CrcAlgorithm(
519 name = "CRC-32C",
520 width = 32,
521 polynomial = (32, 28, 27, 26, 25, 23, 22, 20, 19, 18, 14, 13, 11, 10, 9, 8, 6, 0),
522 seed = 0xFFFFFFFF,
523 lsbFirst = True,
524 xorMask = 0xFFFFFFFF)
525
526
527 CRC5_USB = CrcAlgorithm(
528 name = "CRC-5-USB",
529 width = 5,
530 polynomial = (5, 2, 0),
531 seed = 0x1F,
532 lsbFirst = True,
533 xorMask = 0x1F)
534
535
536 CRC64 = CrcAlgorithm(
537 name = "CRC-64",
538 width = 64,
539 polynomial = (64, 4, 3, 1, 0),
540 seed = 0,
541 lsbFirst = True,
542 xorMask = 0)
543
544
545
546
547
548 CRC256 = CrcAlgorithm(
549 name = "CRC-256",
550 width = 256,
551 polynomial = 0x82E2443E6320383A20B8A2A0A1EA91A3CCA99A30C5205038349C82AAA3A8FD27,
552 seed = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,
553 lsbFirst = True,
554 xorMask = 0)
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
650
652 import sys
653 d = sys.modules[__name__].__dict__
654 algorithms = sorted(
655 (v for (k, v) in d.iteritems() if isinstance(v, CrcAlgorithm)),
656 key=lambda v: (v.width, v.name))
657 for a in algorithms:
658 format = ("%%0%dX" % ((a.width + 3) // 4))
659 print "%s:" % a.name,
660 print format % fn(a)
661
663 import doctest, sys
664 return doctest.testmod(sys.modules[__name__])
665
666 if __name__ == "__main__":
667 _test()
668