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

## Chapter 6 — Twelve characters are not the digest

<!-- open-cyber-academy:lesson-figures:start ch-06 -->
### Lesson map

Lesson 06. Map, example, EX052.

```mermaid
flowchart TD
  H["sha256 of the bytes"] --> X["hexdigest, 64 characters"]
  X --> S["slice the first 12"]
  S --> Q{"Is the slice the key?"}
  Q -->|No| K["The lookup used the full digest"]
```

The page shows a prefix. The dict key is the whole fingerprint.

### Logical drawing

```text
computed
  hexdigest, 64 hex characters
printed
  the first 12 only
lookup
  the full digest, before the slice
three prefixes on the page
  0edf30e2fa30
  3e5d3b83407c
  ffcab6e8630a
```
<!-- open-cyber-academy:lesson-figures:end ch-06 -->

### Learning outcomes

After this chapter, you should be able to:

1. Separate `hexdigest` from the slice `h[:12]`.
2. Say which value is the dict key.
3. Refuse a note that treats a prefix as the stored fingerprint.

### 6.1 The slice is a reading aid. The key is the full digest.

`hashlib.sha256(data).hexdigest()` returns 64 hexadecimal characters. That length is the whole SHA-256 result written in hex: 256 bits, four bits to a character. The print uses `h[:12]`, so the page keeps the first 12 characters and drops the other 52. Twelve hex characters are 48 bits. They are enough to tell these three rows apart on a classroom page. They are not the value the script stored for the lookup.

The lookup happens before the slice is a problem for a careful reader, because the code computes `h` once and then uses that same `h` twice. `known_bad.get(h, 'no match')` searches for the 64-character string. The f-string then prints `h[:12]`. A classmate who copies only the visible prefix has not copied the key. Two different files can share a 12-character opening in principle. This run's three openings differ, and that fact does not promote the prefix into an identity.

Kornblum (2006) describes a way to notice files that are almost the same. This script does not do that. It asks whether the full digest is exactly the one key. A one-byte change in the byte string would miss. The chapter does not print the hidden 52 characters, because the lab did not print them.

| Piece | Role in this file |
|---|---|
| `hexdigest()` | 64-character fingerprint |
| `h[:12]` | The characters on the page |
| `known_bad.get(h, ...)` | Lookup of the full fingerprint |
| The other 52 characters | Computed, not printed |

### 6.2 Worked example

| Offered reading | What the file does | Decision |
|---|---|---|
| `3e5d3b83407c` is on the installer row | First 12 of that row's digest | Keep |
| The key is those 12 characters | The key is the unprinted full digest | Refuse |
| "Paste the prefix into a new list as the key." | The list was built from `hexdigest()` | Refuse |
| The three prefixes differ | True of this run, and still a prefix | Keep |

> **Synthetic case.** The lab page shows prefixes only.

### Errors and limits

Do not invent the hidden characters in order to look complete.

### Apply

- **EX052 — Prefix.** Each row shows 12 hex characters. Is that slice the dict key, and does this page print the other 52 characters? *Rubric:* 3 = no; `hexdigest` is 64 characters; the lookup uses the full digest; the page prints `h[:12]` only; do not fill in the rest;; 2 = the key is the full digest and the rest is unprinted;; 1 = the prefix only;; 0 = none.

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

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

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

## Worked answers

<a id="answer-ex052"></a>
**EX052.** No. `hexdigest` is 64 characters. The lookup uses that full digest. The page prints the first 12 only. Do not fill in the rest.
