Filed under #creative-coding#privacy

Introducing πrate — Pi Day 2020

40 min read

Updated

First published on my old blog, Tinkering the kernel, in 2020.

πrate is going to end privacy. All personal information that has ever existed or will ever exist, the PII credentials of every earthling, can be searched just by using this website which utilizes the almighty power of Pi.

This Pi Day, πrate is going to end privacy. All personal information that has ever existed or will ever exist, the PII credentials of every earthling, can be searched just by using this website which utilizes the almighty power of Pi. You can find your identity related information which makes you, you! Say, your name, date of birth, CVV number and even your unique super-duper secret pin!

Want to get freaked out? https://www.0x48piraj.com/projects/pirate

That's scary, πrate stores my personal information!?

We do not share your personal information, we just display the locations where your information is, just like a GPS Navigator. It means, all your personal information is still there, quietly sitting in π — it's never going away, you can't scrub the digits, can you? And not only yours. That's right! Every person you've ever met, or anyone else has met or will meet!

Data Protection Laws? All of it is in π! They were always there!

So I've looked up my personal information in π, what did I gain?

Nothing.

Why did you create this?

Think of a scenario where you forgot your credit card number, what will you do? You will have to get it revoked and stuff. But, what if you've written it down somewhere; you could use a piece of paper, a post-it note so to say, but your friendly neighbourhood Billy can look at it and cause trouble. Use πrate to create a unique seq and no-one will understand what the seq means and by merely using πrate again, you can retrieve your credit card number! Amazeballs, right?

Please do not actually do that T_T

Why we chunking?

Well, this is just an initial prototype, we all know that it can take a while to find a long sequence of digits in π, so for practical reasons, we should break the long strings up into smaller chunks that can be more readily found, but don't worry, there's always Moore's law!

What are the chances?

Almost 100% for everything that's chunked. And nearly 100% for things like your name and your date of birth.

Nerds, Dave Andersen explains the funky mathematics behind it far better than I ever could, over at his Pi-Search Page.

UPDATE:

Yeah, so, many folks were not able to grasp what the project is. They were actually generating random details, copying the generated random credit card numbers and plastering them over Netflix. Yes, the same folks pursuing an undergraduate computer science degree were doing this kind of stuff. I'm not talking about my grandma, come on!

I remember not starting with,

Shoutout to criminals with skimmers, you don't have to go to scary public ATMs and other POS systems to install your baby and steal credit card info because you can get the coronavirus. Thanks to πrate, you can steal everything just by sitting at home, sipping your latte.

I thought I did a good job in painting the picture, but I sure didn't. Here we go again,

This project is NOT a card generator which you can use to do transactions (oh my god I am actually saying this). It is like a search engine, aptly titled on GitHub, which searches your data in Pi. The random generation feature was added because, for obvious reasons, no user will want to enter their bank account details on a newly created, 'weird' looking website, thus the random generator function, just to demonstrate the capabilities.

πrate sails again

That was March 2020. Many folks pasted fake credit cards into Netflix, I wrote an update and moved on.

Backblaze started serving all 314 trillion digits of StorageReview's record run on 13 March 2026. That's the day before Pi Day. That's over 130 terabytes of π and anyone can download it for free. Half a decade after πrate, that was the nudge I needed to open the repo again.

The premise still holds up. πrate was unsettling on purpose. A birthday finder for π has been built more times than anyone can count and I wanted πrate to go further and reach your card number, your expiry date and your CVV. Cutting the card into four-digit chunks was how I got there with what I had. A billion digits of π had been sitting on an MIT server for over a decade but searching them live on a web page wasn't going to happen. And a whole 16-digit card number first turns up around digit ten quadrillion on average. That's about 32 times deeper than anyone has ever computed.

Looking back, I don't think the old site was broken. It was simply a reflection of where I was as a UX designer back then. It opened straight onto a credit card form …and I expected the premise to speak for itself. Some people got it, others didn't and it caused quite the kerfuffle.

Six years of building for the web have changed how I think about presentation. I've learned that an idea isn't just about what you're making.

Making something is one thing. Giving someone a reason to care about it, explore it …and feel something along the way is another.

The rebuild is, in many ways, a reflection of how far I've come. Looking at the two versions side by side, I can see just how far I've come and that's probably one of the things I enjoy most about revisiting old projects.

So πrate got rebuilt from the data up. Same premise, a gentler way in. A billion digits instead of sixty-two thousand, every date from 1900 to 2099 found ahead of time, a fall through π to the place your date first appears and a few experiments after the landing. The page itself never searches π or computes a single digit. It looks your date up in an answer key I built once ahead of time and asks Google's pi.delivery (100 trillion digits, computed in 2022) for the real digits around it.

Digit

26,958,942

Read aloud, one a second: 10 months

14 March 1988 first appears at digit 26,958,942.

Your privacy is a thing of the past

That was the 2020 site's headline and the whole site was one HTML file. It had 62,002 digits of π pasted straight into the markup and a form for a card number, an expiry date and a CVV. A script split the card number at its spaces, found each four-digit chunk with a plain string search and drew the results on a spiral of digits with D3. A “generate random” link filled the form because (as the update says) nobody types their real card into a weird new website. It picked from a list of well-known test card numbers (the ones payment processors publish for developers) and added a fake name from faker.js. So the folks pasting them into Netflix were pasting numbers built to never charge anything. Sorry, Netflix.

The 2020 home page. An orange blob, a big π and a ring of digits beside the privacy pitch
Pi Day 2020

I ran it again for this post. The test card 4539 1488 0343 6467 comes back at digits 3,188, 19,468, 7,328 and 41,537. The expiry lands at 9,550 and the CVV at 2,155. Still works. (Every one of those is off by one, by the way. The 2020 site searched the text “3.1415…” and the leading “3.” pushed every position one digit late.)

The 2020 result. A dark spiral of digits with each card chunk, the expiry and the CVV highlighted and their positions listed
Two hashtags, one corner. Still fighting.

Two things held it back.

Too few digits. 62,002 digits was what I could fit in one page and search on the spot. That's why the card got cut into four-digit chunks and for those it's plenty. Only 12 of the 10,000 possible chunks never show up in them. Lucky you if your PIN is 4057, 4325, 5917, 6194, 6362, 6716, 7059, 8335, 8448, 8737, 8978 or 9337; the 2020 πrate couldn't find you. Dates are a different story. Only 6% of all six-digit strings appear anywhere in those digits and a full eight-digit date is pretty much never there.

No reaction. The page told you where things were and stopped. It never asked what finding them felt like.

The intimacy of a coincidence

Here's the thing that kept bugging me. Your birthday in π is kinda lovely and your PIN in π is a little gross. Why is that?

A four-digit PIN and a four-digit day and month are the same kind of string with the same odds of turning up at the same depth. Nothing about the search changes between the two. Only how one feels about those numbers does.

So the question changed. What happens when a random sequence starts producing information that feels personally meaningful?

π is the perfect thing to ask that of. Nobody wrote it. It's the ratio of a circle's circumference to its diameter and every digit follows from that definition. There is no author, no intent and no audience. Nobody can rig it either. A random number generator can be seeded or faked; π can't. Anyone can check any digit I show them against an independent source. Whatever digit sits at position 26,958,942 sat there before the Earth formed and nothing about you could have influenced it. And everybody walks in with a feeling about π already.

That makes π a null source. If a stretch of it feels like it's talking to you then the talking is happening in you.

The design followed from that.

I showed the new version to friends and family before writing any of this. They got what it was trying to be and liked it a lot more than the 2020 one. The old one had a spooky vibe. It opened on a credit card generator. The new one starts with a date that matters to you and eases you in from something familiar. The pirate is still in there. He just doesn't show up first.

πrate wasn't a new idea in 2020 and it isn't one now. “Find yourself in an endless sequence” is older than most of the web and anyone who knows the space recognizes the search in about four seconds.

The granddaddy is Dave Andersen's Pi-Search Page. It has been answering “where is this string in π?” since around 1996, went to 100 million digits on Pi Day 2001 and to 200 million on Pi Day 2005. Go read the original; it's still the friendliest walk through the math on the internet.

Then there's Jonathan Basile's Library of Babel from 2015. It's Borges' library made real. Every possible page of 3,200 characters from a 29-character alphabet sits at a fixed address and you can search for any text and be handed its shelf. There's πfs, an April Fools' joke from 1 April 2012 and the filesystem that stores your files as positions in π and has about 7,500 stars for the bit. The issue tracker delivers the punchline without meaning to (I think). Someone asked in 2015 how to deal with the index getting bigger than the data and pointed out that “it can be proven that the size of index will be greater than the data.” Hold that thought.

And on Pi Day 2020 (the very same day πrate went public) Daniel Shiffman's Coding Train built a search over the first billion digits of π in p5.js and Node. So that Pi Day at least two people half a world apart were rummaging through π in public. Shiffman's would find any number you typed in a billion digits. Mine told you your credit card had been hiding in the first sixty-two thousand all along. Same magical constant, very different bedside manner.

WorkSinceWhat it answers
Pi-Search Pageabout 1996Where a string sits in the first 200 million digits
Library of Babel2015Where a page of text sits among every possible page
πfs2012Where your file sits in π, as a joke about storage
Peeking inside πPi Day 2020Where a string sits in the first billion digits
πrate, 2020Pi Day 2020Where your card number sits, in four pieces

Every one of them answers “where?” and stops. That's a fine thing to answer. It's also the boring half. Nobody built for the moment the answer comes back and you feel something about it.

How deep is a birthday?

Pretend for a moment that π's digits behave like a fair ten-sided die rolled forever. Nobody has proved that and I'll come back to it at the end. Almost every mathematician believes it and the numbers below are about to agree with them.

A specific string of n digits then matches at any given position with a chance of one in 10ⁿ. So on average it first turns up somewhere around digit 10ⁿ. That one fact runs the whole project.

What you search forDigitsTurns up nearTo find almost all
A four-digit chunk (the 2020 site)410,000about 60,000
A short date, DDMMYY61 millionabout 10 million
A full date, DDMMYYYY8100 millionabout 1 billion

The chance of finding a d-digit string somewhere in the first N digits works out to 1 − e^(−N / 10ᵈ). For a six-digit date in the 62,002 digits I had to work with, that's 1 − e^(−0.062) or roughly 6%.

Turns out I had gotten the maths right back in 2020 as well …just in time to calculate my own disappointment. A full birthday was never going to show up with those numbers and probably the reason I turned to jugaad.

A full date needs the first billion digits. So that's what the rebuild uses and it gave me the chance to check the formula against every date from 1900 to 2099.

For random digitsPredictedMeasured in π
Dates within the first 10 million digits9.5%9.6% day first, 9.4% month first
Dates within the first 100 million digits63.2% (1 − 1/e)63.2% day first, 63.3% month first
Median first appearance69.3 million69,122,409 day first, 68,834,562 month first
Dates missing from the first billionabout 54

Andersen's page says a birthday has a 63% chance of turning up in the first 100 million digits. Measured over every date from 1900 to 2099 it's 63.2%. π behaves exactly like randomness here. That's reassuring and also kinda eerie when you remember nothing about it is random at all.

1,00010,000100,0001 million10 million100 million1 billion0%25%50%75%100%within the first N digits of π62,002 digits,where 2020 stopped100 million: 63.2% predicted63.2% and 63.3% measured10 million: 9.5% predicted9.6% and 9.4% measured14 March 1988half of all datesby 69.1 milliona fair dieπ, day firstπ, month firstyou, 76% of dates deeper
π, pretending to be a die and nailing it

My example date for the rest of this post will be 14 March 1988, the first Pi Day ever celebrated. Written day first, the way most of the world writes it, that's 14031988 and it first appears at digit 26,958,942. That's earlier than 76% of all dates. Lucky.

Now look at the two numbers side by side.

where   26958942
what    14031988

Both are eight digits long. That's no accident. Something that first shows up around digit 10ⁿ needs about n digits to say where it is. So the address of anything in π is about as long as the thing itself and π doesn't compress, store or keep anything for you. That's πfs's index problem from a few paragraphs up. It sinks a filesystem and it's kinda the whole point of πrate. π is just sitting there, menacingly. The part where one stroke of random numbers suddenly means something? That's all you.

A billion digits in 47 seconds

A billion digits is a gigabyte of text. Searching it in a browser every time someone types a date isn't happening.

So the plan, obviously became to write the fastest ever searching algorithm!

Psst. I am lying. It was to find every date once ahead of time and ship only the answers.

Two sources do two jobs.

MIT's billion-digit file, for the index. MIT's Student Information Processing Board hosts pi-billion.txt, last modified on 13 March 2009 (a day early, guys). It's “3.” followed by one billion digits, exactly 1,000,000,002 bytes. The 2020 site already linked to that folder as a reference. Felt like coming home. The first download died at around 180 MB with curl exit code 56. The second one resumed from there with curl -C -. Something to do with Murphy's law probably.

Google's pi.delivery, for the digits around your date. Google computed 100 trillion digits in 2022 and serves them through a public API. Naturally, I went poking around before writing a single line of code.

curl "https://api.pi.delivery/v1/pi?start=0&numberOfDigits=12"
# {"content":"314159265358"}   start=0 is the "3", so start=p is decimal digit p

curl "https://api.pi.delivery/v1/pi?start=760&numberOfDigits=10"
# {"content":"3499999983"}     six 9s at digits 762 to 767, the Feynman point

curl "https://api.pi.delivery/v1/pi?start=0&numberOfDigits=1001"
# numberOfDigits is too big      at most 1,000 digits per request

It also answers with access-control-allow-origin: *. In plain words, any web page can call it straight from your browser. So πrate doesn't need a server of its own and there's nothing of mine sitting in the middle. Every digit you see around your date comes straight from Google's copy and you can open the same link and check it yourself.

There's a catch and it's a funny one. The date search happens on your device. But asking pi.delivery for the digits around your date tells Google the position and the position is the date. Years after πrate joked that π leaks your personal information, the latest version of it ended up leaking one date to one search giant. The address is the memory, remember?

The index builder is one Python file with NumPy. Every date becomes an eight-digit number like 14031988. All 146,098 of them (73,049 days, read day first and month first) get marked in a table of 100 million true-or-false slots, one per possible eight-digit number. Then an eight-digit window slides along π in chunks of 50 million digits. Every window in a chunk becomes a number in one vectorized step and gets checked against the table. Once a date turns up it gets crossed off the list and every chunk after that has a little less to look for.

def first_positions(digits, targets, width):
    mask = np.zeros(10 ** width, dtype=bool)
    mask[np.fromiter(targets, dtype=np.int64)] = True
    found = {}
    for s in range(0, len(digits) - width + 1, CHUNK):
        e = min(s + CHUNK, len(digits) - width + 1)
        seg = digits[s:e + width - 1].astype(np.int32)
        vals = np.zeros(e - s, dtype=np.int32)
        for k in range(width):                 # build every window's value at once
            vals = vals * 10 + seg[k:k + (e - s)]
        hits = np.flatnonzero(mask[vals])
        if hits.size:
            uniq, first = np.unique(vals[hits], return_index=True)
            for v, i in zip(uniq.tolist(), hits[first].tolist()):
                found[v] = s + i + 1           # 1-based decimal position
            mask[uniq] = False                 # stop looking for what we found
        if not mask.any():
            break
    return found
02695894214031988
72 pegs for 72 dates spread evenly over the 73,04914 March 1988 comes out at digit 26,958,942The real builder has a table of 100 million true-or-false slots with 117,298 of them marked and reads π 50 million digits at a time. Each peg comes out at its date's real first position from the demo's index. The last of these 72 goes at digit 466,789,476 and the tape runs on to a billion for the rest.

While the full file was still crawling down I cut off its first 300 million digits and ran the builder on those to catch bugs early. It finished in 28 seconds with about 3,700 dates missing per format. Probability said 3,640 for that length. Good sign.

The full billion took 47 seconds on my workstation. 2.6 seconds to load the file, 26.4 to scan for every date and the rest for landmarks and writing. The file checked out from 3.1415926535 to …5275045519. So the billionth digit of π is a 9 if anyone ever asks.

The 146,098 lookups collapse to 117,298 distinct strings because lots of dates read the same both ways (03041995 is 3 April day first and 4 March month first). π has 117,294 of them in its first billion digits. Four are missing.

DateSearchedShort form
18 September 194718091947180947 at 601,922
28 June 197128061971280671 at 1,483,019
26 October 206426102064261064 at 321,775
13 October 2022 (month first)10132022101322 at 3,105,944

Probability predicted about five. Sorry if one of these is your date. You're almost certainly in there. Just further down than this index goes.

The whole answer key ships as one 877 KB file. The page never actually searches anything.

And then there's the fun part of having every date in a box. The first date π ever writes (read day first) is 29 February 1960 at digit 713. A leap day. Of course it is. Month first it's 13 May 2000 at digit 596. π writes its own opening, 314159, again at digit 176,451. Einstein was born on Pi Day 1879 and 14031879 first appears at digit 74,434,701. Stephen Hawking died on Pi Day 2018 and 14032018 first appears at digit 184,676,216. And the deepest date of them all (read day first) sits somewhere past digit 970 million. I'm not telling you which one. Go find it in the demo. Fair warning, there are 73,049 dates to try.

These became the landmarks on the way down.

Falling with style

The first rule I wrote down was that every digit on screen is real. Each one is a digit of π at the exact position it's labeled with. Nothing decorative, nothing made up to look busy. That sounds obvious until you try to animate a fall through a billion digits and notice the cheap version is a column of random numbers scrolling fast. Nobody would notice. I would. And the whole piece is about π being the one thing nobody can fake. Faking it on screen would kinda defeat the point.

So the fall is built from real samples. The index builder also saves 48 real digits from 1,182 depths spaced evenly on a log scale between digit 1 and a billion. The rows move past at a steady pace. Because they're spaced on a log scale a steady pace through rows is an accelerating pace through π. The first hundred digits crawl. The hundred-millionth flies. Every row carries its true position and the fall takes longer the deeper your date is, from 4.5 seconds up to 12.5.

Color is depth. The page starts as pale fog at digit 1 and darkens toward blue-black at a billion. The background alone tells you how far down you are. The text switches from dark to light at the point where dark text stops being readable, around digit 10,000. There is exactly one warm color on the whole page. An amber lamp for your date, the depth marker and the main button. The amber is a little homage to the orange blob that sat on the 2020 site.

A gauge on the left counts the digit you're passing and how long reading π aloud to that point would take at one digit a second. The landmarks drift by on the right as you cross them. Six 9s in a row at digit 762. Digit 62,002, where the 2020 version of πrate ran out of digits. 314159 again at 176,451. The millionth digit at eleven and a half days of reading aloud.

The whole move owes a lot to Neal Agarwal's The Deep Sea. One long scroll from the surface down to the bottom of the Challenger Deep with every creature at its real depth.

I borrowed the feeling of exploring an immense, unfamiliar place. Mine just happened to be made of digits.

The fall at digit 289,206 with the depth gauge on the left, labeled rows of real digits in the middle and notes for the Feynman point, the end of the 2020 digits and 314159 on the right
Digit 289,206. Three days of reading aloud.

Type is two faces and they have separate jobs. Newsreader for every sentence, because the piece leans on Borges and should read like a book. Fragment Mono for digits only, because the digits are the subject and need fixed widths to line up. The date you type goes into the same mono face as π. It already looks like it belongs down there.

The fall ends at the landing. As the fall starts the page quietly asks pi.delivery for about 420 digits around your date so they're ready on arrival. Before drawing them it checks that the eight digits at the indexed position really are your date. If the index were ever wrong you'd see it right away. Your date just wouldn't be in its own row.

Your date glows in its row of real digits. One line under it works out when someone reading π aloud from that very day would have reached it. And the where and the what sit side by side. Both eight digits long.

The landing for 14 March 1988 at digit 26,958,942 with the neighborhood of digits, the reading-aloud sentence and the where and what comparison
Start reading π aloud on 14 March 1988 and you reach it on 20 January 1989.

The first version boxed the date with an outline and a halo. It looked like a coupon. Now it's light only. Like a lamp seen through deep water. The digits glow amber in four layered shadows from a one-pixel edge out to a wide faint haze, a soft pool of light sits behind them and the rest of the row dims to 70%. The lamp comes up once on landing over 1.6 seconds.

The neighborhood at twice the resolution with 14031988 glowing amber in its row
The lamp

v0.1 vs now

The first version ran end to end on day one …which was all well and dandy until a friend tried to use it without getting off their phone. Thanks man >:(

That sent me back into testing where I managed to uncover like six or seven problems of my own (some by simply turning on “reduced motion”). Here are the fun ones:

v0.1's descent with position labels like 101,038,483 running into the digits beside them, with a magnifier in the corner showing three of the labels losing their last digit
v0.1. The labels eat the digits.

The position labels were 11 characters long in a column 8 characters wide. 101,038,483 ran straight into the digits it was labelling. Fixing that widened the labels and pushed the ends of the digit rows off their column. That regression got caught later and the column grew again. Classic.

On a wide screen the right half of the opening page was empty. Now the first 2,400 digits of π fill it and fade downward like water. The first thing you see is the place you're about to fall into.

v0.1's opening screen with the right half empty
v0.1

The opening screen now, with the first digits of π filling the right side
Now

The four missing dates used to hit a dead end. Now the page tells you exactly how rare that is and offers the six-digit short form. That lands with its own neighborhood.

18 September 1947 isn't in the first billion digits of π with a button to find 180947 instead
One of four

With reduced motion switched on the fall is skipped. You land directly and get a list of every landmark you would have passed. The opening screen fits one window at every size I tried, ten of them from 1920 × 1080 down to a 360 × 640 phone that started out 201 pixels too tall. And the footer credits all of it in one line. “Every digit you see is real, courtesy of MIT's student computing club and Google's pi.delivery.”

A few things got rejected along the way. A near-black page with one bright accent. A pretty column of fake digits for the reason above. And a lot of copy.

Some ideas were easier to let go of than others. Over the months, a few grew into rather serious projects with prototypes and far too much time invested …before I finally pulled the plug.

The actual graveyard is considerably larger and probably explains why this post didn't quite make it out on Pi Day.

An oracle that knows nothing

The landing tells you where. The next experiment was supposed to tell you what. Take the eight digits right after your date and read them as a sentence. It was the part I was most excited about.

It's gone now. Here's why.

The idea came from film. In the 1910s and 20s Lev Kuleshov cut one neutral shot of an actor's face against a bowl of soup, a child in a coffin and a woman. Audiences praised the actor's hunger, grief and desire. Same face every time. Replications are shaky and it's film craft more than settled science. Still, the trick is real enough. Same digits, different framing, different feeling. And Bertram Forer showed in 1949 that people rate a generic “personal” sketch as eerily accurate (his 39 students gave the same astrology-book text 4.30 out of 5). An oracle reading that felt meant for you would be Forer at work.

So the plan was to make people feel it and then show them the trick.

Version one was hand-written codebooks. The eight digits split into four pairs from 00 to 99. Each pair picks one entry from a 100-entry list for its slot in a fixed sentence.

Theadjunspokenmonthly37nounblanketextension cord10verbforgivesis waiting for09endyour morning walkyour old router32.the eight digits right after your date, two at a timetenderon top, the same pairs in the mundane codebook underneath
Same four pairs, two codebooks

Three moods (tender, ominous and mundane) at four slots of 100 entries each is 1,200 hand-written entries. Verbs carry their own prepositions (“waits for”, “is homesick for”) so any verb can meet any ending and stay grammatical. The mundane list snuck in “your PIN” and “your mother's maiden name” as a nod to 2020.

You saw the tender or the ominous reading first (chosen at random) with each word sitting above the two digits that picked it. Then the page asked “Did this feel meant for you?” and only then revealed a dial to turn the same digits through the other codebooks. Feeling first, trick second.

The oracle reading "The unspoken blanket forgives your morning walk" with each word above its digit pair and the question below
Tender

The dial turned to mundane, reading "The monthly extension cord is waiting for your old router" over the same digit pairs 37 10 09 32
Mundane. Same four pairs.

It worked mechanically. It read like fridge-magnet poetry. Odd, never personal. “The tarnished telephone wants the dream you keep having” is a fun line and it isn't about anybody.

The ominous reading on a phone, "The tarnished telephone wants the dream you keep having"
Ominous, on a phone

Version two let a small language model write and π choose. A language model writes one token at a time. At each step:

  1. The model scores every possible next token.
  2. Anything with digits or symbols goes. So do words about death or violence, first-person words and any token that would copy four words in a row from the instructions.
  3. The most likely few stay (at most 8 of them covering 85% of the probability).
  4. The next three digits of π after your date pick one. 417 becomes the point 0.417 and the token whose slice of the probability covers that point wins.
  5. After enough words only an ending can be chosen and every line closes.

The model never sees your date or the digits. It only proposes; π decides. The same digits always produce the same line and a sentence eats about 43 digits. pi.delivery already supplies those around every date. On paper it kept the premise. Nobody chooses the words and anyone can check which digits chose each one.

I tested it on my workstation's CPU before touching the page. Same Transformers.js library and same model files the browser would use. Four small models, 16 real dates (four birthdays, four days someone was lost, four days someone was met, four days everything changed), three moods each. 48 lines per model, every one chosen by the real digits that follow its date.

The first attempts were… let's say educational.

  • Mentioning π in the instructions ruined everything. SmolLM2 started writing about π instead of the person. “You are a person, a soul, hidden in the depths of the infinite digits of pi.” Thanks, I hate it.
  • Tiny models copy example lines word for word. Real predictive guys.
  • Tiny models drift into the first person (“I still hear the sound of my grandmother's voice”) and run on forever. First person got blocked and endings got forced.
  • Gemma answered “Okay, here's the requested line” and at one point slipped into German.

The fix that finally worked came on the third try. Before any words π draws a concrete object. The first two digits pick one of 100 hand-written things (a ring, a seashell, a set of house keys) like a tarot card. That gave the model something to hold on to and LFM2.5-350M suddenly got good. Probably not a coincidence that it was the newest of the four, out only days earlier with its training stretched from 10 trillion to 28 trillion tokens.

Model“a ring”, uncanny“a seashell”, tender
LFM2.5-350MYou wore that ring every time you left home.You took the seashell and held it, its warm touch a silent reminder.
SmolLM2-360MYou're a little bit old, but a ring is your home.You lost someone, now you must call them.
Gemma 3 270MYou're a small private detail in the heart of the year, a secret you're keeping.You're not the only one who's lost.
Qwen2.5-0.5BYou lost a precious ring that holds your love and memories, and it's time to find.You lost a seashell, a seashell that spoke quietly, its sadness echoed in the calm of.

LFM2.5 was also the smallest browser download of the four (255 MB) and the fastest at 0.52 seconds a line. Qwen2.5-0.5B came in as a ceiling check at nearly twice the size (483 MB) and wrote like an insurance claim.

Here's one line taken apart. 5 February 2019, read day first, first appears at digit 300,990,060. The digits after it are 36 452 351 468 624 018 852 337 491 950 057. The first two (36) draw object number 36, a ring. Then each group of three picks a word.

DigitsChosenWhat the model offered
452YouYou (the line must open by addressing you)
351worekept 22%, wore 20%, held 20%, still 11%, carried 8%
468thatthat 52%, the 49%
624ringring 100%
018everyevery 61%, on 9%, a comma 7%, like 6%, at 5%
852timemorning 75%, time 11%, night 8%, day 7%
337youyou 100%
491leftleft 66%, walked 23%, laughed 5%, said 3%, sat 2%
950homea full stop 44%, for 38%, the 10%, home 8%
057.a full stop 100%
digitsπ picksthe model's options, 0 to 1452YouYou351worekeptworeheldstillothers468thatthatthe624ringring018everyeveryonatothers852timemorningtimeday337youyou491leftleftwalked950homestopforthehome057full stopstopYou wore that ring every time you left home.π overruled the model's favorite 3 times in 10: kept, morning, a full stop
Where π overruled the model

The model wanted “…every morning you left.” π picked “time” at 11% and “home” at 8%. So the line that lands, “You wore that ring every time you left home”, is π's and not the model's. I checked those digits and that date against the raw billion-digit file. It's a genuinely good line (trust me bro).

Annnd… I cut the whole thing anyway.

The lines weren't good enough. A rough read of the best model's 48 lines came out at about 20 strong, 18 fine and 10 weak. That's me being generous. Too many leaned on clichés like “a quiet ache” and “a silent reminder”. Lines like that fall apart the moment anyone really reads them. And whoever's reading just typed in a day that means the world to them. They read every word twice.

It worked against the idea. The whole premise is that π has no author and the meaning is yours. With a model in the loop most of the voice comes from the model's training data. In that traced line π really overruled the model on 3 of the 10 words. The rest was the model's taste with π nodding along. I had built an AI fortune teller with a π gimmick. I was fitting a language model into π instead of the other way round.

Too many crutches. Forced first words, a list of blocked words, rules for endings, a deck of objects, a 255 MB download, desktop-only WebGPU, a license to carry and the open question of whether a 16-bit browser GPU picks the same words as a 32-bit PC CPU near a boundary. Every crutch was a little admission that the idea didn't stand on its own.

So the oracle went. Language model and word lists alike.

What survived is the lesson. The lines that landed didn't land because of the sentence. They atleast sorta landed because of the concrete object π drew. A ring. A borrowed book. A set of house keys. A concrete thing next to a date that matters is what hits. Keep that in mind for the pirate.

One more thing died along the way. A voice that read the digits aloud as you fell (in the spirit of On Kawara's One Million Years readings and Roman Opałka's recorded counting). The browser's built-in speech read the real digits of whichever row was crossing the center (four at a time) and sped up with depth from 0.85 to about 2.4 so it could never keep up. On landing it stopped and read your date slowly.

It made the experience worse. Every text-to-speech voice sounds like every other one and a generic voice reading out your digits is the antithesis of what πrate is about. The whole project hangs on the moment feeling like yours. So the fall went back to silence and it's better for it.

I could have recorded my own voice, polished it up with what I've been picking up in FL Studio lately. I procrastinated and here we are (ᵕ—ᴗ—)

Further out

With the oracle gone the landing needed somewhere to go. Your date was easy to find because it's only eight digits long. So what about the things that are more you than a date?

The answer is a ladder in the spirit of Charles and Ray Eames's Powers of Ten. One step per screen and sinking toward black. Every rung is something more specific to you and every rung is buried deeper than the one before. You can type in your own name, a sentence and even pick a photo of your face. Only their length gets used. The photo is measured and never opened and nothing leaves the page.

RungTurns up nearRead aloud, one digit a second
Your date, 14031988 (8 digits)digit 26,958,94210 months
A first name, “Meruem” (about 8.5 digits in base 26)digit 310 million9 years and 9 months
A phone number (10 digits)digit 10 billionabout 320 years
The edge of the known, 314 trillion digits
A card number (16 digits)digit 1016about 317 million years
“I'll call you when I land.” (about 39 digits)digit 10391032 years
A 3 MB photo of your face (7,224,720 digits)digit 107,224,720107,224,712 years

Each rung also says how long its depth would be printed on one line in 12-point type, at 2.54 mm a digit. Your date is a 68 km strip of paper. A phone number gets you about 63% of the way round the Earth. A card number is 25 billion km. That's about 4.3 times the distance to Pluto. The sentence comes out at 3.9 billion times the width of the observable universe and the photo's address alone would stretch 18.4 km.

(yes, I borrowed the name from one of my favourite anime of all time)

The 🐐

Anyway, the rung I keep coming back to is the phone number. Ten decimal digits is about 33 bits and 2³³ is about 8.6 billion. That's enough to tell every person alive apart. Arvind Narayanan made 33 bits famous as the amount of information it takes to single someone out. It's a back-of-envelope bound. Back in 2011 Daniel Castro called it one of the most “misused and overused” facts in the privacy debate. His point was that unique isn't the same as identifiable. Take it as poetry and not law. Still. Somewhere around the ten-billionth digit π stops describing everyone and starts describing someone.

And then there's the amber line.

The ladder's phone number rung, the amber line marking the edge of the known at 314 trillion digits and the card number rung below it
Below this line, no one has ever seen a digit of π.

The most digits of π anyone has ever computed is 314 trillion. StorageReview finished that run on 18 November 2025 after four months on a single server. Everything below that line already exists and every digit is already settled but nobody's ever gotten around to looking. Funny enough, that's where most of what makes us us lives.

110¹⁰10²⁰10³⁰10⁴⁰the demostops at 10⁹…another 7,224,678 decadesthe edge of the known at 314 trillion digitsno one has ever seen a digit of π below this lineYour date, 14031988digit 26,958,942 and 10 months read aloudA first name, "Meruem"digit 310 million and 9 years and 9 months read aloudA phone numberdigit 10 billion and about 320 years read aloudA card numberdigit 10¹⁶ and about 317 million years read aloud"I'll call you when I land."digit 10³⁹ and 10³² years read aloudA 3 MB photo of your facedigit 107,224,720. The address alone would stretch 18.4 km
Powers of ten, downward

The pirate comes back

Somewhere in the middle of all this I looked back at the 2020 site and winced. The rebuild had become personal but it had lost its charm. πrate was a pirate joke and little me had found a sneaky way to drag a card number up from under that amber line. Cheating, sure. It was my cheat, though. I'd been so busy chasing the experience that I lost sight of what little me was going for.

But the 2020 trick still holds. A whole 16-digit card number almost certainly isn't in the first billion digits. Cut it into four 4-digit pieces and every piece turns up in the first 100,000. That's the whole idea behind the trick.

And the oracle debacle (hey it rhymes!) had just taught me that a date that matters hits differently when paired with something from everyday life. A card is about as familiar as it gets.

So the pirate is back as the first button on the landing.

Your date wasn't alone down there. On the way to digit 26,958,942 you fell past every four-digit PIN about 2,696 times with 1403 and 1988 lit in their digits
The turn

The turn. People love making PINs out of dates. The page shows yours. The day and month of 14 March 1988 (1403) first turns up at digit 6,053. The year (1988) turns up at 1,535. Every PIN has surfaced by digit 99,846 and the last one in is 6716. Remember the twelve PINs the 2020 site couldn't find? 6716 was one of them. Your date lies 270 times deeper than the deepest PIN.

Birthdays are also less anonymous than they feel. Latanya Sweeney showed in 2000 that 87% of people in the 1990 US census were likely unique on just their ZIP code, gender and date of birth. The date you typed in to feel something is one third of a fingerprint.

The card. Then the page makes up a card number on your device. It starts with 4 and passes the Luhn check so it looks like a card. It's random. A string that long first turns up around digit ten quadrillion. The record falls about 32 times short. Reading your way down there would take 316,880,878 years. In 2020 I wrote “don't worry, there's always Moore's law!” 314 trillion digits later it's still not close.

A made-up card number 4719 4305 9372 8952 for card holder Nobody with the line telling you never to type a real one into a page like this
Card holder: Nobody

That little warning is a later addition. Let's just say the 2020 version taught me not to leave quite so much to interpretation.

The cut. The four groups lift off the card and each one falls to where it first appears.

Each piece of the card at its first position in π, marked on a strip with the treasure map written out underneath
The treasure map

The joke in 2020 was the thesis all along. Turns out, it just needed a birthday in front of it …and better execution.

Two bits of plumbing. PINs need the first 100,000 or so digits and the fall's data only carries the first 2,400. So I computed π myself for this one, 120,000 digits in Node with the Chudnovsky series, binary splitting and BigInt in about 0.2 seconds. Only 120,000 digits, but still. They're checked against the SIPB file and digits 99,500 to 99,999 against pi.delivery. This part needs no network at all. And the page color follows the story. It rises to the PIN layer for the turn, sinks past the bottom of the map for the whole card and rises again for the cut.

Testing turned up some rather entertaining problems. The cut pieces initially fell straight into “CARD HOLDER / NOBODY” instead of lifting into place (they behave themselves now). The integer square root inside Chudnovsky started its Newton iteration below the actual root and promptly decided it had done enough. And halfway down the page, the amber button had pale text on an equally pale background. Invisible buttons always are a bold design choice. Dattebayo.

Somewhere between you and someone you love

The last experiment is the quietest. Add someone else's date. A parent's birthday, the day you met someone, the day someone left. You can say who it is. That word never leaves the page.

Take the demo's own example. Say a parent was born on 21 July 1962. That date first appears at digit 79,696,471. You're 52,737,529 digits apart. Yours surfaces first. Reading the distance between the two of you aloud would take 20 months. And between the two of you, 22,924 other dates surface for the first time, counted exactly from the index. Other people's birthdays, anniversaries and last days.

A parent's date, 21 July 1962, at digit 79,696,471, 52,737,529 digits from 14 March 1988 with a strip showing both dates and the density of every other date
Twenty months of reading aloud apart

The first version drew this on the descent's log scale. Two dates tens of millions of digits apart looked like they were touching and 73,049 faint ticks piled up into one solid block. Now it's a linear strip zoomed to the two dates and the crowd is drawn as a soft density curve. The curve shows something true that I didn't plan for. Dates surface thickly near the start of π and thin out the deeper you go. Everyone's day is down there somewhere, packed tightest near the surface.

52,737,529 digits apartdigit 020 million40 million60 million80 million100 millionthemyou

Their date (21 July 1962) first appears at digit 79,696,471. The 52,737,529 digits between you take 20 months to read aloud. 22,924 other dates surface for the first time in between.

Twenty months of reading aloud apart

Souvenirs from the abyss

A web page is forgotten in a day. A thing on your desk isn't. So the landing hands you something to take home, three ways.

Keep this date. One tap and the page makes you a little card of your spot in π. Your date glows among its real digits with how deep it sits and how long reading π aloud would take to reach it. The whole card takes the colors of the depth you fell to. It's made right there in your browser and saves straight to your device. Nothing gets uploaded.

The keepsake card for 14 March 1988, first appearing at digit 26,958,942 with the date glowing amber among seven rows of real digits
A little piece of π to take home

Print a receipt. This one's for anyone with a little thermal printer lying around (it's sized for an 80 mm roll). Out comes a narrow black-and-white slip with your date stamped in black among its digits, how long reading π aloud would take to get there and the exact minute it was printed. Right at the end it adds one more line. I like the “probably” a lot. Somebody at Google might have scrolled past digit 26,958,942 once. Doubt it.

A thermal receipt for 14 March 1988 at digit 26,958,942, with the date inverted in black among eight rows of digits
80 mm of π

And here's the fun bit. Add ?installation to the address and πrate turns into a kiosk. Every landing prints its own receipt and if nobody touches it for 90 seconds it quietly resets for the next person. Hook up a cheap thermal printer, start Chrome with --kiosk-printing so it skips the print dialog and you've got yourself an installation.

Film my reaction. The whole project is about how people react and sooner or later that needs actual faces on camera. Add ?film to the address and the opening screen grows a little tick box asking if it can film your reaction. Whatever it records stays on that computer.

The opening screen in film mode with the consent box ticked above the Find it in π button
Film mode

It only asks for the camera once you tick that box and the permission pop-up never cuts into the fall. A little red dot stays on screen from the moment you press the button until ten seconds after you land. The video saves to that computer without your date anywhere in the file name and goes nowhere else. Then the box unticks itself and the camera switches off. The next person has to say yes for themselves.

The film itself doesn't exist yet. Roman Opałka photographed his face next to his numbers every day for decades and that's the picture I have in my head. A face and a number in the same frame.

What I haven't measured yet

Here's the uncomfortable bit for a project that claims to be about reactions. I haven't measured any.

What I have is friends and family telling me the new one makes sense and feels better than the spooky 2020 one. That's encouraging. It's also an anecdote with a sample size of “people who love me”. The study πrate wants to be is pretty clear by now and it hasn't run.

CompareKeep the sameChangeWhat I'd expect
Whose dateThe digits and the positionYour date or a stranger'sYours feels far more meaningful at identical odds
What it isThe odds of being foundA birthday or a PIN of equal lengthSame odds, opposite feeling
When the numbers comeThe landingThe arithmetic before or after the feelingThe feeling first lands harder

The measures would be small on purpose. One tap per moment (meant for me, a little, nothing), one slider at the end from delighted to unsettled and with consent a few behaviors. How long people stay on the landing and whether they come back with a second date.

All of that needs somewhere to keep answers and πrate deliberately has no server. A shared store would hold only the condition and the answer, never a date or a PIN. The pirate section already explains why. Storing the position would be storing the date. Grief is welcome as an input and never prompted. And before collecting anything from strangers I'd want an ethics review on top of my own good intentions.

Then there's the gap I can't fix at all. “Everything is in π” assumes π is normal, meaning every string of digits turns up with its fair share of frequency forever. Almost every mathematician believes it. Nobody has proved it. My measurements fit it beautifully in the first billion digits (63.2% within 100 million, a median of 69.1 million against 69.3 predicted, four missing against five) and say absolutely nothing about digit 1016. The whole premise of this project rests on a belief. So do the treasure map and your face at digit 107,224,720.

Smaller gaps, while we're here. Dates only go from 1900 to 2099. The index is 877 KB and could be a sixth smaller in base 64. It could be half as big if it only loaded the order you picked. Or if the world could just agree on one way to write a date. Half of that file is there for America. The phone version works but the fall was clearly designed on a PC.

And if somebody ever proves π isn't normal I'll write an update. In caps. That's a promise.

The demo lives at works/pirate.

So I've looked up my date in π, what did I gain?

Nothing, technically. Same answer as 2020. π didn't learn a thing about you.

Except this time I think that's the point. The coincidence belongs to π and the significance belongs to you.