How We Checked 12.3 Million Shuffles Against Each Other

September 12, 2026 ·  ShuffleArchive

ShuffleArchive's core promise is a strong one: every shuffle in the archive has been checked against every shuffle before it, exactly, not probabilistically. At 12,300,339 audited shuffles that means 75,649,163,607,291 pairs. This post is the engineering story of how that check works, why it is fast, and why we rebuilt the archive to make it honest.

The embarrassing part first

The archive's first engine, a Python process that ran from April to September 2025, recorded 12,300,339 shuffles and compared each new deck against exactly one thing: the shuffle immediately before it. Adjacent-only comparison. For its whole first year, the project's central claim, no two shuffles have ever matched, had only actually been verified between neighbors.

The 2026 migration fixed that. We re-encoded every era 1 deck and ran the first all-pairs audit in the project's history: 12,300,339 rows, zero parse errors, zero duplicates, zero hash collisions. Since then, the all-pairs guarantee holds for every new shuffle by construction, because of how the storage works.

A deck is 52 bytes

The original engine stored each deck as roughly a kilobyte of text, which is how 12.3 million shuffles grew into about 13 GB and killed the project on storage costs. But a deck order is a permutation of 52 known cards. It needs exactly 52 bytes: one byte per position, holding the card's index in new-deck order, where the index is suit × 13 + rank.

That encoding turned the archive's decks into about 640 MB, and it is permanent. Changing it would silently invalidate the identity of every deck ever recorded, so it is pinned by tests that are documented as unfixable: if they fail, the code is wrong, never the expected values.

Archive shuffle #12,630,168 drawn from its 52 bytes: position across, card identity down. The dashed diagonal is an unshuffled deck; one dot sits exactly on it, a card that landed back in its factory position.

The encoding is also why a deck can be drawn. The figure above is not an illustration of a shuffle. It is the shuffle, all 52 bytes of it, plotted.

A 64-bit hash makes the check instant

Comparing a new deck byte-by-byte against 12.3 million stored decks on every shuffle would be absurd. Instead, each deck's 52 bytes are hashed: the first 8 bytes of their SHA-256 digest, stored as a 64-bit integer behind a unique database index.

When a new shuffle arrives, the database tries to insert its hash. No conflict means no shuffle in the archive shares the hash, which means none shares the deck order, and the shuffle is admitted in one indexed operation. The check against 12.3 million predecessors costs the same as a check against ten.

The subtle question is what a hash conflict means, and this is where most systems would quietly cut corners. Two different decks can share a 64-bit hash. Across the audited era 1 archive's 75.6 trillion pairs, the expected number of such coincidences is about 4.1 × 10⁻⁶, roughly a 1 in 244,000 event, unlikely but not dismissible for a project making a forever claim.

On conflict: exact comparison, never probability

So a hash conflict never declares a match by itself. It triggers the full check: the stored deck is fetched and compared against the new one, all 52 bytes, exactly. Two outcomes are possible, and both are recorded permanently:

  • A true match. All 52 bytes agree. This is the event the project exists to find, and it has never happened.
  • A hash collision. The bytes differ. Two genuinely different decks happened to share a hash. The new shuffle is then re-admitted under a disambiguated hash derived from both the deck and the conflicting archive number, so the unique index stays intact and the archive keeps its one-row-per-shuffle integrity.

Either way, the claim survives scrutiny: no probabilistic structure ever stands between a shuffle and its verdict. Hashes make the answer fast. Bytes make it true.

Trust, but verify

None of this asks for your trust. The methodology page documents the shuffle algorithm, which is the Gilbert-Shannon-Reeds model running on a cryptographically secure random number generator, the encoding, the hashing, and the audit, in enough detail to reimplement. The audited claim is scoped precisely: 12,300,339 era 1 shuffles, all pairs, zero repeats. Everything since is checked by the same machinery the day it arrives.

And the day one of those checks comes back a true match, the database itself sends the alert. We would rather lose an email than lose the evidence, so the alert can fail without touching the record. That decision, like the others here, follows from one rule: for a claim this large, the math can be astonishing, but the bookkeeping has to be boring.