Luckily, I speak Leet.
– Amita Ramanujan, Numb3rs, CBS’s IRC Drama
There’s an episode of the CBS prime-time drama Numb3rs that plumbs the depths of Dr. Joel Fleischman’s1 knowledge of IRC. In one scene, Fleischman wonders, “What’s ‘leet’”?
“Leet” is writing that replaces letters with numbers, e.g.,
“Numb3rs,” where 3
stands in for e
.
In short, leet is like the heavy-metal “S” you drew in middle school: Sweeeeet.
/ \
/ | \
| | |
\ \
| | |
\ | /
\ /
ASCII art version of your misspent youth.
Following years of keen observation, I’ve noticed Git commit hashes are also letters and numbers.
Git commit hashes are, as Fleischman might say, prime targets for l33tification.
What can I spell with a git commit?
With hexidecimal we can spell any word containing the set of letters
{A, B, C, D, E, F}
—DEADBEEF
(a classic) or
ABBABABE
(for Mama Mia aficionados).
This is because hexidecimal is a base-16 numbering system—a single “digit” represents 16 numbers:
Base-10: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 16 15
Base-16: 0 1 2 3 4 5 6 7 8 9 A B C D E F
Leet expands our palette of words—using 0
,
1
, and 5
to represent O
,
I
, and S
, respectively.
I created a script that scours a few word lists for valid words and phrases.
With it, I found masterpieces like DADB0D
(dad bod),
BADA55
(bad ass), and 5ADBAB1E5
(sad
babies).
Manipulating commit hashes for fun and no profit
Git commit hashes are no mystery. A commit hash is the SHA-1 of a commit object.
And a commit object is the commit message with some metadata.
$ mkdir /tmp/BADA55-git && cd /tmp/BAD55-git
$ git init
Initialized empty Git repository in /tmp/BADA55-git/.git/
$ echo '# BADA55 git repo' > README.md && git add README.md && git commit -m 'Initial commit'
[main (root-commit) 68ec0dd] Initial commit
1 file changed, 1 insertion(+)
create mode 100644 README.md
$ git log --oneline
68ec0dd (HEAD -> main) Initial commit
Let’s confirm we can recreate the commit hash:
$ git cat-file -p 68ec0dd > commit-msg
$ sha1sum <(cat \
<(printf "commit ") \
<(wc -c < commit-msg | tr -d '\n') \
<(printf '%b' '\0') commit-msg)
68ec0dd6dead532f18082b72beeb73bd828ee8fc /dev/fd/63
Our repo’s first commit has the hash 68ec0dd
. My goal
is:
- Make
68ec0dd
beBADA55
. - Keep the commit message the same, visibly at least.
But I’ll need to change the commit to change the hash. To keep those
changes invisible in the output of git log
, I’ll add a
\t
and see what happens to the hash.
$ truncate -s -1 commit-msg # remove final newline
$ printf '\t\n' >> commit-msg # Add a tab
$ # Check the new SHA to see if it's BADA55
$ sha1sum <(cat \
<(printf "commit ") \
<(wc -c < commit-msg | tr -d '\n') \
<(printf '%b' '\0') commit-msg)
27b22ba5e1c837a34329891c15408208a944aa24 /dev/fd/63
Success! I changed the SHA-1. Now to do this over-and-over until we
get to BADA55
—mining for immature hashes.
Fortunately, user not-an-aardvark
created a tool for
that—lucky-commit
that manipulates a commit message, adding a combination of
\t
and [:space:]
characters until you hit a
desired SHA-1.
Written in rust, lucky-commit
computes all 256 unique
8-bit strings composed of only tabs and spaces. And then pads out
commits up to 48-bits with those strings, using worker threads to
quickly compute the SHA-12 of each commit.
It’s pretty fast:
$ time lucky_commit BADA555
real 0m0.091s
user 0m0.653s
sys 0m0.007s
$ git log --oneline
bada555 (HEAD -> main) Initial commit
$ xxd -c1 <(git cat-file -p 68ec0dd) | grep -cPo ': (20|09)'
12
$ xxd -c1 <(git cat-file -p HEAD) | grep -cPo ': (20|09)'
111
Now we have an more than an initial commit. We have a
BADA555
initial commit.
All that’s left to do is to make ALL our commits BADA55
by abusing git hooks.
$ cat > .git/hooks/post-commit && chmod +x .git/hooks/post-commit
#!/usr/bin/env bash
echo 'L337-ifying!'
lucky_commit BADA55
$ echo 'A repo that is very l33t.' >> README.md && git commit -a -m 'l33t'
L337-ifying!
[main 0e00cb2] l33t
1 file changed, 1 insertion(+)
$ git log --oneline
bada552 (HEAD -> main) l33t
bada555 Initial commit
And now I have a git repo almost as cool as the sweet “S” I drew in middle school.
This is a Northern Exposure spin off, right? I’ve only seen 1:48 of the show…↩︎
or SHA-256 for repos that have made the jump to a more secure hash function↩︎