Adler32 Checksum Algorithm Explained

Adler-32 is a 32-bit checksum algorithm designed by Mark Adler and used by zlib and the DEFLATE format to detect accidental data corruption. This article explains how the algorithm works, why it was designed, how to implement it in C, and where it is used in practice.

Iman Atarof imaarov

Computer Engineering student focused on systems programming, Linux, data compression, binary file formats and software written in C.

Updated July 27, 2026
115 views

Table of Contents

Introduction to Adler-32

Adler-32 is a 32-bit checksum algorithm designed by Mark Adler. It is primarily used by zlib and appears in many file formats and network protocols that rely on the DEFLATE compression format. Although simple and fast, Adler-32 is designed to detect accidental data corruption rather than malicious modifications.

Use case

Before understanding Adler-32, it's worth asking a simple question: why do we need checksums at all? When data is written to disk, transmitted over network, or copied between systems, individual bits may change because of hardware faults, electrical noise, storage failure or transmission errors. Even a single flipped bit can completely change the meaning of the data. A checksum provides a quick way to detect whether the received data is still identical to the original.

Transmission flow

Original Data
    |
Compute Adler-32
    |
+--------------------------+
|  Data | Adler-32         |
+--------------------------+
    |
Transmission
    |
Receiver
    |
Recompute Adler-32
    |
Compare
Compare Match?      -> Data accepted
Compare Different?  -> Data corrupted

Corruption scenarios

Three outcomes are possible.

  1. The data is corrupted while the checksum is transmitted correctly. The receiver computes a different checksum and detects the error.
  2. The checksum itself is corrupted. The recomputed checksum no longer matches the transmitted checksum, so the receiver again detects an error.
  3. Both the data and the checksum are corrupted. In most cases the mismatch is still detected. However, there is a small probability that the corrupted data produces exactly the corrupted checksum. This situation is known as a collision. Good checksum algorithms are designed so that such collisions are unlikely to occur accidentally.

Implementation

To understand Adler-32 in practice, we can implement a small version of the algorithm in C. The implementation follows the definition of Adler-32: maintaining two running sums, A and B, and combining them into a single 32-bit checksum at the end.

The complete implementation does not require any external libraries.

Constants

#define BASE_MODULO       65521
#define INIT_SUM_A        1
#define INIT_SUM_B        0

Adler-32 uses two 16-bit sums internally:

  • A starts with the value 1
  • B starts with the value 0

The calculations are performed modulo 65521, which is the largest prime number smaller than 2^16. The modulo operation keeps both sums within a predictable range while allowing the final result to fit into a 32-bit value.

Maintaining the Two Sums

The core of Adler-32 is the update of the two accumulators:

uint32_t sumA = INIT_SUM_A;
uint32_t sumB = INIT_SUM_B;
for (size_t i = 0; i < message_size; i++) {
    sumA += message[i];
    sumB += sumA;
    sumA %= BASE_MODULO;
    sumB %= BASE_MODULO;
}

For every byte in the input:

  1. Add the byte value to sumA.
  2. Add the new value of sumA to sumB.
  3. Reduce both values using modulo 65521.

The first sum represents the accumulated value of all bytes:
A = 1 + byte1 + byte2 + ... + byten

The second sum represents the accumulation of all previous values of A:
B = A1 + A2 + A3 + ... + An

Because B depends on the history of A, it can detect changes in both the value and the position of bytes.

Combining the Final Checksum

After processing all bytes, Adler-32 combines both 16-bit sums into a single 32-bit value:

return (sumB << 16) + sumA;

The final checksum layout is:

31                16 15                 0
+------------------+------------------+
|         B        |         A        |
+------------------+------------------+

The upper 16 bits contain B, and the lower 16 bits contain A. For example:

A = 0x1234
B = 0xabcd

Result: 0xabcd1234

Why Adler-32 Uses Two Sums

The first sum, A, tracks the total of all bytes in the message. If only A were used, different byte sequences could produce the same result.

The second sum, B, tracks the running history of A. This makes the checksum sensitive to the position of each byte as well as its value.

A starts at 1 instead of 0 so that an empty message produces a non-zero checksum (0x00000001), which avoids a special all-zero result.

Limitation of Adler-32

Adler-32 is extremely fast and simple, but it has weaker error-detection properties than stronger checksums such as CRC32.

In particular:

  1. It produces more collisions than CRC32.
  2. Its distribution is weaker for very short messages.
  3. It is not resistant to intentional modification.

For this reason, Adler-32 is best suited for detecting accidental corruption in compressed data streams, while cryptographic hashes such as SHA-256 should be used when security is required.

Worked Example: Adler-32 of "ABC"

To see how Adler-32 works, let's calculate the checksum for the string "ABC".

ASCII values:

A = 65

B = 66

C = 67

Initial values:

sumA = 1

sumB = 0

After processing 'A' (65):

sumA = 1 + 65 = 66

sumB = 0 + 66 = 66

After processing 'B' (66):

sumA = 66 + 66 = 132

sumB = 66 + 132 = 198

After processing 'C' (67):

sumA = 132 + 67 = 199

sumB = 198 + 199 = 397

The final Adler-32 checksum is:

sumA = 199 = 0x00C7

sumB = 397 = 0x018D

checksum = (sumB << 16) | sumA

= 0x018D00C7

Therefore, the Adler-32 checksum of "ABC" is:

0x018D00C7

Notice that sumA tracks the cumulative byte values, while sumB accumulates the history of sumA. This is what makes Adler-32 sensitive to both the values and the order of the bytes. (Here the sums are combined with a bitwise OR instead of addition, as in the earlier C code, both give the same result, since sumA never exceeds 16 bits and so the two halves never overlap.)

RFC Reference

Adler-32 was first formally specified in RFC 1950, which defines the zlib compressed data format. Section 2.2 of that document describes the algorithm precisely, including the initial values A=1 and B=0, the modulo 65521 operation, and the final combination of the two 16‑bit sums into a 32‑bit checksum. You can read the full specification at RFC 1950 – ZLIB Compressed Data Format Specification.

Because Adler-32 is part of the zlib format, it appears anywhere zlib streams are used, most notably inside PNG image files, whose compressed pixel data is wrapped in a zlib stream, and in protocols that use zlib-style "deflate" content encoding. It's worth noting that gzip files and ZIP archives, although they also rely on DEFLATE compression (defined separately in RFC 1951), do not use Adler-32 for their checksums, they use CRC-32 instead. The full DEFLATE specification is available at RFC 1951 – DEFLATE Compressed Data Format Specification.

Conclusion

Adler-32 remains a practical checksum choice when speed and simplicity outweigh the need for cryptographic security. As we saw in the Why Adler-32 Uses Two Sums section, the two‑accumulator design makes the checksum sensitive to both byte values and their positions, catching common transmission errors with very little computational overhead.

However, the Limitation of Adler-32 discussion makes clear that it is not suitable for all situations. Short messages and highly repetitive data can lead to a higher collision rate than a CRC‑32, and the algorithm offers no protection against intentional tampering.

When selecting a checksum, consider the nature of your data and the threats you face:

  • For accidental corruption in bulk data streams, Adler-32 is an excellent, lightweight option.
  • When you need stronger error detection but still want performance, CRC‑32 is often a better fit.
  • If data integrity is critical, whether against accidental changes or deliberate modification, use a cryptographic hash like SHA‑256 instead.

Ultimately, Adler-32 has earned its place in the history of data integrity by being small, fast, and good enough for its intended purpose. Understanding how it works, as detailed in this guide, helps you decide exactly when "good enough" is the right engineering choice.