Home / Alt manpages / crc32(1)

  • crc32(1)
  • User command
  • linux

Check Files with crc32 Without Mistaking It for Security

You will use crc32 to calculate a CRC-32 value for one or more files, compare two copies, and recognise the cases where a stronger hash is required. 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

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

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