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?

O’RLY Insulting SHA-1 Collisions. (Copyright 2024 DenITDao via orlybooks)

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:

  1. Make 68ec0dd be BADA55.
  2. 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 until we get to BADA55.

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.


  1. This is a Northern Exposure spin off, right? I’ve only seen 1:48 of the show…↩︎

  2. or SHA-256 for repos that have made the jump to a more secure hash function↩︎