密码程序失准

2024-05-23 15:28:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个python程序,需要两个字符串。一个是纯文本字符串,另一个是密钥。它所做的是遍历每个字符,并将位与密码字符异或。但来回走的时候,有几个字母似乎没有适当的变化。代码如下:

//turns int into bin string length 8
def bitString(n):
    bin_string = bin(n)[2:]
    bin_string = ("0" * (8 - len(bin_string))) + bin_string
    return bin_string

//xors the bits
def bitXOR(b0, b1):
    nb = ""
    for x in range(min(len(b0), len(b1))):
        nb += "0" if b0[x] == b1[x] else "1"
    return nb

//takes 2 chars, turns them into bin strings, xors them, then returns the new char
def cypherChar(c0, c1):
    return chr(int(bitXOR(bitString(ord(c0)), bitString(ord(c1))), 2))

//takes s0 (the plaintext) and encrypts it using the cipher key (s1)
def cypherString(s0, s1):
    ns = ""
    for x in range(len(s0)):
        ns += cypherChar(s0[x], s1[x%len(s1)])
    return ns

例如,有时在一个长字符串中,“test”这个词会被加密回“eest”,诸如此类

我已经检查了十几次代码,我不知道是什么原因导致一些字符发生了变化。有没有可能有些角色只是行为怪异?你知道吗

编辑:

示例:

This is a test

Due to the fact that in the last test

Some symbols: !@#$%^&*()

were not changed properly

I am retesting

END

使用密码密钥:“cypher key”

转换回:

This is a test

Due to toe aact that in the last sest

Some symbols: !@#$%^&*()

were not changed properly

I am retestiig

END

Tags: the字符串inteststringlenreturnbin
3条回答

我觉得你把事情搞得太复杂了:

def charxor(s1, s2):
    return chr(ord(s1) ^ ord(s2))

def wordxor(w1, w2):
    return ''.join(charxor(w1[i], w2[i]) for i in range(min(len(w1), len(w2))))

word = 'test'
key = 'what'
cyphered = wordxor(word, key)
uncyphered = wordxor(cyphered, key)

print(repr(cyphered))
print(uncyphered)

你得到了吗

'\x03\r\x12\x00'
test

How do you get the logical xor of two variables in Python?中对Python的位算法有很好的解释

当使用输入数据和键进行测试时,我发现函数的结果没有任何问题。为了演示,您可以尝试以下不应失败的测试代码:

import random

def random_string(n):
    return ''.join(chr(random.getrandbits(8)) for _ in range(n))

for i in range(1000):
    plaintext = random_string(500)
    key = random_string(random.randrange(1,100))
    ciphertext = cypherString(plaintext, key)
    assert cypherString(ciphertext, key) == plaintext

如果您能提供一个失败的纯文本、密钥和密码文本的确定示例,我可以进一步查看。你知道吗

抱歉,有点乱,我很快就把它拼好了

from binascii import hexlify, unhexlify
from sys import version_info

def bit_string(string):
    if version_info >= (3, 0):
        return bin(int.from_bytes(string.encode(), 'big'))
    else:
        return bin(int(hexlify(string), 16))

def bitXOR_encrypt(plain_text, key):
    encrypted_list = []
    for j in range(2, len(plain_text)):
        encrypted_list.append(int(plain_text[j]) ^ int(key[j])) #Assume the key and string are the same length
    return encrypted_list

def decrypt(cipher_text, key):
    decrypted_list = []
    for j in range(2, len(cipher_text)): #or xrange
        decrypted_list.append(int(cipher_text[j]) ^ int(key[j])) #Again assumes key is the same length as the string

    decrypted_list = [str(i) for i in decrypted_list]
    add_binary = "0b" + "".join(decrypted_list)
    decrypted_string = int(add_binary, 2)
    if version_info >= (3, 0):
        message =  decrypted_string.to_bytes((decrypted_string.bit_length() + 7) // 8, 'big').decode()
    else:
        message = unhexlify('%x' % decrypted_string)
    return message


def main():
    plain_text = "Hello"
    plain_text_to_bits = bit_string(plain_text)
    key_to_bits = bit_string("candy")

    #Encrypt
    cipher_text = bitXOR_encrypt(plain_text_to_bits, key_to_bits)

    #make Strings
    cipher_text_string = "".join([str(i) for i in cipher_text])
    key_string = "".join([str(i) for i in key_to_bits])

    #Decrypt
    decrypted_string = decrypt("0B"+cipher_text_string, key_string)

    print("plain text: %s" % plain_text)
    print("plain text to bits: % s" % plain_text_to_bits)
    print("key string in bits: %s" % key_string)
    print("Ciphered Message: %s" %cipher_text_string)
    print("Decrypted String: %s" % decrypted_string)

main()

有关更多详细信息或示例代码,您可以访问github上的my repository https://github.com/marcsantiago/one_time_pad_encryption

另外,我知道在这个示例中,键的长度与字符串的长度相同。如果要使用比字符串小的字符串,请尝试将其包装为vigenere密码(http://en.wikipedia.org/wiki/Vigenèreèu密码)

相关问题 更多 >