我刚刚开始了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:我知道我应该使用库,但我想弄明白我的错误是什么
答案 0 :(得分:2)
您有几个问题:
您的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']
只需使用追加将元素添加到列表的末尾:
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在十六进制和字节之间进行转换。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()
。