【问题标题】:Equivalent strings don't give equivalent bitstrings in Python等效字符串在 Python 中不给出等效的位串
【发布时间】:2019-02-25 01:15:56
【问题描述】:

我目前正在为一项作业制作加密程序,但我无法解密。原因是密钥是由随机生成的位串制成的字符串,但是当将密钥转回位串时,我得到一个不同的位串。在检查并发现将密钥转回二进制后的位串比用于制作密钥的位串短后,我意识到这一点。

##imports##################################################
from socket import *
import random

##functions################################################
def CCipher(message, k):
    output = ""
    for x in message:
        i = ord(x)
        i = (i+k)%128
        output += chr(i)
    return output

def toBinary(message):
    output = ""
    for x in message:
        i = bin(ord(x))[2:]
        output += i
    return output

def XOR(bitstring1, bitstring2):
    output = ""
    if(len(bitstring1) != len(bitstring2)):
        print("Use bitstrings of the same length")
        return None
    for x in range(len(bitstring1)):
        if(bitstring1[x] == "1" and bitstring2[x] == "0"):
            output += "1"
        elif(bitstring1[x] == "0" and bitstring2[x] == "1"):
            output += "1"
        else:
            output += "0"
    return output

def randomBinary(k):
    output = ""
    for x in range(k):
        i = random.randint(0,1)
        output = output + str(i)
    return output

def toString(message):
    output = ""
    i = ""
    n = 0
    for x in message:
        n += 1
        i += x
        if(n == 7):
            output += chr(int(i,2))
            n = 0
            i = ""
    return output

##server stuff#########################################
serverName = "OmariPC"
serverPort = 12347
clientSocket = socket(AF_INET,SOCK_STREAM)
clientSocket.connect((serverName,serverPort))

##files################################################
nowar = open("NoWar.dat",'r')
trump = open("Trump.dat","w")

##encryption###########################################
message = nowar.read()
mesBin = toBinary(message)
bkey = randomBinary(len(mesBin))
encrypted = XOR(mesBin, bkey)
encrypted = toString(encrypted)
key = toString(bkey)
trump.write(encrypted)
trump.close()
enKey = CCipher(key, 4)

##sending###############################################
clientSocket.send(enKey.encode())
print(len(enKey))
clientSocket.send(encrypted.encode())
print(len(encrypted))

##testing###############################################
if key == toString(bkey):
    print(True)
else:
    print(False)
if len(toBinary(key)) == len(bkey):
    print(True)
else:
    print(False)

输出: 168 168 真的 假的

【问题讨论】:

  • key == toString(bkey) 测试似乎没有用,因为key 首先被初始化为toString(bkey)。他们当然是平等的。您应该通过对您的函数进行单元测试来开始调试它:toString() 是否会为给定的输入生成您期望的字符串? toBinary()
  • 您的 toString() 实现在收集 7 位后生成字符,但您不应该收集 8 位吗?
  • 是的,在以前的程序中,我使用了这些确切的函数(尽管被转换的消息要小得多),它们为我提供了我预期的结果。也谢谢你现在提到它不需要 key == toString(bkey) 测试
  • toString() 函数按预期工作,因为生成的二进制代码也是 7 位长。它最初应该是 8,但先生说使用 7,因为那是正在生成的,而其他人不知道如何将额外的 0 添加到位串的前面

标签: python security encryption binary one-time-pad


【解决方案1】:
def toBinary(message):
    output = ""
    for x in message:
        i = bin(ord(x))[2:]
        output += i
    return output

bin(ord(x)) 生成可变长度的字符串。例如:

>>> bin(ord(' '))
0b100000
>>> bin(ord('a'))
0b1100001

您将bin() 的所有结果连接在一起,因此以后无法将它们分开。同时,您的 toString() 函数一次只能读取 7 个“位”。

您可以让bin() 附加固定大小的块:

# Pad the left with 0s to always generate a string of length 7.
# (Assumes that all input characters are ASCII.)
assert(ord(x) < 128)
bin(ord(x))[2:].rjust(7, '0')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-10
    • 2022-08-17
    • 2015-05-24
    • 1970-01-01
    • 1970-01-01
    • 2018-03-29
    • 2014-01-14
    • 2013-06-16
    相关资源
    最近更新 更多