OpenCyber Academy
Rapid course · Lesson 8 · English
Course code: OCA-020Lesson 08: OCA-020-A008

Sixteen hex characters are not the digest

Open, free learning for anyone who wants to protect people and technology. No account is required to read this text or its worked answers.

Lesson map

Lesson 08. Map, example, EX054.

flowchart TD
  H["Full SHA-256 hex digest"] --> J["JSON keeps the first 16 characters"]
  J --> C["The later check still compares the full digest"]

A short prefix can look familiar and still be the wrong object to trust.

Logical drawing

{
 "model.bin": "e96760a87768717b",
 "tokenizer.json": "f63d2ddabc61f2d9",
 "config.yaml": "e5bbb570ca0fcb87"
}

Learning outcomes

After this chapter, you should be able to:

  1. Name the three 16-character prefixes and the file each one labels.
  2. Say that json.dumps sliced each digest before printing.
  3. Refuse to treat a matching prefix as a passed integrity check.

8.1 The manifest stores the full hex string. The JSON object slices it.

Each artefact is hashed with hashlib.sha256 and the full .hexdigest() is stored. SHA-256 as hex is 64 characters. The print is json.dumps({k: v[:16] for k, v in manifest.items()}, indent=1). The slice keeps characters 0 through 15. Indent 1 puts one space after the newline. The dict's insertion order is model.bin, then tokenizer.json, then config.yaml, so the JSON object follows that order.

The three prefixes are e96760a87768717b, f63d2ddabc61f2d9 and e5bbb570ca0fcb87. They identify the clean bytes that were hashed: bytes(range(256))*40 for the model file, the tiny vocabulary bytes for the tokenizer, and the two-line config. They are abbreviations of those clean digests. The comparison later in the file asks whether a newly computed full digest equals manifest[n]. A 16-character glance is not that comparison.

Lesson table; scroll horizontally to read all columns →

Printed prefix File What it is not
e96760a87768717b model.bin The full digest
f63d2ddabc61f2d9 tokenizer.json A passing check
e5bbb570ca0fcb87 config.yaml Proof the received bytes match

8.2 Worked example

Lesson table; scroll horizontally to read all columns →

What Omar sees What he may conclude
Sixteen hex characters beside model.bin This is the clean manifest's prefix
The same prefix after a file copy Still only a prefix, until the full digest is compared
"The prefix matches, so the file is intact." Refuse that sentence

Synthetic case. These bytes are constructed in the lab. They are not a vendor model.

Errors and limits

A familiar 16-character string can belong to the manifest and say nothing about the bytes now on disk.

Apply

  • EX054 — Sixteen characters. What do the three JSON strings represent, and why is a matching prefix not an integrity pass?
    Show marking criteria
    Rubric: 3 = they are the first 16 hex characters of the clean SHA-256 digests, in insertion order; the check compares the full digest;; 2 = prefixes of the clean digests, not the check;; 1 = "short hashes" with no file names;; 0 = treats the prefix as a pass.
Worked answers

EX054. The JSON strings are the first 16 hex characters of the clean SHA-256 digests: e96760a87768717b for model.bin, f63d2ddabc61f2d9 for tokenizer.json, and e5bbb570ca0fcb87 for config.yaml. The manifest stores the full digest. A later check compares full digests. A familiar prefix is not a pass.