繁体   English   中英

在python中返回多个值时的不同结果(Cryptopal挑战)

[英]Different results when return multiple values in python (Cryptopal challenges)


我正在研究cryptopals挑战的问题3(set 1)( https://cryptopals.com/sets/1/challenges/3
我已经找到了密钥('x')并解密了消息('像一磅培根一样烹饪mcs')这是我的代码:

from hexToBase64 import hexToBinary
from fixedXOR import xorBuffers

def binaryToChar(binaryString):
    asciiValue = 0
    for i in range(int(len(binaryString))-1,-1,-1):
        if(binaryString[i] == '1'):
          asciiValue = asciiValue + 2**(7-i)
    return chr(asciiValue)

def decimalToBinary(number):
    binaryString = ""
    while (number != 0):
        bit = number % 2 
        binaryString = str(bit) + binaryString
        number = int(number/2)
    while(len(binaryString) < 8): 
        binaryString = "0" + binaryString
    return binaryString

def breakSingleByteXOR(cipherString):
    decryptedMess = ""
    lowestError = 10000
    realKey = ""
    for i in range(0,128):
        errorChar = 0 
        tempKey = decimalToBinary(i)
        tempMess = ""
        for j in range(0,len(cipherString),2):
            #Take each byte of the cipherString 
            cipherChar = hexToBinary(cipherString[j:j+2])
            decryptedChar = binaryToChar(xorBuffers(cipherChar,tempKey))
            asciiValue = ord(decryptedChar)
            if (not ((asciiValue >= 65) and (asciiValue <= 90)) \
               or ((asciiValue >= 90) and (asciiValue <= 122)) \
               or ( asciiValue == 32 )):
               # if the character is not one of the characters ("A-Z" or "a-z"
               # or " ") consider it as an "error" 
               errorChar += 1 
            tempMess = tempMess + decryptedChar
        if(errorChar < lowestError):
            lowestError = errorChar
            decryptedMess = tempMess
            realKey = chr(i)
    return (realKey,decryptedMess)



if __name__ == "__main__":
    print(breakSingleByteXOR("1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736")) 

问题是,当我使用功能breakSingleByteXOR返回一个值(decryptedMess)时,结果“显示mcS像培根一样”没问题
但是当我使用函数返回2个值时(如上面的代码-(key,decryptedMess)),我收到了一个奇怪的结果('x','cOOKING \\ x00mc \\ x07S \\ x00LIKE \\ x00A \\ x00POUND \\ x00OF \\ x00BACON') ,任何人都可以向我解释为什么会这样吗?

Tbh,我在学习python的同时也正面临挑战,因此希望我不会用这些代码触发任何人。...如果有人可以给我一些有关编写良好python代码的建议,我也将非常感谢
谢谢大家:D

的确,打印字符串不同的原因是print功能的怪癖。

该程序的更深层问题是它无法产生正确的答案。 那是因为if试图确定解密的字符是否在可接受的范围内,那很丑陋if这是不正确的。

这有两种错误。 第一个是(asciiValue >= 90)应该是(asciiValue >= 97) 编写所有这些表达式的更好方法(可以避免此错误)是将它们表示为(asciiValue >= ord('a'))(asciiValue == ord(' ')) ,依此类推,避免使用难以理解的数字。

第二种方法是表达式未正确分组。 当他们站立时,他们这样做:

character is not in the range 'A' to 'Z',
    or character is in the range 'a' to 'z',
    or character is 'space',
        then count this as an error

因此,一些本应该不错的字符(特别是从“ a”到“ z”以及空格)被视为坏字符。 要解决此问题,您需要对括号进行重新处理,以使条件为:

character is not in the range 'A' to 'Z',
    and character is not in the range 'a' to 'z',
    and character is not space,
        then count this as an error

或(您正在尝试的样式)

character is not (in the range 'A' to 'Z'
    or in the range 'a' to 'z'
    or a space)

我不会为您提供确切的插入式表达式来修复该程序,让您自己解决这个问题会更好。 (处理这种复杂性的一种好方法是将其移动到一个返回TrueFalse的单独函数中。通过调用具有不同字符的函数并查看结果,可以轻松地测试实现是否正确是你想要的。)

当您获得正确的表达式时,您会发现程序发现了一个不同的“最佳密钥”,并且该密钥的解密字符串不包含愚蠢的超出范围的字符,这些字符在print上的行为异常。

print功能是罪魁祸首-执行时它将\\x00\\x07字符\\x07为ASCII值。 具体来说,只有在将字符串传递给print函数时,才会发生这种情况,而不是将迭代对象或其他对象(例如tuple )传递给它。

这是一个例子:

>>> s = 'This\x00string\x00is\x00an\x00\x07Example.'

>>> s
'This\x00string\x00is\x00an\x00\x07Example.'

>>> print(s)
This string is an Example.

如果要将字符串s添加到可迭代( tuplesetlist )中,则将不会通过print函数set s格式:

>>> s_list = [s]
>>> print(s_list)  # List
['This\x00string\x00is\x00an\x00\x07Example.']

>>> print(set(s_list))  # Set
{'This\x00string\x00is\x00an\x00\x07Example.'}

>>> print(tuple(s_list))  # Tuple
('This\x00string\x00is\x00an\x00\x07Example.')

编辑

因为\\x00\\x07字节是ASCII控制字符( \\x00是NUL, \\x07是BEL),所以您无法用其他任何方式表示它们。 因此,无需打印就可以从字符串中剥离这些字符的唯一方法之一就是使用.replace()方法。 但是如果终端将\\x00字节视为空格,则必须使用s.replace('\\x00', ' ')来获得相同的输出,该输出现在更改了字符串的真实内容。

否则在构建字符串时; 您可以尝试实现一些逻辑来检查ASCII控制字符,而不是将它们添加到tempMess或不添加其他字符(例如空格或类似字符)。

参考

ASCII Wiki: https//en.wikipedia.org/wiki/ASCII

诅咒模块: https ://docs.python.org/3.7/library/curses.ascii.html?highlight = ascii#module- curses.ascii (如果您希望实现任何逻辑,可能会很有用)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM