异或位串

  • 本文关键字: python byte xor
  • 更新时间 :
  • 英文 :


我正在尝试实现明文的RC4加密/解密,我已经在XOR步骤上停留了一段时间。

我的代码如下:

def byteXOR(a, b):
#TODO take two lists of byte string and return a list with the xor product of them
u = a.split()
v = b.split()
print('Fst: t {}'.format(u))
print('Snd: t {} n'.format(v))
'''Fill inn 0' if a bit is shorter than the other'''
for x,y in zip(u, v):
if len(x) != len(y):
if len(x) < len(y):
x.zfill(len(y) - len(x))
elif len(x) > len(y):
y.zfill(len(x) - len(y))
xor = [ord(x) ^ ord(y) for (x, y) in zip(a, b)]
print('Fst: t {}'.format(u))
print('Snd: t {}'.format(v))
print('XOR: t {}'.format(xor))
return xor
p = "1111 1010001 10111111 11111010 10101011"
q = "1101000 1100101 1101100 1101100 1101111"
byteXOR(p, q)

我得到这个输出:

Fst:     ['1111', '1010001', '10111111', '11111010', '10101011']
Snd:     ['1101000', '1100101', '1101100', '1101100', '1101111'] 
Fst:     ['1111', '1010001', '10111111', '11111010', '10101011']
Snd:     ['1101000', '1100101', '1101100', '1101100', '1101111']
XOR:     [0, 0, 1, 0, 16, 1, 0, 17, 1, 1, 0, 1, 17, 1, 1, 17, 0, 0, 1, 0, 0, 16, 1, 17, 0, 0, 1, 1, 0, 0, 16, 17, 1, 0, 0, 0, 1, 0, 0]

我似乎无法解决的第一个问题是如何确保比特串的长度相同,我使用了内置的方法zfill((,但当我打印列表时,它们没有改变。

我遇到的第二个问题是如何从每个列表中获得第n个元素的XOR乘积的期望输出,如下所示:

Fst:      ['0001111', '1010001', '10111111', '11111010', '10101011']
Snd:      ['1101000', '1100101', '01101100', '01101100', '01101111']
XOR:      ['0110011', '0110100', '11010011', '10010110', '11000100']

关于XOR,您需要将strs转换为ints,使用^,然后转换为bin表示,以使其在列表中的元素之间切换,您可以使用map,即:

Fst = ['0001111', '1010001', '10111111', '11111010', '10101011']
Snd = ['1101000', '1100101', '01101100', '01101100', '01101111']
result = list(map(lambda x,y: bin(int(x,2)^int(y,2)), Fst, Snd))
print(result)

输出

['0b1100111', '0b110100', '0b11010011', '0b10010110', '0b11000100']

请注意,bin返回以0b开头的表示,并尽可能少地返回数字,因此,如果您希望在没有0b的情况下具有固定宽度,则需要丢弃前两个字符,然后使用zfill,即

final_result = [i[2:].zfill(8) for i in result]
print(final_result)

输出:

['01100111', '00110100', '11010011', '10010110', '11000100']

注意,int函数的第二个可选参数允许指定基数,它可以是从236的任何值。例如:

print(int('FFF',16))

输出:

4095

等等

这对你有用吗?

def byteXOR(a, b):
u = [int(bits, 2) for bits in a.split()]
v = [int(bits, 2) for bits in b.split()]
xor =  [f ^ s for (f, s) in zip(u, v)]
print(" ".join([bin(bits).replace("0b", "") for bits in xor]))
return xor
p = "1111 1010001 10111111 11111010 10101011"
q = "1101000 1100101 1101100 1101100 1101111"
byteXOR(p, q)

对于第一个问题,str.zfill()返回一个新字符串,它不会修改原始字符串。因此,您必须将其重新分配给您的变量:

for x,y in zip(u, v):
if len(x) != len(y):
if len(x) < len(y):
x = x.zfill(len(y) - len(x))
elif len(x) > len(y):
y = y.zfill(len(x) - len(y))

对于第二个问题,您可以将字符串强制转换为int(),并传递一个base=2参数来表示其为二进制。然后,您可以对整数执行XOR"^",然后使用bin()将其强制转换回二进制字符串

x = '0001111'
y = '1101000'
x = int(x, base=2)
y = int(y, base=2)
z = str(bin(x ^ y))[2:]  # remove the trailing 0b from the string
print(z)

输出:

1100111

也就是说,由于int(string, base=2)将字符串转换为整数,因此您实际上不需要首先zfill()字节,您可以使用zip()在一行中执行以下操作:

p = "1111 1010001 10111111 11111010 10101011"
q = "1101000 1100101 1101100 1101100 1101111"
r = [bin(int(x, base=2) ^ int(y, base=2))[2:].zfill(8) for x, y in zip(p.split(' '), q.split(' '))]
print(' '.join(r))

输出:

01100111 00110100 11010011 10010110 11000100

相关内容

  • 没有找到相关文章

最新更新