TheAlgorithms/Python · #14035

feat: add CRC32 hash algorithm implementation

rodrigobnogueira · merged Sep 21, 20262 files · 125 + / 0
DIRECTORY.md1 + / 0
@@ -686,6 +686,7 @@ ## [Hashes](hashes)   * [Adler32](hashes/adler32.py)   * [Chaos Machine](hashes/chaos_machine.py)+  * [Crc32](hashes/crc32.py)   * [Djb2](hashes/djb2.py)   * [Elf](hashes/elf.py)   * [Enigma Machine](hashes/enigma_machine.py)
hashes/crc32.pyadded124 + / 0
@@ -0,0 +1,124 @@+"""+CRC32 (Cyclic Redundancy Check 32-bit) Hash Algorithm++This module implements the CRC32 hash algorithm, a non-cryptographic hash function+widely used for error detection and data integrity verification.++CRC32 is commonly used in:+- ZIP file format for data integrity+- Ethernet frame check sequences+- PNG image format for chunk verification+- Gzip compression++The algorithm uses the IEEE 802.3 polynomial (0xEDB88320 in reversed bit order)+and produces a 32-bit hash value.++Note: CRC32 is NOT suitable for cryptographic purposes. It's designed for+error detection, not security. For cryptographic hashing, use SHA-256 or similar.++Reference:+- https://en.wikipedia.org/wiki/Cyclic_redundancy_check+- https://www.rfc-editor.org/rfc/rfc1952.html (GZIP specification)+"""+++def _generate_crc32_table() -> list[int]:+    """+    Generate the CRC32 lookup table for optimized calculation.++    Uses the IEEE 802.3 polynomial: 0xEDB88320 (reversed bit order)++    >>> table = _generate_crc32_table()+    >>> len(table)+    256+    >>> hex(table[0])+    '0x0'+    >>> hex(table[128])+    '0xedb88320'+    """+    polynomial = 0xEDB88320+    table = []++    for i in range(256):+        crc = i+        for _ in range(8):+            if crc & 1:+                crc = (crc >> 1) ^ polynomial+            else:+                crc >>= 1+        table.append(crc)++    return table+++CRC32_TABLE = _generate_crc32_table()+++def crc32(data: bytes) -> int:+    """+    Calculate the CRC32 hash of byte data.++    Args:+        data: Byte data to calculate the hash for++    Returns:+        CRC32 hash as a 32-bit integer (0 to 4294967295)++    Raises:+        TypeError: If data is not of type bytes++    >>> crc32(b"Hello World")+    1243066710++    >>> crc32(b"")+    0++    >>> crc32(b"The quick brown fox jumps over the lazy dog")+    1095738169++    >>> crc32(b"a")+    3904355907++    >>> crc32(b"abc")+    891568578++    >>> crc32(b"123456789")+    3421780262++    >>> crc32(b"Python")+    2742599054++    >>> crc32(b"Algorithms")+    3866870335++    >>> crc32(b"CRC32")+    4128576900++    >>> crc32(b"\\x00\\x00\\x00\\x00")+    558161692++    >>> import zlib+    >>> test_data = b"Verify with zlib"+    >>> crc32(test_data) == zlib.crc32(test_data)+    True+    """+    if not isinstance(data, bytes):+        msg = f"data must be bytes, not {type(data).__name__}"+        raise TypeError(msg)++    crc = 0xFFFFFFFF++    for byte in data:+        table_index = (crc ^ byte) & 0xFF+        crc = (crc >> 8) ^ CRC32_TABLE[table_index]++    return crc ^ 0xFFFFFFFF+++if __name__ == "__main__":+    import doctest++    doctest.testmod()++    print(f"CRC32 of 'Hello World': {crc32(b'Hello World')}")+    print(f"CRC32 of empty bytes: {crc32(b'')}")