crc32

Calculates the CRC-32 checksum of a string and returns it as an integer.

Signature
crc32(string $string): int
  • Added in PHP 4.0.1

Parameters

ParameterTypeDescription
$stringstringThe data to compute the checksum for. Binary safe.

Return value

intThe CRC-32 checksum of the string as an integer.

Errors

Nothing. Any string yields a checksum.

crc32() computes the 32-bit cyclic redundancy check used by ZIP, gzip and PNG. It is an error-detecting code, not a hash function: it is designed to catch accidental corruption on a wire or a disk, and it does that extremely cheaply.

When to reach for it

Use it when you need a small, fast integer fingerprint and nobody is trying to fool you — validating a ZIP entry, checking that a serial port frame arrived intact, or turning a string into a stable integer for sharding or picking a colour. It is far faster than MD5 and the result fits in an INT column.

What trips people up

The return value is a signed PHP integer. On a 32-bit build any checksum above 2^31 comes back negative, so crc32($s) can print something like -1897434577; on a 64-bit build every result is a positive integer. Format it with sprintf('%u', ...) for the unsigned decimal form, or sprintf('%08x', ...) for the eight-hexit form that other tools print. dechex() and the %x formatter both convert the result to unsigned for you, but they drop leading zeros, so pad to eight characters — str_pad(dechex(crc32($s)), 8, '0', STR_PAD_LEFT) is exactly what hash('crc32b', $s) returns.

Also note that hash('crc32', ...) is not the same algorithm; the one matching crc32() is hash('crc32b', ...).

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Check a received data frame against the checksum its sender appended.
  • Map a cache key to one of N servers with a cheap integer modulo.
  • Store a compact change-detection value for a row in an INT column.

Frequently asked questions

Why does crc32 return a negative number?

PHP integers are signed, so on 32-bit builds checksums above 2147483647 wrap into negative values. Use sprintf('%u', $c) to print the unsigned form.

What is the difference between crc32 and hash('crc32b')?

crc32() matches hash('crc32b', ...), which is the standard CRC-32 used by ZIP and gzip. The algorithm named 'crc32' inside hash() uses a different bit ordering and gives a different result.

Can crc32 be used to verify a download?

Only against accidental corruption. It is trivial to craft a different file with the same CRC-32, so use sha256 when an attacker could have modified the file.

More examples

Detecting a single-byte change

One flipped digit produces a completely different checksum, so the mismatch is caught. The final check confirms the value is deterministic for identical input.

Example · php
<?php
$frame    = "SENSOR:23.5C";
$received = "SENSOR:23.6C";

printf("sent     %08x%s", crc32($frame), PHP_EOL);
printf("received %08x%s", crc32($received), PHP_EOL);
var_dump(crc32($frame) === crc32($received));
var_dump(crc32($frame) === crc32("SENSOR:23.5C"));

Cheap consistent sharding

Each key lands on a fixed server every time the script runs. abs() is used because crc32() may return a negative int, and a negative modulo would produce an invalid array index.

Example · php
<?php
$servers = ['cache-a', 'cache-b', 'cache-c'];

foreach (['user:1', 'user:2', 'user:3', 'user:4'] as $key) {
    $idx = abs(crc32($key)) % count($servers);
    echo $key, ' -> ', $servers[$idx], PHP_EOL;
}

Discussion

  • Be the first to comment on this lesson.