MessageDigest hashes bytes; a text digest is reproducible only when the text-to-byte encoding is part of the protocol.
Java SHA-256: hash declared bytes, not an implicit string encoding
Define the byte contract
A receipt checksum calculated with the platform default charset can change when the job moves to another runtime. Encode the exact text with UTF-8 before hashing, and decide separately whether line endings and Unicode normalization are canonicalized. The fixture uses an accented receipt marker so the byte count is visible.
A plain digest detects accidental changes only when its expected value is trusted through another channel. It does not authenticate a message from an attacker who can replace both bytes and digest. Use HMAC verification for shared-key authentication.
Keep passwords out of this workflow
SHA-256 is intentionally fast. Storing password digests directly with this method makes guessing inexpensive; password storage needs a purpose-built, tuned password hashing scheme and its own migration policy. Unicode encoding covers the bytes being hashed.
Working program
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Arrays;
public class ReceiptDigestBytes {
public static void main(String[] args) throws Exception {
byte[] receiptBytes = "café".getBytes(StandardCharsets.UTF_8);
byte[] first = MessageDigest.getInstance("SHA-256").digest(receiptBytes);
byte[] second = MessageDigest.getInstance("SHA-256").digest(receiptBytes);
System.out.println("bytes=" + receiptBytes.length);
System.out.println("digestBytes=" + first.length);
System.out.println("same=" + Arrays.equals(first, second));
}
}Output
bytes=5
digestBytes=32
same=trueCost and ownership
Hashing visits the input bytes and keeps fixed-size digest state, while this program allocates the UTF-8 byte array and result. For a large file, stream chunks instead of loading it all into memory. The digest cannot reconstruct the input or substitute for a MAC.
Common Mistakes
- Do not call getBytes without an explicit charset in a wire protocol.
- Do not treat a public digest as proof of origin.
- Do not store passwords as a bare SHA-256 digest.
Read next
Java Unicode: code units, code points and UTF-8 bytes, hmac sha256 verify, message digest bytebuffer, Java byte streams: partial reads and bounded copying.
