title: ROT2 cipher resulting in different than expected characters when deciphered with Python
body: <p>I was having fun solving the riddles from the <a href="http://www.pythonchallenge.com/pc/def/map.html" rel="nofollow noreferrer">Pythonchallenge</a> website</p>
  <p>when I stumbled upon a weird behaviour:</p>
  <p>With this input:
  *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.</p>
  <p>We should be able to get the following output:
  *&quot;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.&quot;
  *</p>
  <p>Instead what we get when we decipher it with a simple ROT2 script is:
  <em>i hope you didnt tr{nsl{te it |y h{nd0 th{ts wh{t computers {re for0 doing it in |y h{nd is inefficient {nd th{t)s why this text is so long0 using string0m{ketr{ns</em>+ is recommended0 now {pply on the url0*</p>
  <p>My ROT2 script I refer to is as <a href="https://pythontutor.com/visualize.html#code=user_input%20%3D%20input%28%29.split%28%27%20%27%29%0Anewletter_int%20%3D%200%0Anew_output%20%3D%20%5B%5D%0A%0Afor%20word%20in%20user_input%3A%0A%20%20%20%20newletter_int%20%3D%200%20%0A%20%20%20%20newstr%20%3D%20%27%27%0A%0A%20%20%20%20for%20letter%20in%20word%3A%0A%20%20%20%20%20%20%20%20newletter%20%3D%20ord%28letter%29%20%2B%202%0A%20%20%20%20%20%20%20%20newstr%20%2B%3D%20chr%28newletter%29%0A%20%20%20%20new_output.append%28newstr%29%0Aprint%28%22%20%22.join%28new_output%29%29&amp;cumulative=false&amp;curInstr=1&amp;heapPrimitives=nevernest&amp;mode=display&amp;origin=opt-frontend.js&amp;py=3&amp;rawInputLstJSON=%5B%22g%20fmnc%20wms%20bgblr%20rpylqjyrc%20gr%20zw%20fylb.%20rfyrq%20ufyr%20amknsrcpq%20ypc%20dmp.%20bmgle%20gr%20gl%20zw%20fylb%20gq%20glcddgagclr%20ylb%20rfyr%27q%20ufw%20rfgq%20rcvr%20gq%20qm%20jmle.%20sqgle%20qrpgle.kyicrpylq%28%29%20gq%20pcamkkclbcb.%20lmu%20ynnjw%20ml%20rfc%20spj.%22%5D&amp;textReferences=false" rel="nofollow noreferrer">follows</a>:</p>
  <pre><code>user_input = input().split(' ')
  newletter_int = 0
  new_output = []
  
  for word in user_input:
      newletter_int = 0 
      newstr = ''
  
      for letter in word:
          newletter = ord(letter) + 2
          newstr += chr(newletter)
      new_output.append(newstr)
  print(&quot; &quot;.join(new_output))
  </code></pre>
  <p>This naturally happens of course, because the letter &quot;y&quot; has the order number of 121 and when we add 2 to 121 we get the character with order number 123 which is &quot;{&quot;. But why would then the Python maketrans result in the correct character?</p>
  <p>Please, note that I have solved the task with maketrans and what I am looking for is not a solution to the riddle, as I have been able to find it out myself. I am looking for a simple explanation what is the difference between the two methods. Also, please, do not refer to the pages where the solution is linked, as I am not looking for them, but for explanation of the difference of the functionalities between my script above and the string.maketrans() method and also an answer to the question why is this the recommended way to solve the riddle.</p>