PDF file structure: the index near the end is the whole trick
A PDF is a container of numbered objects at arbitrary offsets, with an index at the end and one pointer, startxref, telling a parser where to begin. That is why page 3 can sit before page 1 in the bytes, why an incremental update contains the same object twice, and why a truncated file can still open.
Independent guide. We describe a documented format and parse text the reader pastes locally. Nothing here strips a permission or opens an encrypted document. Encryption and digital signatures are outside this page.
Findings
From Wikipedia's PDF article, File format section, retrieved 18 Oct 2026. Rows follow the source's wording.
| Element | What the source states | Confidence | What it does not prove |
|---|---|---|---|
| Magic number | a header with a readable magic number and version, for example %PDF-1.7. The infobox lists the magic as %PDF- | High | — |
| Mostly ASCII | organised with ASCII characters, except elements that may have binary content | High | — |
| Underlying model | a subset of a COS ("Carousel" Object Structure) format | High | — |
| Nine object types | booleans, reals, integers, strings in (...) or <...>, names starting with /, arrays, dictionaries, streams, and null | High | — |
| Indirect objects | numbered with an object number and a generation number, between obj and endobj | High | — |
| Streams | optionally compressed binary data, preceded by a dictionary, between stream and endstream | High | The filter names a given file uses. Read them from that file's stream dictionary |
| The index | a cross-reference table near the end, giving each indirect object's byte offset | High | — |
| Why it exists | random access, and small changes without rewriting the file (incremental update) | High | — |
| Pre-1.5 shape | always a special ASCII format, marked with xref, after the main body | High | — |
| 1.5 onward | optional cross-reference streams, with integer widths in the /W array. A hybrid file may contain both | High | — |
| Footer | startxref, then the offset, then %%EOF. Without an xref stream, a trailer dictionary precedes it | High | — |
| Text is not plain text | typeset text is stored as content streams | High | — |
| Provenance | Adobe 1991–2008, ISO from 2008; initial release 15 June 1993; application/pdf; ISO 32000-2 | High | — |
| Adobe-proprietary parts | PDF 1.7 includes XFA and a JavaScript extension for Acrobat, referenced by ISO 32000-1 and not supported by many third-party implementations | High | Whether a given file uses them. Check the catalogue for /XFA and /JavaScript |
| ISO 32000-2 drops them | it does not include proprietary technologies as normative references | High | — |
| Text order is derived | content streams, with rendering described as declarative after loops and branches are removed | Medium | Not read in this run: the exact positioning operators. Copy-paste order differing from visual order is an inference. Test it on your own file before publishing it. |
| Encryption and signatures | the specification provides for them, plus attachments and metadata | High | The encryption mechanism itself is out of scope |
| Zip-bomb hazard | a section with that title exists in the article | — | Not read. The fetch cut before that passage. Do not quote a nested-stream ratio from this page. |
The sentence that explains the rest. Objects live at whatever offset the writer chose, and the index maps each object number to that offset. Logical page order is a property of the page tree, not of the byte order.
Reading order, in pseudocode
open file as bytes
read first bytes # "%PDF-1.7" → declared version
scan forward from the END for "startxref"
offset = integer on the next line
read the index at that offset:
if it starts with "xref": # classic ASCII table
entries = rows of (offset, generation, n|f)
else: # xref stream, PDF 1.5+
decode using the /W widths
follow /Root → catalogue → /Pages → each /Page's /ContentsThe pointer does not say "start reading the file". A parser starts at the end, reads one table, then jumps. If the index is damaged, a recovery scan can look for every obj keyword, which is why truncated files often still open.
Paste the ASCII portion of a PDF you are allowed to read. Streams will look like noise. This reports structure. It does not decrypt a file or remove a permission.
press Parse structureTry it yourself
Take this PDF and do not extract its text. Report only structure: the
declared version in the header, how many indirect objects are present,
the highest object number, whether the file uses an ASCII cross-reference
table or a cross-reference stream, whether a /Prev entry exists, and the
byte offset named by startxref plus the first characters actually found at
that offset. If the two disagree, say so — that is the finding.What we could not confirm. Which offset width a specific file dedicates (2 bytes is an example for files under 64 KiB, not a rule), the internal layout of cross-reference stream entries beyond /W, and whether your file's generator sorted objects by page. ISO 32000 section numbers are not verified here. This page cites the article's summary, not the standard text.
Next
Blend mode math
Multiply is the product. Overlay branches on the base. Measured in the browser.
Read it →MethodStructure before behaviour
Step 2 is a fingerprint pass: layout first, logic later.
The 6-step loop →LayerNative targets
When the layer is machine code, the plan changes, and so do the tools.
REA vs Ghidra →