<a id="ch-08"></a>

## Chapter 8 — Sixteen hex characters are not the digest

### 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.

| 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

| 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? *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.

<!-- open-cyber-academy:chapter-navigation:start ch-08 -->
### Continue studying — lesson 08 (chapter 08 of 20)

[← Chapter 07](#ch-07) · [Course chapter index](../SUBJECTS.md) · [Chapter 09 →](#ch-09)

Continue to the next authored lesson.
<!-- open-cyber-academy:chapter-navigation:end -->

## Worked answers

<a id="answer-ex054"></a>
**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.
