Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java CRC32: detect a byte change without claiming authenticity

Last updated: 29 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

CRC32 computes a checksum of a byte sequence for detecting accidental changes; it is not proof of who produced that sequence.

Download Java source kit

This complete program targets Java 8. Its displayed output is checked by the tutorial validation script.

Compare the same encoded bytes

The manifest fixture calculates the checksum of a UTF-8 record, checks it again without changing the bytes, then changes one byte and observes a different value. The comparison is on encoded bytes, not characters, because encoding and line-ending changes alter the stored representation.

A checksum match is useful evidence that an accidental transmission change was not observed by that check. It is not a guarantee that two different messages cannot share a checksum. A sender can also replace a payload and its unchecked checksum together.

Choose the trust boundary separately

The checksum object keeps mutable running state. Reset or create a fresh instance for an independent record, otherwise the result includes earlier bytes. The fixture uses a new instance per call so the record boundary is explicit.

When adversarial modification matters, define a signature or keyed authentication design and key ownership instead of upgrading a checksum label. Random token material and authenticated transport solve other problems; neither makes an untrusted supplied CRC an authentication mechanism.

Working program

Java
import java.nio.charset.StandardCharsets;
import java.util.zip.CRC32;
public class ManifestChecksum {
    static long checksum(byte[] bytes){CRC32 crc=new CRC32();crc.update(bytes);return crc.getValue();}
    public static void main(String[] args) {
        byte[] manifest="receipt=125".getBytes(StandardCharsets.UTF_8);
        long expected=checksum(manifest);System.out.println(expected==checksum(manifest));
        byte[] changed=manifest.clone();changed[changed.length-1]=(byte)'6';
        System.out.println(expected==checksum(changed));
    }
}

Output

Output
true
false

Costs and boundaries

Checksum calculation takes O(b) time for b bytes and bounded checksum state. The fixture already holds the byte array; a streaming calculation can avoid retaining the entire file. No collision-resistance or authenticity guarantee is made.

Common Mistakes

  • Calculate over the exact bytes whose integrity you want to check.
  • Do not reuse running state across unrelated records accidentally.
  • Do not use an untrusted CRC as an authentication decision.

Read next

Java byte streams: partial reads and bounded copying, Java ZIP inputs: bounded staging and rejected path traversal, Java SecureRandom: token entropy, encoding and comparison boundaries.

java
crc32-boundary
Storage details