为什么我得到错误的XOR输出
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么我得到错误的XOR输出相关的知识,希望对你有一定的参考价值。
我刚刚开始了cryptopals.com的挑战,我已经陷入了第二个问题。由于某种原因,我的输出错误只有一个字符而不是7我得到3作为我的XOR操作的第一个数字。
你能帮我找到我代码中的错误:
def XORfunction(input_1, input_2):
bin_input_1 = hexToBinary(input_1)
bin_input_2 = hexToBinary(input_2)
# check if length of strings is the same for XOR compare or add "0" to the end
if len(bin_input_1) != len(bin_input_2):
if len(bin_input_1) > len(bin_input_2):
number_length = len(bin_input_1)
temp_input = list(bin_input_2)
for x in xrange(0, number_length - len(bin_input_2)):
temp_input.insert(0, "0")
bin_input_2 = "".join(temp_input)
if len(bin_input_1) < len(bin_input_2):
number_length = len(bin_input_2)
temp_input = list(bin_input_1)
for x in xrange(0, number_length - len(bin_input_1)):
temp_input.insert(0, "0")
bin_input_1 = "".join(temp_input)
solution = []
# XOR is like a sum so if el1+el2 == 1 output is 1 else output is 0
for x in xrange(0, len(bin_input_1) - 1):
# the array is iterated from [0] to len(bin_input_1)-1 so the elements are calculated from last to first
current_compare = int(bin_input_1[x]) + int(bin_input_2[x])
if current_compare == 1:
solution.insert(-1, "1")
else:
solution.insert(-1, "0")
return dec_to_hex(int("".join(solution), 2))
# the final solution has to be converted from decimal to hexadecimal
def dec_to_hex(value):
dictionary_hex = "0123456789abcdef"
solution = []
while value != 0:
solution.insert(0, dictionary_hex[value % 16])
value = value / 16
return "".join(solution)
# Hex is converted to a binary string to make comparisons easy as the digits become easy to select as an array of chars
def hexToBinary(text):
# first Hex is converted to decimal, then to binary (that needs to be sliced for a clean output), lastly it becomes a string
return str(bin(int(text, base=16))[2:])
print XORfunction("1c0111001f010100061a024b53535009181c", "686974207468652062756c6c277320657965")
# expected output: 746865206b696420646f6e277420706c6179
# my output: 346865206b696420646f6e277420706c6179
这是我第一次发帖,所以欢迎任何关于格式化/代码的提示。
PS:我知道我应该使用库,但我想弄清楚我的错误是什么
答案
你有几个问题:
- 你的
hexToBinary()
函数不会产生填充二进制。bin()
每字节不会返回8位;不包括前导零!因此,你从第一个字符串的开头缺少000
,另一个字符串是0
。您尝试在XORfunction
函数中对此进行补偿,但这只会增加2个零,而不是3。 您可以使用str.format()
方法来确保获得正确的位数,零填充:return '{:0{}b}'.format(int(text, base=16), len(text) * 4)
b
格式化指令告诉str.format()
生成数字的二进制表示。宽度之前的0
表示将数字填充到所需长度,并且长度的{}
占位符取自len(text) * 4
值,因此输入中每个十六进制字符为4位。 - 您正在列表中的最后一个元素之前插入解决方案位。这会在解决方案的最后留下第一位,在其之前插入其他所有内容:
>>> demo = [] >>> demo.insert(-1, 'foo') # inserting into an empty list >>> demo ['foo'] >>> demo.insert(-1, 'bar') # inserting before the last element >>> demo ['bar', 'foo'] >>> demo.insert(-1, 'spam') # inserting before the last element ['bar', 'spam', 'foo']
只需使用append将元素添加到列表的末尾:solution.append("1")
和solution.append("0")
- 你跳过处理最后一位。你需要一直迭代到
len(bin_input_1)
:for x in xrange(len(bin_input_1)):
通过应用这3个修复程序,您的代码将工作并生成预期的输出。
您的代码确实在Python语言和标准库中重新发明了标准轮:
- 不是手动对每个位进行异或,而是使用
^
运算符一次处理整个字节。 - 使用
binascii.hexlify()
和binascii.unhexlify()
functions在十六进制和字节之间进行转换。 - 在Python 2中,使用
bytearray()
type将二进制数据作为整数序列来处理,这对于应用XOR操作要容易得多。 - 使用
zip()
function迭代两个序列,将两者中的元素配对。
放在一起作为Python 2解决方案:
from binascii import hexlify, unhexlify
def XORfunction(input_1, input_2):
input_1 = bytearray(unhexlify(input_1))
input_2 = bytearray(unhexlify(input_2))
return hexlify(bytearray(
a ^ b for a, b in zip(input_1, input_2)))
在Python 3中,您可以简单地省略前两个bytearray()
调用,并用bytes()
替换最后一个。
以上是关于为什么我得到错误的XOR输出的主要内容,如果未能解决你的问题,请参考以下文章
java缓冲字符字节输入输出流:java.io.BufferedReaderjava.io.BufferedWriterjava.io.BufferedInputStreamjava.io.(代码片段