The URL for level1 changed from 274877906944.html to map.html.

As I said previously it’s good practice to check the HTML title first.

The HTML title for level1 is What about making trans?

I’m also given a scratch book named map.jpg.

It’s a notebook that has K->M, O->Q, E->G written on it.

If you look carefully shifting 2 alphabets from K gets you M, O gets you Q, E gets you G.

K,L,M 
O,P,Q 
E,F,G 

There’s also a ciphertext.

ciphertext

Shifting 2 characters from our ciphertext g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj. will likely gives us the decipher.

Caesar_cipher is similar to the level1.

The only difference between Caesar cipher and level1 is that Caesar Cipher shifts 3 letters instead of 2.

ROT13 is another famous substitution cipher.

ROT13 shifts 13 lettters as it says in the name.

The dec function gets each character’s ASCII value and subtracts the ASCII value of character a to find the index of the alphabet and adds 2.

This gives us the offset (how far away it’s from the character a) and takes the remainder of it divided by 26.

You need to divide it by 26 because there are 26 letters in the alphabets.

97 is the ASCII value for 'a' so by adding the offset with 97 gives you the actual letter.

I initially wrote the dec function like this.

def dec(cipher):
    decrypt = ""
    for c in cipher:
        if c in letters:
            decrypt += chr((ord(c) - ord("a") + 2) % 26 + 97)
        else:
            decrypt += c
    return decrypt

Many people said string concatenation is generally bad practice in Python.

Especially if the string is long.

Reading this will give a detailed explanation.

According to the post string concatenation is fine if the string is short, but using ''.join() is the better choice so I went with that.

import string 
letters = string.ascii_lowercase


def dec(cipher):
    decrypt = []
    for c in cipher:
        if c in letters:
            decrypt.append(chr((ord(c) - ord("a") + 2) % 26 + 97))
        else:
            decrypt.append(c)
    return "".join(decrypt)

# print(dec("map")) => ocr

Here’s the decipher below.

i hope you didnt translate it by hand. thats what computers are for. doing it in by hand is inefficient and that's why this text is so long. using string.maketrans() is recommended. now apply on the url

The decipher tells me to use string.maketrans() but because I’ve never used string.maketrans() I decided not to.

Since the URL for level1 is http://www.pythonchallenge.com/pc/def/map.html I should do the 2 letter shift on the word map.

Passing map to the dec function gives you ocr.

Changing the URL from map to ocr gets you to level2.

P.S

You can also do the same process with shellscript.

echo "g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj." | tr a-z c-za-x

If the letter is between a-x you can 2 letter shift it to c-z, but if the letter is y or z it needs to go back to a or b so the letters are changed from all the letters except y,z which is a-x.

That’s the reason why you need the extra a-x after c-z.

{{ partial “author.html” . }}