Home / Alt manpages / crc32(1)

  • crc32(1)
  • User command
  • linux

Check Files with crc32 Without Mistaking It for Security

Use crc32 to calculate a checksum, compare two copies for accidental corruption, and know exactly where its guarantees stop.

The examples use crc32 from libarchive-zip-perl version 1.68-1, installed here as /usr/bin/crc32. Allow about ten minutes. You need a shell and read access to the files you want to check.

The normal workflow is unprivileged and read-only: crc32 does not alter its input files. Do not use sudo just to calculate a checksum. If a file is deliberately restricted, resolve that access decision separately rather than making a routine check run as root.

1. Check the installed command

Confirm which executable will run and read the local manual page if you need to check the interface:

$ command -v crc32
/usr/bin/crc32
$ dpkg-query -W -f='${Package} ${Version}\n' libarchive-zip-perl
libarchive-zip-perl 1.68-1
$ man crc32

The command accepts one or more filenames. It has no documented options in this manpage. That means a familiar-looking request such as crc32 --help is not a help request: --help is treated as a filename and the program tries to open it.

Checkpoint

The command should be present, and the package version should be the one you intend to document or reproduce. Package versions vary between distributions, so record yours when a checksum check is part of an incident report or build record.

2. Calculate one checksum

Create a small test file in a working directory, then pass its filename as an ordinary argument:

$ printf 'hello\n' > sample.txt
$ crc32 sample.txt
363a3020

The output is an eight-character hexadecimal CRC-32 value followed by a newline. The value describes the bytes currently in the file, including the newline added by printf. Changing even one byte should normally produce a different value, so be precise about line endings and about whether a command adds a final newline.

Verify the file still exists and was not accidentally replaced while you were working:

$ file sample.txt
sample.txt: ASCII text
$ test -r sample.txt && echo readable
readable

file is only a basic sanity check. It does not prove that the content is the expected content, and a matching CRC does not prove that a file came from a trusted source.

3. Check several files in one pass

Give the command multiple filenames when you want a compact report:

$ printf 'another file\n' > second.txt
$ crc32 sample.txt second.txt
363a3020	sample.txt
cbd98ad8	second.txt

Each output line contains the checksum, a tab, and the corresponding filename. The checksum for second.txt above is an example of the output shape, not a value to copy blindly: calculate it on your own machine because the bytes must match exactly. If a filename contains spaces, quote it:

$ printf 'data\n' > 'report copy.txt'
$ crc32 'report copy.txt'
e6c1c582	report copy.txt

Keep the quotes around the shell argument. Without them, the shell passes report and copy.txt as two separate filenames.

4. Compare a copy

A useful integrity check is to calculate both files and compare the reported values. First make a copy without changing the original:

$ cp -- sample.txt sample-copy.txt
$ crc32 sample.txt sample-copy.txt
363a3020	sample.txt
363a3020	sample-copy.txt

Matching values are evidence that the two byte streams produced the same CRC-32 value. To check whether the files are actually byte-for-byte identical, use cmp as well:

$ cmp --silent -- sample.txt sample-copy.txt
$ printf '%s\n' "$?"
0

Status 0 from cmp means the files match exactly. A non-zero status means they differ or could not be compared. This is a stronger direct comparison for two files, while crc32 is convenient when you need a short recorded value or are checking a stream of stored files.

Checkpoint

For a copied file, expect the same checksum and a zero status from cmp. If only the checksums match, do not describe that as proof of equality: CRC-32 has collisions.

5. Handle missing files and awkward defaults

The interface is filename-only. A missing file produces an error message:

$ crc32 does-not-exist.bin
/usr/bin/crc32: Cannot open does-not-exist.bin: No such file or directory

Check the path and permissions without changing anything:

$ ls -l -- does-not-exist.bin
$ test -r -- does-not-exist.bin && echo readable

On this installed version, an open failure can still leave the command with a successful shell status. Do not build a script that trusts $? alone. Validate that every requested filename appears in the output, and inspect standard error separately when the command is part of a larger check:

if ! output=$(crc32 sample.txt); then
    printf '%s\n' 'crc32 could not complete' >&2
    exit 1
fi
if ! printf '%s\n' "$output" | grep -F -- 'sample.txt' >/dev/null; then
    printf '%s\n' 'crc32 did not produce a clean result' >&2
    exit 1
fi
printf '%s\n' "$output"

The command also does not read standard input: crc32 - means a file literally named -, not a request to checksum a pipe. If you need to capture diagnostics in automation, redirect standard error to a deliberately chosen temporary file and inspect it before removing it.

6. Know the security boundary

Security boundary

CRC-32 is designed for detecting accidental errors in transmission or storage. It is not a cryptographic hash and is not intended to protect against malicious modification. An attacker can deliberately produce or choose data with a matching CRC, so do not use it to verify downloads, software releases, evidence, backups against an adversary, or the authenticity of a message.

For those cases, use the cryptographic hash or signature scheme specified by the publisher or your operational process. On a local system, a command such as sha256sum may be appropriate for an ordinary file digest, but it does not establish authenticity unless the trusted digest or signature came through a trustworthy channel. Keep the CRC result when the format or protocol specifically calls for CRC-32; add a cryptographic check when the threat model requires one.

Done means

  • Tool and version known. crc32 is installed, and you know the package version being used.
  • Interface respected. You passed filenames as arguments and did not assume that - reads standard input or that --help is a valid option.
  • Output verified. The output contains an eight-character hexadecimal value and the matching filename for every successful input.
  • Copies checked properly. A copied file was checked with both crc32 and cmp when byte-for-byte equality mattered.
  • Boundary respected. You treated CRC-32 as accidental-error detection, not as protection against deliberate tampering.