~$ skillshelf
← OverTheWire Bandit

Bandit 11 → 12: rot13, and what I got wrong about it

banditlinuxencodingshell

Another one-command level, like base64 two levels back. I got the password in under a minute and still walked away with the wrong idea about what the command does, which turned out to be the more useful half.

the goal

The password for the next level is stored in the file data.txt, where all lowercase (a-z) and uppercase (A-Z) letters have been rotated by 13 positions.

the approach

bandit11@bandit:~$ ls
data.txt
bandit11@bandit:~$ cat data.txt

Readable characters, but not words. The shape of a password is there and the letters are just wrong — which is what a substitution cipher looks like from outside.

I asked the AI for the command and used it:

bandit11@bandit:~$ cat data.txt | tr 'A-Za-z' 'N-ZA-Mn-za-m'

Password out, level done.

where I was wrong

I read that command as “swap uppercase to lowercase and lowercase to uppercase, then rotate by 13.” That’s not what it does, and it’s worth writing down because the mistake is built right into how the command looks.

tr takes two sets and maps the first onto the second, character by character. Line them up:

from:  A B C ... M N O ... Z    a b c ... m n o ... z
to:    N O P ... Z A B ... M    n o p ... z a b ... m

A becomes N. N becomes A. a becomes n. Case never changes. What misled me is the second set being written N-ZA-M — uppercase on the left of the lowercase block — so it looks like the cases are crossing over. They aren’t. It’s two separate 13-shifts written in one string: uppercase mapped onto uppercase, lowercase onto lowercase.

Worth checking rather than believing me:

$ echo "Hello" | tr 'A-Za-z' 'N-ZA-Mn-za-m'
Uryyb

HU, capital stays capital. If it swapped case you’d have got uRYYB.

the takeaway

rot13 is its own inverse. The alphabet is 26 letters and 13 is exactly half of it, so applying the shift twice brings you back to where you started — the same command encodes and decodes. That’s the whole reason 13 was chosen.

$ echo "Uryyb" | tr 'A-Za-z' 'N-ZA-Mn-za-m'
Hello

And the same point as base64 in level 10, from a different direction: this is not encryption. There’s no key. Anyone who recognises it can reverse it with one command. rot13 exists to stop you reading something by accident — a spoiler, a punchline — not to stop you reading it on purpose.

The reusable piece is tr itself: it maps one set of characters onto another, one to one. tr 'a-z' 'A-Z' really does uppercase a stream — which is the command I thought I was running.