All our Data Science projects include bite-sized activities to test your knowledge and practice in an environment with constant feedback.
All our activities include solutions with explanations on how they work and why we chose them.
Shift the letters by 5 places to the right and store the result in the variable shift_5
. Do NOT modify the letters
variable.
shift_5
will look something like: [F, G, H, ...]
Shift the letters by 8 places to the left (that is, -8
places) and store the result in the variable shift_minus_8
. Do NOT modify the letters
variable.
shift_minus_8
will look something like: [S, T, U, ...]
Similar as before, but now we'll use 32
as shift. In this case, 32
will overflow and start counting all the way from the right.
The shift_letters
function receives two parameters:
letters
: containing an alphabet, andshift
: indicating the number of positions to shift (either right or left depending if the number is positive or negative)and returns a list of the letters
variable shifted.
So far, is pretty much the same as we did before. The only twist is that shift_letters
should work with ANY alphabet passed in letters
. For example, the Spanish alphabet contains the word Ñ
, and it should work on the same way:
# V note the Ñ
>>> spanish_letters = list("ABCDEFGHIJKLMNÑOPQRSTUVWXYZ")
>>> shift_letters(list("ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"), 9)
'JKLMNÑOPQRSTUVWXYZABCDEFGHI'
The function encrypt_simple
receives a word
and a shift
and returns the word
encrypted using the Caesar's cipher technique explored so far. Examples:
Note: we'll use only uppercase letters for now, and we won't introduce any characters outside of letters (no whitespaces, no special symbols or numbers).
>>> encrypt_simple("DATAWARS", 5)
'IFYFBFWX'
>>> encrypt_simple("DATAWARS", -14)
'PMFMIMDE'
Write the function decrypt_simple
that receives an encrypted word and the original shift used to encrypt it, and returns it decrypted counterpart. Examples:
>>> encrypt_simple("DATAWARS", 5)
'IFYFBFWX'
# Now we decrypt:
>>> decrypt_simple("IFYFBFWX", 5)
"DATAWARS"
>>> encrypt_simple("DATAWARS", -14)
'PMFMIMDE'
# Now we decrypt:
>>> decrypt_simple("PMFMIMDE", -14)
"DATAWARS"
Define the function encrypt_full
that will receive ANY text and the shift and encrypt it. The key is to encrypt only ASCII chars (that is, the characters defined in string.ascii_lowercase
and string.ascii_uppercase
). Anything else, should remain "intact" (unencrypted). Example:
>>> encrypt_full("DataWars is Great!", 9)
'MjcjFjab rb Panjc!'
# We can verify the encryption work by running:
>>> encrypt_simple("DATAWARS", 9)
'MJCJFJAB
>>> encrypt_simple("IS", 9)
'RB'
>>> encrypt_simple("GREAT", 9)
'PANJC
Similarly, the function decrypt_full
receives the encrypted text and the original shift, and returns the unencrypted version:
>>> decrypt_full('MjcjFjab rb Panjc!', 9)
'DataWars is Great!'
Now it's time to apply all our previous functions and some algorithmic brain power to break the cipher! This is the ultimate challenge for any criptographer.
Implement the function break_cipher
that breaks any encrypted message (encrypted_message
) by finding a known word (known_word
) in it.
For simplicity, you can assume the message is ONLY uppercase ascii characters and whitespaces. No symbols or numbers. Example:
We can start by encoding a message that we know the shift already:
>>> encrypt_full("MY FAVORITE WEBSITE IS DATAWARS SO MANY GREAT PROJECTS", 9)
'VH OJEXARCN FNKBRCN RB MJCJFJAB BX VJWH PANJC YAXSNLCB'
We know that the encrypted message has (somewhere) the word "DATAWARS"
, so the break_cipher
function should work as follows:
>>> break_cipher('VH OJEXARCN FNKBRCN RB MJCJFJAB BX VJWH PANJC YAXSNLCB', "DATAWARS")
'MY FAVORITE WEBSITE IS DATAWARS SO MANY GREAT PROJECTS'
Seems like magic! Somehow, our break_cipher
function was able to find the known word DATAWARS
in the encrypted message and break the code.