1

Well I have an assignment to implement DES and I chose python, only problem is I can't figure out how to XOR bits of a String or Byte String, I can manually XOR them if only I can manage to read the 1s and 0s in them.

Example:

s1 = b'abc'
s2 = b'efg'

s3 = XOR(s1,s2) // my own method

How can I XOR them or how can I get the binary values of 1s and 0s that represent them?

If you use any python methods explain them, I'm relatively new to this language.

Obito
  • 391
  • 3
  • 8
Newbie
  • 386
  • 4
  • 19
  • repeated question? [https://stackoverflow.com/questions/2612720/how-to-do-bitwise-exclusive-or-of-two-strings-in-python][1] [1]: https://stackoverflow.com/questions/2612720/how-to-do-bitwise-exclusive-or-of-two-strings-in-python – adrianX Dec 31 '14 at 08:30
  • i think it is, but i got alot of questions about implementing these methods since i'm really new to python and generally wanna know more about it – Newbie Dec 31 '14 at 09:24

3 Answers3

3
>>> b''.join(chr(ord(a) ^ ord(b)) for a, b in zip(b'abc', b'efg'))
'\x04\x04\x04'
Dan D.
  • 73,243
  • 15
  • 104
  • 123
2

First you need to zip your strings then use ord (in python 2) and ^ for each of characters :

>>> s1 = b'abc'
>>> s2 = b'efg'
>>> ''.join(chr(ord(i)^ord(j)) for i,j in zip(s1,s2))
'\x04\x04\x04'

the ord() function retuen value of the byte when the argument is an 8-bit string.But if you are using python 3 you dont need ord :

>>> ''.join(chr(i^j) for i,j in zip(s1,s2))
'\x04\x04\x04'

Since bytes objects are sequences of integers (akin to a tuple), for a bytes object b, b[0] will be an integer, while b[0:1] will be a bytes object of length 1. (This contrasts with text strings, where both indexing and slicing will produce a string of length 1)

example :

>>> s1[0]
97
>>> s1[0:1]
b'a'

and if you want to convert back your strings you need to firs convert the XORed string to binary you can do it by binascii.a2b_qp function :

>>> import binascii 
>>> s=''.join(chr(i^j) for i,j in zip(s1,s2))
>>> s4=binascii.a2b_qp(s)
>>> ''.join(chr(i^j) for i,j in zip(s1,s4))
'efg'
Mazdak
  • 105,000
  • 18
  • 159
  • 188
  • i'm not really familiar with the ord and python syntax, firstly i'm getting "TypeError: ord() expected string of length 1, but int found" is it because i'm using python 3.x and secondly does join(chr(ord(i)^ord(j)) for i,j in zip(s1,s2)) = perform ord(i) xor ord (j) for the range in zip? – Newbie Dec 31 '14 at 09:22
  • @Newbie yep, in python 3 you dont need `ord` ! see the edit ! – Mazdak Dec 31 '14 at 09:47
  • okay i know that i shouldn't ask this, but can u XOR them back to return s1? s3 =''.join(chr(i^j) for i,j in zip(s1,s2)) s4 =''.join(chr(i^j) for i,j in zip(s3,s2)) (s3 is printing 3 chars which i can't copy here) this isn't working – Newbie Dec 31 '14 at 10:03
  • I love you, thanks alot for all your troubles with this newbie :D! – Newbie Dec 31 '14 at 10:51
  • @Newbie you're welcome dude ! there's no trouble with your questions , i'm appreciated for your good question that forced me to learn new things ! ;) – Mazdak Dec 31 '14 at 12:31
1

Not really efficient, but this should work.

s1 = b'abc'
s2 = b'efg'
s3= b''
for c1,c2 in zip(s1, s2):
    s3 += chr( ord(c1) ^ ord(c2) )

>>> s3
'\x04\x04\x04'
xvan
  • 4,554
  • 1
  • 22
  • 37