Skip to content

hashes/adler32.py: checksum diverges from the Adler-32 spec for any non-ASCII input (sums Unicode code points instead of bytes) #15635

Open

Description

@rahul05ranjan

Repository commit

6e03a48

Python version (python --version)

Python 3.13.5

Dependencies version (pip freeze)

None needed — hashes/adler32.py only uses the standard library.

Expected behavior

Adler-32 is defined over a byte stream, so adler32(text) should produce the same value as the reference implementation on the text's UTF-8 bytes (zlib.adler32(text.encode())), for any input text. The sibling module hashes/crc32.py does exactly this (it takes bytes and matches zlib.crc32 for every input).

Actual behavior

adler32 iterates Unicode code points and sums ord(char), so it only matches the real Adler-32 for pure-ASCII text. Every non-ASCII character silently produces a checksum that no standard implementation would produce:

>>> from hashes.adler32 import adler32
>>> import zlib
>>> adler32('Algorithms')
363791387
>>> zlib.adler32('Algorithms'.encode())
363791387
>>> adler32('€100')
2211914046
>>> zlib.adler32('€100'.encode())
196018850
>>> adler32('日本語テスト')
3064850950
>>> zlib.adler32('日本語テスト'.encode())
2053180537

For a checksum/integrity algorithm, producing values that disagree with every other Adler-32 implementation (zlib, Python's zlib.adler32, etc.) for non-ASCII input makes the results unusable for verification.

Steps to reproduce

python - <<'EOF'
from hashes.adler32 import adler32
import zlib
for s in ['Algorithms', 'héllo', '€100', '日本語テスト']:
    print(s, adler32(s), zlib.adler32(s.encode()), adler32(s) == zlib.adler32(s.encode()))
EOF

Output: only 'Algorithms' matches; the other three lines end with False.

Suspected cause

hashes/adler32.py (adler32(plain_text: str)) uses a = (a + ord(plain_chr)) % MOD_ADLER per character. Encoding the input to UTF-8 first (like crc32.py already requires bytes) would keep it on-spec for all inputs; the doctests only cover ASCII strings, so this never shows up in the test run.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions