I have tried to encrypt a string using a XOR operator and took the output in alphabets. Now when I am trying to decrypt it I'm not getting the string again. Encryption code:
string= "Onions"
keyword = "MELLON"
def xor(string, key):
st=[]
ke=[]
xored=[]
for i in string:
asc= (ord(i))
st.append(int(asc))
print(st)
for i in key:
asc= (ord(i))
ke.append(int(asc))
print(ke)
for i in range(len(string)):
s1=st[i]
k1=ke[i]
abc = s1^k1
le = ord('A')+abc
ch = chr(le)
if le> 90:
le= le-26
ch = chr(le)
print(s1,k1)
print('XOR =',abc)
print(ch)
xored.append(ch)
print(xored)
return("" . join(xored))
Need help!!
The algorithm does not perform a pure XOR, but maps values conditionally to another value, leading to a relation that is no longer bijective.
To illustrate this point. See what this script outputs:
keyword = "MELLON"
print(xor("Onions", keyword) == xor("OTGEHs", keyword))
It will output True
!
So this means you have two words that are encrypted to the same string. This also means that if you need to do the reverse, there is no way to know which of these is the real original word.
If you want to decryption to be possible, make sure to only use operations that lead to a bijective mapping. For instance, if you only use a XOR, without adding or subtracting values, it will be OK.
Here is an approach where only lower and uppercase letters of the Latin alphabet are allowed (for both arguments):
def togglecrypt(string, key):
mapper = "gUMtuAqhaEDcsGjBbreSNJYdFTiOmHKwnXWxzClQLRVyvIkfPpoZ"
res = []
for i, ch in enumerate(string):
shift = mapper.index(key[i % len(key)]) % 26
i = mapper.index(ch)
if i < 26:
j = 26 + (i + shift) % 26
else:
j = (i - shift) % 26
res.append(mapper[j])
return("".join(res))
keyword = "MELLON"
encoded = togglecrypt("Onions", keyword)
print(encoded) # TdsDAn
print(togglecrypt(encoded, keyword)) # Onions