Skip to content

Commit 67c6d79

Browse files
author
PentesterTN
committed
Add CRC-32 checksum implementation
Lookup-table based CRC-32 using the standard reflected polynomial. Output verified against zlib.crc32() in doctests.
1 parent 68473af commit 67c6d79

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

hashes/crc32.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
"""
2+
CRC-32 is a cyclic redundancy check algorithm that produces a 32-bit checksum.
3+
It is widely used for error detection in network transmissions and file integrity
4+
checks (ZIP, PNG, gzip, etc.). This implementation uses the reflected polynomial
5+
0xEDB88320 with a precomputed 256-entry lookup table.
6+
7+
Reference: https://en.wikipedia.org/wiki/Cyclic_redundancy_check
8+
"""
9+
10+
11+
def _generate_crc32_table() -> list[int]:
12+
"""
13+
Build a 256-entry lookup table for CRC-32 using the reflected
14+
polynomial 0xEDB88320.
15+
16+
>>> table = _generate_crc32_table()
17+
>>> len(table)
18+
256
19+
>>> hex(table[0])
20+
'0x0'
21+
>>> hex(table[1])
22+
'0x77073096'
23+
"""
24+
table: list[int] = []
25+
for byte in range(256):
26+
crc = byte
27+
for _ in range(8):
28+
if crc & 1:
29+
crc = (crc >> 1) ^ 0xEDB88320
30+
else:
31+
crc >>= 1
32+
table.append(crc)
33+
return table
34+
35+
36+
_CRC32_TABLE = _generate_crc32_table()
37+
38+
39+
def crc32(data: bytes) -> int:
40+
"""
41+
Compute the CRC-32 checksum for the given bytes.
42+
43+
The output matches Python's ``zlib.crc32()`` for the same input.
44+
45+
>>> crc32(b'')
46+
0
47+
>>> hex(crc32(b'hello'))
48+
'0x3610a686'
49+
>>> crc32(b'hello world')
50+
222957957
51+
>>> hex(crc32(b'The quick brown fox jumps over the lazy dog'))
52+
'0x414fa339'
53+
54+
Verify against zlib:
55+
>>> import zlib
56+
>>> crc32(b'hello world') == zlib.crc32(b'hello world')
57+
True
58+
>>> crc32(b'\\x00\\xff\\x55\\xaa') == zlib.crc32(b'\\x00\\xff\\x55\\xaa')
59+
True
60+
"""
61+
crc = 0xFFFFFFFF
62+
for byte in data:
63+
lookup_index = (crc ^ byte) & 0xFF
64+
crc = (crc >> 8) ^ _CRC32_TABLE[lookup_index]
65+
return crc ^ 0xFFFFFFFF
66+
67+
68+
if __name__ == "__main__":
69+
import doctest
70+
71+
doctest.testmod()

0 commit comments

Comments
 (0)