簡體   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