What the way you write gives away about you.
A tell, in poker, is the thing somebody does without knowing they are doing it, and it is the reason they lose.
[MATCHES] blog and notes: these two look like the same hand
blog 41,208 words, 16 pieces
notes 22,940 words, 9 pieces
1.71 times as far apart as each of them is from itself.
Under 1.8 is one hand, over 2.4 is two, and in between
nothing here can settle it.
[HABIT ] 9 habits are the same across both of them
sentence length 21.4 and 21.1 words
semicolons 13.3 and 14.5 per thousand words
comma before and 41.0 and 38.3 out of a hundred
starting with however 0.42 and 0.44 per hundred sentences
british spelling 39.0 and 39.8 out of a hundred
You can clean the metadata off everything. You cannot hear your own voice.
How long your sentences run, whether you write "do not" or "don't", how often you reach for a semicolon, where you put the word "however": none of it is chosen, all of it is stable over years, and together it identifies a person about as well as anything short of a name. It is what caught J.K. Rowling writing as Robert Galbraith, and it is what catches anybody keeping a second identity long after the timestamps and the exit nodes have been sorted out.
The field is a hundred and thirty years old and the tools are academic. The famous pair, JStylo and Anonymouth out of Drexel, are Java desktop applications and the real work on them stopped around 2013. JGAAP is another Java program with a wizard. stylo is excellent and it is an R package.
All of them answer "who wrote this?", which is the attacker's question. This one answers "how much does mine give me away, and which habit is doing it?", which is the same inversion as the rest of these tools.
Burrows's Delta, from 2002, and arithmetic all the way down. Take the six hundred words everybody uses constantly, work out how often each piece of writing uses each one, express that as how far from ordinary it is, and the distance between two pieces is the average of the differences. The words a piece is about are deliberately not the interesting part: they change when the subject changes, so leaning on them measures the topic and calls it a person.
The number that comes out is meaningless on its own, so it is divided by how far each source sits from itself, measured by splitting its own pieces in half at random, thirty three times over. The answer is "these two are 1.7 times as far apart as each of them is from itself on a different day", which is a thing somebody can weigh.
Every threshold in here was measured, and the numbers are in the source next to the constants they set.
Six books, three authors, two each, from Project Gutenberg with the boilerplate stripped, compared a pair at a time the way somebody actually uses this:
| same author | different authors | |
|---|---|---|
| Austen, Dickens, Doyle | 1.19, 1.66, 1.75 | 1.44, 1.93, 2.24, 2.45, 2.81, 3.16 |
The ranges overlap on one pair: A Tale of Two Cities against A Study in Scarlet, at 1.44. Two Victorian London novels by two men who read each other. Nothing I tried pulled them apart, and there were several attempts, including a noise correction that made it worse and is written up in the comments so nobody repeats it.
Which way to lean on the overlap is a judgement, and it goes toward saying linked. Somebody told they might be identifiable when they are not loses an afternoon changing habits. Somebody told they are safe when they are not loses the identity. So the bands catch all three real matches and accept one wrong one out of nine, and the wrong one lands in the hedged wording rather than the confident one.
Getting this far took three wrong methods, and each of them is a comment in the code: comparing pieces one at a time instead of averaging them first reported Austen and Dickens as the same person, and the very first run threw away an entire novel because the Gutenberg text of The Hound of the Baskervilles is indented six spaces and the code stripper took it for a code block.
The verdict is a number nobody can act on. Being told two things you wrote sit 1.7 apart is true and useless; being told you put a space before your colons, use three times as many semicolons as the other account, and never once wrote "don't" in eleven thousand words is a thing you can go and change.
Twenty three of them, each a ratio that survives being said out loud: sentence and word and paragraph length, the long dash, two hyphens for a dash, semicolons, colons, brackets, commas per sentence, exclamations, questions, trailing dots, contractions, starting a sentence with "and" or with "however", the serial comma, "which" against "that", Latin abbreviations, British against American spelling, curly quotes, a space before punctuation, two spaces after a full stop, and digits against spelt out numbers.
They are described and never judged. Calling a habit unusual needs a population to be unusual against, and the only way to ship one would be to ship somebody else's prose as the definition of normal. What it can say, and does, is which of them two pieces of writing do the same way.
tell posts/ essays/tell blog/ notes/ mail/tell essays/Folders or files. Markdown is understood: code, links, front matter and markup come out before anything is counted, because one fenced code block moves every number in the report at once. If most of a source turns out to have been code, it says so rather than quietly measuring the rest.
One source on its own gets described rather than judged.
Exit code is 1 when two sources look like the same hand, 3 when there is not enough to say, 0 when they look apart.
Windows marks anything that came from the internet, so the first run may bring up a blue "Windows protected your PC" box. Right click the zip, Properties, tick Unblock at the bottom, and then extract it.
It needs about ten thousand words per source and says so below that rather than guessing. Four pieces of two and a half thousand words is the least that lets a source be split in half and measured against itself, and without that there is no yardstick at all.
It is not evidence. One wrong answer in nine on the calibration corpus, on the hardest pair. Somebody writing deliberately differently, or about a very different subject, or edited into a house style, moves the number enough to matter.
It measures the words and nothing else. When things were posted, what they were about, who replied: any one of those can tie two accounts together on its own, and none of them is here.
Translated or heavily edited writing is somebody else's habits. What it measures then is the translator or the editor, which is a real finding of a different kind.
Nothing is written, nothing is sent anywhere, no other program is run, and
there is no model in it: nothing to download, nothing trained, nothing that
phones anywhere. Tests read the source and fail the build if a write call,
an import of net, an import of os/exec or anything that looks like a
model turns up.
That last one matters more here than in the others. What this is pointed at is the writing somebody is trying to keep to themselves.
Needs Go and nothing else. No dependencies at all.
go build -o tell .go test ./...The tests build two writers out of different function words and the same subject words, so a pass means the method separated them on their habits and not on what they were writing about.
MIT. Do what you like with it.