README du dépôt
whatsthisid
English · Français
You find an identifier in a log, a URL or a bug report. It is twenty-six characters of noise. What is it, when was it made, and what does it tell anyone who looks at it?
$ whatsthisid 01ARZ3NDEKTSV4RRFFQ69G5FAV
01ARZ3NDEKTSV4RRFFQ69G5FAV
ULID
Time first, then randomness — sortable as text, and the time is in plain sight.
created 2016-07-30 23:54:10 UTC · 10 years ago
timestamp 01ARZ3NDEK 48 bits, milliseconds
randomness TSV4RRFFQ69G5FAV 80 bits
gives away
· the moment it was created, to the millisecond
Try it in your browser — same code, nothing uploaded.
Use it
No install:
npx github:CedricPoint/whatsthisid 01ARZ3NDEKTSV4RRFFQ69G5FAV
Or keep it around:
git clone https://github.com/CedricPoint/whatsthisid
cd whatsthisid && npm link
It takes a list, and it reads a pipe:
whatsthisid 507f1f77bcf86cd799439011 175928847299117063
grep -o '[0-9a-f]\{24\}' app.log | sort -u | whatsthisid
--all | every format that fits, not just the most likely |
--json | the whole report, for scripts |
exit 0 | recognised |
exit 1 | not recognised |
What it reads
| Format | What comes out of it |
|---|---|
| UUID v1–v8 | version, variant, the clock for v1/v6/v7 — and the MAC address for v1 |
| ULID | the millisecond, in plain sight at the front |
| KSUID | the second, counted from 2014-05-13 |
| Snowflake | the millisecond, the worker and process, the counter — tried against the Discord, Twitter/X, Instagram and Mastodon epochs |
| MongoDB ObjectId | the second, the per-process bytes, the counter |
| JWT | the header and the payload, decoded; expiry, alg: none, a missing exp |
| API keys | Stripe, GitHub, Slack, AWS, Google, SendGrid, npm, DigitalOcean, GitLab — and whether that one is a secret |
| Unix timestamps | seconds or milliseconds |
| Hashes | MD5, SHA-1, SHA-256, SHA-512 by shape |
| Nano ID, base64 | the shape, and what the base64 decodes to |
Several formats share a shape — a 24-character hex string is an ObjectId and
also the right length for nothing else, while a 16-digit number could be a
snowflake from any of four services. It says which reading it prefers and
why, and --all shows the rest.
Why bother
An identifier is only opaque at a glance.
A version 1 UUID carries the MAC address of the machine that minted it. A snowflake carries the millisecond and the number of the server. A ULID, a KSUID and an ObjectId all carry the time. Put one of those in a public URL and all of that goes with it — which is sometimes fine, and sometimes the thing you did not mean to publish.
So the output has a gives away section. That is the part worth reading.
Nothing leaves your machine
There is no network code in this project — not in the CLI, not in the page.
npm run check:offline greps everything that ships for fetch,
XMLHttpRequest, sendBeacon, WebSocket, remote imports and hard-coded
URLs, and CI fails the build if one turns up. A test feeds the checker code
that does call out, to make sure it would notice.
That matters more than usual here: the natural thing to paste into a box like this is a token. If you paste a secret key, it says so, and tells you to rotate it.
As a library
import { analyse } from 'whatsthisid';
const report = analyse('175928847299117063');
report.best.name; // 'Snowflake'
report.best.at; // 1462015105796
report.best.leaks; // ['the moment it was created, to the millisecond', …]
report.matches; // every format that fits, best first
No dependencies, no build step. 49 tests, pinned to published vectors: the ULID from the specification, the snowflake in Discord's own documentation, the ObjectId from MongoDB's, the UUID example from RFC 4122.
Contributing
A format it does not know yet, with an example and a link to where the layout is written down, is the most useful kind of issue. See CONTRIBUTING.md.
MIT.