diff --git a/coded-correspondence/.ipynb_checkpoints/coded_correspondence-checkpoint.ipynb b/coded-correspondence/.ipynb_checkpoints/coded_correspondence-checkpoint.ipynb new file mode 100644 index 0000000..9901f4f --- /dev/null +++ b/coded-correspondence/.ipynb_checkpoints/coded_correspondence-checkpoint.ipynb @@ -0,0 +1,267 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Off-Platform Project: Coded Correspondence\n", + "\n", + "You and your pen pal, Vishal, have been exchanging letters for some time now. Recently, he has become interested in cryptography and the two of you have started sending encoded messages within your letters.\n", + "\n", + "In this project, you will use your Python skills to decipher the messages you receive and to encode your own responses! Put your programming skills to the test with these fun cryptography puzzles. Here is his most recent letter:\n", + "\n", + " Hey there! How have you been? I've been great! I just learned about this really cool type of cipher called a Caesar Cipher. Here's how it works: You take your message, something like \"hello\" and then you shift all of the letters by a certain offset. \n", + "\n", + " For example, if I chose an offset of 3 and a message of \"hello\", I would encode my message by shifting each letter 3 places to the left with respect to the alphabet. So \"h\" becomes \"e\", \"e\" becomes \"b\", \"l\" becomes \"i\", and \"o\" becomes \"l\". Then I have my encoded message, \"ebiil\"! Now I can send you my message and the offset and you can decode it by shifting each letter 3 places to the right. The best thing is that Julius Caesar himself used this cipher, that's why it's called the Caesar Cipher! Isn't that so cool! Okay, now I'm going to send you a longer encoded message that you have to decode yourself!\n", + " \n", + " xuo jxuhu! jxyi yi qd unqcfbu ev q squiqh syfxuh. muhu oek qrbu je tusetu yj? y xefu ie! iudt cu q cuiiqwu rqsa myjx jxu iqcu evviuj!\n", + " \n", + " This message has an offset of 10. Can you decode it?\n", + " \n", + "\n", + "#### Step 1: Decode Vishal's Message\n", + "In the cell below, use your Python skills to decode Vishal's message and print the result." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Stuck? Open this cell to view Hints: \n", + "\n", + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Step 2: Send Vishal a Coded Message\n", + "Great job! Now send Vishal back a message using the same offset. Your message can be anything you want! Remember, encoding happens in opposite direction of decoding." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Step 3: Make functions for decoding and coding \n", + "\n", + "Vishal sent over another reply, this time with two coded messages!\n", + " \n", + " You're getting the hang of this! Okay here are two more messages, the first one is coded just like before with an offset of ten, and it contains a hint for decoding the second message!\n", + "\n", + " First message:\n", + " \n", + " jxu evviuj veh jxu iusedt cuiiqwu yi vekhjuud.\n", + " \n", + " Second message:\n", + " \n", + " bqdradyuzs ygxfubxq omqemd oubtqde fa oapq kagd yqeemsqe ue qhqz yadq eqogdq!\n", + " \n", + "Decode both of these messages. \n", + "\n", + "If you haven't already, define two functions `caesar_decode(message, offset)` and `caesar_encode(message, offset)` that can be used to quickly decode and encode messages given any offset." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Step 4: Solving a Caesar Cipher without knowing the shift value\n", + "\n", + "Awesome work! While you were working to decode his last two messages, Vishal sent over another letter! He's really been bitten by the crypto-bug. Read it and see what interesting task he has lined up for you this time.\n", + "\n", + " Hello again friend! I knew you would love the Caesar Cipher, it's a cool, simple way to encrypt messages. Did you know that back in Caesar's time, it was considered a very secure way of communication and it took a lot of effort to crack if you were unaware of the value of the shift? That's all changed with computers! Now we can brute force these kinds of ciphers very quickly, as I'm sure you can imagine.\n", + " \n", + " To test your cryptography skills, this next coded message is going to be harder than the last couple to crack. It's still going to be coded with a Caesar Cipher but this time I'm not going to tell you the value of the shift. You'll have to brute force it yourself.\n", + " \n", + " Here's the coded message:\n", + " \n", + " vhfinmxkl atox kxgwxkxw tee hy maxlx hew vbiaxkl hulhexmx. px'ee atox mh kxteer lmxi ni hnk ztfx by px ptgm mh dxxi hnk fxlltzxl ltyx.\n", + " \n", + " Good luck!\n", + " \n", + "Decode Vishal's most recent message and see what it says!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Stuck? Open this cell to view Hints: \n", + "\n", + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Step 5: The Vigenère Cipher\n", + "\n", + "Great work! While you were working on the brute force cracking of the cipher, Vishal sent over another letter. That guy is a letter machine!\n", + "\n", + " Salutations! As you can see, technology has made brute forcing simple ciphers like the Caesar Cipher extremely easy, and us crypto-enthusiasts have had to get more creative and use more complicated ciphers. This next cipher I'm going to teach you is the Vigenère Cipher, invented by an Italian cryptologist named Giovan Battista Bellaso (cool name eh?) in the 16th century, but named after another cryptologist from the 16th century, Blaise de Vigenère.\n", + " \n", + " The Vigenère Cipher is a polyalphabetic substitution cipher, as opposed to the Caesar Cipher which was a monoalphabetic substitution cipher. What this means is that opposed to having a single shift that is applied to every letter, the Vigenère Cipher has a different shift for each individual letter. The value of the shift for each letter is determined by a given keyword.\n", + " \n", + " Consider the message:\n", + " \n", + " barry is the spy\n", + "\n", + " If we want to code this message, first we choose a keyword. For this example, we'll use the keyword\n", + " \n", + " dog\n", + " \n", + " Now we repeat the keyword over and over to generate a keyword phrase that is the same length as the message we want to code. So if we want to code the message \"barry is the spy\" our keyword phrase is \"dogdo gd ogd ogd\". Now we are ready to start coding our message. We shift each letter of our message by the place value of the corresponding letter in the keyword phrase, assuming that \"a\" has a place value of 0, \"b\" has a place value of 1, and so forth.\n", + "\n", + " message: b a r r y i s t h e s p y\n", + " \n", + " keyword phrase: d o g d o g d o g d o g d\n", + " \n", + " resulting place value: 24 12 11 14 10 2 15 5 1 1 4 9 21\n", + " \n", + " So we shift \"b\", which has an index of 1, by the index of \"d\", which is 3. This gives us an place value of 24, which is \"y\". Remember to loop back around when we reach either end of the alphabet! Then continue the trend: we shift \"a\" by the place value of \"o\", 14, and get \"m\", we shift \"r\" by the place value of \"g\", 15, and get \"l\", shift the next \"r\" by 4 places and get \"o\", and so forth. Once we complete all the shifts we end up with our coded message:\n", + " \n", + " ymlok cp fbb ejv\n", + " \n", + " As you can imagine, this is a lot harder to crack without knowing the keyword! So now comes the hard part. I'll give you a message and the keyword, and you'll see if you can figure out how to crack it! Ready? Okay here's my message:\n", + " \n", + " txm srom vkda gl lzlgzr qpdb? fepb ejac! ubr imn tapludwy mhfbz cza ruxzal wg zztcgcexxch!\n", + " \n", + " and the keyword to decode my message is \n", + " \n", + " friends\n", + " \n", + " Because that's what we are! Good luck friend!\n", + " \n", + "And there it is. Vishal has given you quite the assignment this time! Try to decode his message. It may be helpful to create a function that takes two parameters — the coded message and the keyword — then work towards a solution from there." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Stuck? Open this cell to view Hints: \n", + "\n", + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "#### Step 6: Send a message with the Vigenère Cipher\n", + "Great work decoding the message. For your final task, write a function that can encode a message using a given keyword and write out a message to send to Vishal!\n", + "\n", + "*As a bonus, try calling your decoder function on the result of your encryption function. You should get the original message back!*" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Conclusion\n", + "Over the course of this project you've learned about two different cipher methods and have used your Python skills to code and decode messages. There are all types of other facinating ciphers out there to explore, and Python is the perfect language to implement them with, so go exploring! " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/coded-correspondence/coded_correspondence.ipynb b/coded-correspondence/coded_correspondence.ipynb new file mode 100644 index 0000000..2fbb91f --- /dev/null +++ b/coded-correspondence/coded_correspondence.ipynb @@ -0,0 +1,491 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Off-Platform Project: Coded Correspondence\n", + "\n", + "You and your pen pal, Vishal, have been exchanging letters for some time now. Recently, he has become interested in cryptography and the two of you have started sending encoded messages within your letters.\n", + "\n", + "In this project, you will use your Python skills to decipher the messages you receive and to encode your own responses! Put your programming skills to the test with these fun cryptography puzzles. Here is his most recent letter:\n", + "\n", + " Hey there! How have you been? I've been great! I just learned about this really cool type of cipher called a Caesar Cipher. Here's how it works: You take your message, something like \"hello\" and then you shift all of the letters by a certain offset. \n", + "\n", + " For example, if I chose an offset of 3 and a message of \"hello\", I would encode my message by shifting each letter 3 places to the left with respect to the alphabet. So \"h\" becomes \"e\", \"e\" becomes \"b\", \"l\" becomes \"i\", and \"o\" becomes \"l\". Then I have my encoded message, \"ebiil\"! Now I can send you my message and the offset and you can decode it by shifting each letter 3 places to the right. The best thing is that Julius Caesar himself used this cipher, that's why it's called the Caesar Cipher! Isn't that so cool! Okay, now I'm going to send you a longer encoded message that you have to decode yourself!\n", + " \n", + " xuo jxuhu! jxyi yi qd unqcfbu ev q squiqh syfxuh. muhu oek qrbu je tusetu yj? y xefu ie! iudt cu q cuiiqwu rqsa myjx jxu iqcu evviuj!\n", + " \n", + " This message has an offset of 10. Can you decode it?\n", + " \n", + "\n", + "#### Step 1: Decode Vishal's Message\n", + "In the cell below, use your Python skills to decode Vishal's message and print the result." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Stuck? Open this cell to view Hints: \n", + "\n", + "" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "hey there! this is an example of a caesar cipher. were you able to decode it? i hope so! send me a message back with the same offset!\n" + ] + } + ], + "source": [ + "alphabet = \"abcdefghijklmnopqrstuvwxyz\"\n", + "\n", + "message = \"xuo jxuhu! jxyi yi qd unqcfbu ev q squiqh syfxuh. muhu oek qrbu je tusetu yj? y xefu ie! iudt cu q cuiiqwu rqsa myjx jxu iqcu evviuj!\"\n", + "\n", + "translated_message = \"\"\n", + "\n", + "for character in message:\n", + " if character in alphabet:\n", + " character_value = alphabet.find(character)\n", + " translated_message += alphabet[(character_value + 10) % 26]\n", + " else:\n", + " translated_message += character\n", + "\n", + "print(translated_message)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Step 2: Send Vishal a Coded Message\n", + "Great job! Now send Vishal back a message using the same offset. Your message can be anything you want! Remember, encoding happens in opposite direction of decoding." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "xuo lyixqb! Txyi yi q ikfuh seeb syfxuh, jxqdai veh ixemydw cu! Wxqj ubiu oek wej?\n" + ] + } + ], + "source": [ + "message_for_v = \"hey vishal! This is a super cool cipher, thanks for showing me! What else you got?\"\n", + "\n", + "translated_message_for_v = \"\"\n", + "\n", + "for character in message_for_v:\n", + " if character in alphabet:\n", + " character_value = alphabet.find(character)\n", + " translated_message_for_v += alphabet[(character_value - 10) % 26]\n", + " else:\n", + " translated_message_for_v += character\n", + " \n", + "print(translated_message_for_v)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Step 3: Make functions for decoding and coding \n", + "\n", + "Vishal sent over another reply, this time with two coded messages!\n", + " \n", + " You're getting the hang of this! Okay here are two more messages, the first one is coded just like before with an offset of ten, and it contains a hint for decoding the second message!\n", + "\n", + " First message:\n", + " \n", + " jxu evviuj veh jxu iusedt cuiiqwu yi vekhjuud.\n", + " \n", + " Second message:\n", + " \n", + " bqdradyuzs ygxfubxq omqemd oubtqde fa oapq kagd yqeemsqe ue qhqz yadq eqogdq!\n", + " \n", + "Decode both of these messages. \n", + "\n", + "If you haven't already, define two functions `caesar_decode(message, offset)` and `caesar_encode(message, offset)` that can be used to quickly decode and encode messages given any offset." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "def caesar_decode(message, offset):\n", + " decoded_message = \"\"\n", + " for character in message:\n", + " if character in alphabet:\n", + " character_value = alphabet.find(character)\n", + " decoded_message += alphabet[(character_value + offset) % 26]\n", + " else:\n", + " decoded_message += character\n", + " return decoded_message\n", + "\n", + "def caesar_encode(message, offset):\n", + " encoded_message = \"\"\n", + " for character in message:\n", + " if character in alphabet:\n", + " character_value = alphabet.find(character)\n", + " encoded_message += alphabet[(character_value - offset) % 26]\n", + " else:\n", + " encoded_message += character\n", + " return encoded_message\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "the offset for the second message is fourteen.\n", + "performing multiple caesar ciphers to code your messages is even more secure!\n" + ] + } + ], + "source": [ + "message_one = \"jxu evviuj veh jxu iusedt cuiiqwu yi vekhjuud.\"\n", + "print(caesar_decode(message_one, 10))\n", + "\n", + "message_two = \"bqdradyuzs ygxfubxq omqemd oubtqde fa oapq kagd yqeemsqe ue qhqz yadq eqogdq!\"\n", + "print(caesar_decode(message_two, 14))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Step 4: Solving a Caesar Cipher without knowing the shift value\n", + "\n", + "Awesome work! While you were working to decode his last two messages, Vishal sent over another letter! He's really been bitten by the crypto-bug. Read it and see what interesting task he has lined up for you this time.\n", + "\n", + " Hello again friend! I knew you would love the Caesar Cipher, it's a cool, simple way to encrypt messages. Did you know that back in Caesar's time, it was considered a very secure way of communication and it took a lot of effort to crack if you were unaware of the value of the shift? That's all changed with computers! Now we can brute force these kinds of ciphers very quickly, as I'm sure you can imagine.\n", + " \n", + " To test your cryptography skills, this next coded message is going to be harder than the last couple to crack. It's still going to be coded with a Caesar Cipher but this time I'm not going to tell you the value of the shift. You'll have to brute force it yourself.\n", + " \n", + " Here's the coded message:\n", + " \n", + " vhfinmxkl atox kxgwxkxw tee hy maxlx hew vbiaxkl hulhexmx. px'ee atox mh kxteer lmxi ni hnk ztfx by px ptgm mh dxxi hnk fxlltzxl ltyx.\n", + " \n", + " Good luck!\n", + " \n", + "Decode Vishal's most recent message and see what it says!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Stuck? Open this cell to view Hints: \n", + "\n", + "" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Offset: 1\n", + "\t wigjonylm bupy lyhxylyx uff iz nbymy ifx wcjbylm um ivmifyny. qy'ff bupy ni lyuffs mnyj oj iol augy cz qy quhn ni eyyj iol gymmuaym muzy.\n", + "Offset: 2\n", + "\t xjhkpozmn cvqz mziyzmzy vgg ja ocznz jgy xdkczmn vn jwnjgzoz. rz'gg cvqz oj mzvggt nozk pk jpm bvhz da rz rvio oj fzzk jpm hznnvbzn nvaz.\n", + "Offset: 3\n", + "\t ykilqpano dwra najzanaz whh kb pdaoa khz yeldano wo kxokhapa. sa'hh dwra pk nawhhu opal ql kqn cwia eb sa swjp pk gaal kqn iaoowcao owba.\n", + "Offset: 4\n", + "\t zljmrqbop exsb obkaboba xii lc qebpb lia zfmebop xp lyplibqb. tb'ii exsb ql obxiiv pqbm rm lro dxjb fc tb txkq ql hbbm lro jbppxdbp pxcb.\n", + "Offset: 5\n", + "\t amknsrcpq fytc pclbcpcb yjj md rfcqc mjb agnfcpq yq mzqmjcrc. uc'jj fytc rm pcyjjw qrcn sn msp eykc gd uc uylr rm iccn msp kcqqyecq qydc.\n", + "Offset: 6\n", + "\t bnlotsdqr gzud qdmcdqdc zkk ne sgdrd nkc bhogdqr zr narnkdsd. vd'kk gzud sn qdzkkx rsdo to ntq fzld he vd vzms sn jddo ntq ldrrzfdr rzed.\n", + "Offset: 7\n", + "\t computers have rendered all of these old ciphers as obsolete. we'll have to really step up our game if we want to keep our messages safe.\n", + "Offset: 8\n", + "\t dpnqvufst ibwf sfoefsfe bmm pg uiftf pme djqifst bt pctpmfuf. xf'mm ibwf up sfbmmz tufq vq pvs hbnf jg xf xbou up lffq pvs nfttbhft tbgf.\n", + "Offset: 9\n", + "\t eqorwvgtu jcxg tgpfgtgf cnn qh vjgug qnf ekrjgtu cu qduqngvg. yg'nn jcxg vq tgcnna uvgr wr qwt icog kh yg ycpv vq mggr qwt oguucigu uchg.\n", + "Offset: 10\n", + "\t frpsxwhuv kdyh uhqghuhg doo ri wkhvh rog flskhuv dv revrohwh. zh'oo kdyh wr uhdoob vwhs xs rxu jdph li zh zdqw wr nhhs rxu phvvdjhv vdih.\n", + "Offset: 11\n", + "\t gsqtyxivw lezi virhivih epp sj xliwi sph gmtlivw ew sfwspixi. ai'pp lezi xs vieppc wxit yt syv keqi mj ai aerx xs oiit syv qiwwekiw weji.\n", + "Offset: 12\n", + "\t htruzyjwx mfaj wjsijwji fqq tk ymjxj tqi hnumjwx fx tgxtqjyj. bj'qq mfaj yt wjfqqd xyju zu tzw lfrj nk bj bfsy yt pjju tzw rjxxfljx xfkj.\n", + "Offset: 13\n", + "\t iusvazkxy ngbk xktjkxkj grr ul znkyk urj iovnkxy gy uhyurkzk. ck'rr ngbk zu xkgrre yzkv av uax mgsk ol ck cgtz zu qkkv uax skyygmky yglk.\n", + "Offset: 14\n", + "\t jvtwbalyz ohcl yluklylk hss vm aolzl vsk jpwolyz hz vizvslal. dl'ss ohcl av ylhssf zalw bw vby nhtl pm dl dhua av rllw vby tlzzhnlz zhml.\n", + "Offset: 15\n", + "\t kwuxcbmza pidm zmvlmzml itt wn bpmam wtl kqxpmza ia wjawtmbm. em'tt pidm bw zmittg abmx cx wcz oium qn em eivb bw smmx wcz umaaioma ainm.\n", + "Offset: 16\n", + "\t lxvydcnab qjen anwmnanm juu xo cqnbn xum lryqnab jb xkbxuncn. fn'uu qjen cx anjuuh bcny dy xda pjvn ro fn fjwc cx tnny xda vnbbjpnb bjon.\n", + "Offset: 17\n", + "\t mywzedobc rkfo boxnobon kvv yp droco yvn mszrobc kc ylcyvodo. go'vv rkfo dy bokvvi cdoz ez yeb qkwo sp go gkxd dy uooz yeb wocckqoc ckpo.\n", + "Offset: 18\n", + "\t nzxafepcd slgp cpyopcpo lww zq espdp zwo ntaspcd ld zmdzwpep. hp'ww slgp ez cplwwj depa fa zfc rlxp tq hp hlye ez vppa zfc xpddlrpd dlqp.\n", + "Offset: 19\n", + "\t oaybgfqde tmhq dqzpqdqp mxx ar ftqeq axp oubtqde me aneaxqfq. iq'xx tmhq fa dqmxxk efqb gb agd smyq ur iq imzf fa wqqb agd yqeemsqe emrq.\n", + "Offset: 20\n", + "\t pbzchgref unir eraqrerq nyy bs gurfr byq pvcuref nf bofbyrgr. jr'yy unir gb ernyyl fgrc hc bhe tnzr vs jr jnag gb xrrc bhe zrffntrf fnsr.\n", + "Offset: 21\n", + "\t qcadihsfg vojs fsbrsfsr ozz ct hvsgs czr qwdvsfg og cpgczshs. ks'zz vojs hc fsozzm ghsd id cif uoas wt ks kobh hc yssd cif asggousg gots.\n", + "Offset: 22\n", + "\t rdbejitgh wpkt gtcstgts paa du iwtht das rxewtgh ph dqhdatit. lt'aa wpkt id gtpaan hite je djg vpbt xu lt lpci id ztte djg bthhpvth hput.\n", + "Offset: 23\n", + "\t secfkjuhi xqlu hudtuhut qbb ev jxuiu ebt syfxuhi qi eriebuju. mu'bb xqlu je huqbbo ijuf kf ekh wqcu yv mu mqdj je auuf ekh cuiiqwui iqvu.\n", + "Offset: 24\n", + "\t tfdglkvij yrmv iveuvivu rcc fw kyvjv fcu tzgyvij rj fsjfcvkv. nv'cc yrmv kf ivrccp jkvg lg fli xrdv zw nv nrek kf bvvg fli dvjjrxvj jrwv.\n", + "Offset: 25\n", + "\t ugehmlwjk zsnw jwfvwjwv sdd gx lzwkw gdv uahzwjk sk gtkgdwlw. ow'dd zsnw lg jwsddq klwh mh gmj ysew ax ow osfl lg cwwh gmj ewkksywk ksxw.\n" + ] + } + ], + "source": [ + "brute_force_message = \"vhfinmxkl atox kxgwxkxw tee hy maxlx hew vbiaxkl tl hulhexmx. px'ee atox mh kxteer lmxi ni hnk ztfx by px ptgm mh dxxi hnk fxlltzxl ltyx.\"\n", + "\n", + "for i in range(1, 26):\n", + " print(\"Offset: {}\".format(i))\n", + " print(\"\\t {}\".format(caesar_decode(brute_force_message, i)))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Step 5: The Vigenère Cipher\n", + "\n", + "Great work! While you were working on the brute force cracking of the cipher, Vishal sent over another letter. That guy is a letter machine!\n", + "\n", + " Salutations! As you can see, technology has made brute forcing simple ciphers like the Caesar Cipher extremely easy, and us crypto-enthusiasts have had to get more creative and use more complicated ciphers. This next cipher I'm going to teach you is the Vigenère Cipher, invented by an Italian cryptologist named Giovan Battista Bellaso (cool name eh?) in the 16th century, but named after another cryptologist from the 16th century, Blaise de Vigenère.\n", + " \n", + " The Vigenère Cipher is a polyalphabetic substitution cipher, as opposed to the Caesar Cipher which was a monoalphabetic substitution cipher. What this means is that opposed to having a single shift that is applied to every letter, the Vigenère Cipher has a different shift for each individual letter. The value of the shift for each letter is determined by a given keyword.\n", + " \n", + " Consider the message:\n", + " \n", + " barry is the spy\n", + "\n", + " If we want to code this message, first we choose a keyword. For this example, we'll use the keyword\n", + " \n", + " dog\n", + " \n", + " Now we repeat the keyword over and over to generate a keyword phrase that is the same length as the message we want to code. So if we want to code the message \"barry is the spy\" our keyword phrase is \"dogdo gd ogd ogd\". Now we are ready to start coding our message. We shift each letter of our message by the place value of the corresponding letter in the keyword phrase, assuming that \"a\" has a place value of 0, \"b\" has a place value of 1, and so forth.\n", + "\n", + " message: b a r r y i s t h e s p y\n", + " \n", + " keyword phrase: d o g d o g d o g d o g d\n", + " \n", + " resulting place value: 24 12 11 14 10 2 15 5 1 1 4 9 21\n", + " \n", + " So we shift \"b\", which has an index of 1, by the index of \"d\", which is 3. This gives us an place value of 24, which is \"y\". Remember to loop back around when we reach either end of the alphabet! Then continue the trend: we shift \"a\" by the place value of \"o\", 14, and get \"m\", we shift \"r\" by the place value of \"g\", 15, and get \"l\", shift the next \"r\" by 4 places and get \"o\", and so forth. Once we complete all the shifts we end up with our coded message:\n", + " \n", + " ymlok cp fbb ejv\n", + " \n", + " As you can imagine, this is a lot harder to crack without knowing the keyword! So now comes the hard part. I'll give you a message and the keyword, and you'll see if you can figure out how to crack it! Ready? Okay here's my message:\n", + " \n", + " txm srom vkda gl lzlgzr qpdb? fepb ejac! ubr imn tapludwy mhfbz cza ruxzal wg zztcgcexxch!\n", + " \n", + " and the keyword to decode my message is \n", + " \n", + " friends\n", + " \n", + " Because that's what we are! Good luck friend!\n", + " \n", + "And there it is. Vishal has given you quite the assignment this time! Try to decode his message. It may be helpful to create a function that takes two parameters — the coded message and the keyword — then work towards a solution from there." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Stuck? Open this cell to view Hints: \n", + "\n", + "" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "you were able to decode this? nice work! you are becoming quite the expert at crytography!\n" + ] + } + ], + "source": [ + "def vigenere_decode(message, keyword):\n", + " keyword_phrase = \"\"\n", + " keyword_index = 0\n", + "\n", + " #Generate keyword_phrase\n", + " for character in message:\n", + " if keyword_index >= len(keyword):\n", + " keyword_index = 0\n", + " if character in alphabet:\n", + " keyword_phrase += keyword[keyword_index]\n", + " keyword_index += 1\n", + " else:\n", + " keyword_phrase += character\n", + "\n", + " decoded_message = \"\"\n", + " #Decoding\n", + " for i in range(len(message)):\n", + " if message[i] in alphabet:\n", + " old_character_index = alphabet.find(message[i])\n", + " offset_index = alphabet.find(keyword_phrase[i])\n", + " new_character = alphabet[(old_character_index + offset_index) % 26]\n", + " decoded_message += new_character\n", + " else:\n", + " decoded_message += message[i]\n", + " \n", + " return decoded_message\n", + "\n", + "vigenere_message = \"txm srom vkda gl lzlgzr qpdb? fepb ejac! ubr imn tapludwy mhfbz cza ruxzal wg zztcgcexxch!\"\n", + "vigenere_keyword = \"friends\"\n", + "\n", + "print(vigenere_decode(vigenere_message, vigenere_keyword))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } + }, + "source": [ + "#### Step 6: Send a message with the Vigenère Cipher\n", + "Great work decoding the message. For your final task, write a function that can encode a message using a given keyword and write out a message to send to Vishal!\n", + "\n", + "*As a bonus, try calling your decoder function on the result of your encryption function. You should get the original message back!*" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "sdiuco nnn blsyphjo tw wtk pplka knkt jalpdna! fgq zdwtsq wzd ppl taas!\n", + "thanks for teaching me all these cool ciphers! you really are the best!\n" + ] + } + ], + "source": [ + "def vigenere_encode(message, keyword):\n", + " keyword_phrase = \"\"\n", + " keyword_index = 0\n", + " for character in message:\n", + " if keyword_index >= len(keyword):\n", + " keyword_index = 0\n", + " if character in alphabet:\n", + " keyword_phrase += keyword[keyword_index]\n", + " keyword_index += 1\n", + " else:\n", + " keyword_phrase += character\n", + "\n", + " encoded_message = \"\"\n", + " for i in range(len(message)):\n", + " if message[i] in alphabet:\n", + " old_character_index = alphabet.find(message[i])\n", + " offset_index = alphabet.find(keyword_phrase[i])\n", + " new_character = alphabet[(old_character_index - offset_index) % 26]\n", + " encoded_message += new_character\n", + " else:\n", + " encoded_message += message[i]\n", + " \n", + " return encoded_message\n", + "\n", + "vigenere_message_for_v = \"thanks for teaching me all these cool ciphers! you really are the best!\"\n", + "keyword_for_v = \"besties\"\n", + "\n", + "print(vigenere_encode(vigenere_message_for_v, keyword_for_v))\n", + "print(vigenere_decode(vigenere_encode(vigenere_message_for_v, keyword_for_v), keyword_for_v))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Conclusion\n", + "Over the course of this project you've learned about two different cipher methods and have used your Python skills to code and decode messages. There are all types of other facinating ciphers out there to explore, and Python is the perfect language to implement them with, so go exploring! " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}