为什么我得到错误的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.(代码片段

为啥我通过 jquery ajax 和 codeigniter 得到验证错误?

为啥我得到错误的清单? [复制]

为什么我没有得到分段错误?

为啥我得到以下程序的分段错误?

代码中异常捕获输出