1

I've created this code that uses the Vigenère cipher to encrypt a block of text, for some reason it's giving me this weird output

import string

original_word = raw_input("what text do you want to encrypt ?")
one_time_pad = raw_input("How do you want to encrypt ?")
word_array = list(original_word)
pad = list(one_time_pad)

i = 0
b = 0
for word in word_array:
    word_array[i]= chr(ord(word) + ord(pad[b]))
    print word_array
    i += 1
    if b == len(one_time_pad):
        b = 0
    else:
        b += 1

cipher_text = "".join(word_array)
print cipher_text

that only gives me this weird output

 ['\xc2', 'b', 'c']
  ['\xc2', '\xc4', 'c']
  ['\xc2', '\xc4', '\xc6']
  ???

Can somebody please explain this?

Artjom B.
  • 58,311
  • 24
  • 111
  • 196
Zubin JAIN
  • 47
  • 3
  • Please fix your indentation's code. – Chiheb Nexus May 28 '17 at 03:01
  • Also: `chr(ord('a') +ord('a'))` gives: '\xc2'. i think you may reconcider your algorithm. Or maybe can you explain how do your algorithm work ? – Chiheb Nexus May 28 '17 at 03:08
  • First thing ... `if b == len(one_time_pad)` should be checking for `len()-1` since `one_time_pad[len(one_time_pad)]` results in an `IndexError`. Try using `b = (b + 1) % len(one_time_pad)` instead of the `if-else`. – D.Shawley May 28 '17 at 03:09
  • Ok this is supposed to work by adding the values of the chars and outputing a new char in that place, I'm just confused about the output – Zubin JAIN May 28 '17 at 03:56
  • Have a look here: https://stackoverflow.com/questions/tagged/vigenere+python – Artjom B. May 28 '17 at 07:22

1 Answers1

0

So the Vigenère cipher is defined on letters [A-Z]. You are using ord() to find the ASCII index of characters. However, ASCII is defined over more than just the uppercase letters. For example:

>>> ord('m')
109
>>> ord('k')
107
>>> 216

The value of the 216th character is not defined in general ASCII, so Python when you use chr() to get the character, you will get '\xd8', which is Python telling you that it is "just the 0xd8th (is hex for 216) character".

Instead you will want to remain in the range of uppercase letters. I would suggest to do the following:

ord1 = string.ascii_uppercase.index(word.upper())
ord2 = string.ascii_uppercase.index(pad[b].upper())
word_array[i] = string.ascii_uppercase[(ord1 + ord2) % 26]
dsprenkels
  • 1,464
  • 14
  • 21