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.
The route
Jump straight to the step you need, or tick off Done means at the end.
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
crc32is installed, and you know the package version being used.- You passed filenames as arguments and did not assume that
-reads standard input or that--helpis 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
crc32andcmpwhen byte-for-byte equality mattered. - You treated CRC-32 as accidental-error detection, not as protection against deliberate tampering.