gpt4 book ai didi

python - 类型错误 : object of type '_io.TextIOWrapper' has no len ()

转载 作者:行者123 更新时间:2023-12-05 05:06:58 28 4
gpt4 key购买 nike

完整代码如下:

from Crypto.Protocol.KDF import scrypt
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes

class transmitter():

def __init__(self):

self.random_password = None
self.message_plain = True
self.key = None
self.salt = None

self.password_option()
self.text_option()
self.encrypt()


def password_option(self):

while ( self.random_password == None ):

random = input("\nDo you want to generate a random symmetric key? (y/n)\n\n>>> ").strip().lower()

if random == "y":
self.random_password = True
self.random()

elif random == "n":
self.random_password = False
self.random()

else:
pass

def text_option(self):

if self.message_plain:

question = input("\nHow will you enter your message?\n\n[1] file\n\n[2] directly in the program\n\n>>> ").strip()

if question == "1":
path = input("\nEnter the file path\n\n>>> ")
name = path.split("\\")[-1]
with open(name,mode = "r") as self.message_plain:
self.message_plain.read().encode("utf-8")

elif question == "2":
self.message_plain = input("\nEnter your message\n\n>>> ").strip()
self.message_plain = self.message_plain.encode("utf-8")


def random(self):

if self.random_password:
password = "password".encode("utf-8")
self.salt = get_random_bytes(16)
self.key = scrypt(password, self.salt, 16, N=2**14, r=8, p=1)

else:
password = input("\nEnter your password\n\n>>> ").strip()
self.salt = get_random_bytes(16)
self.key = scrypt(password.encode("utf-8"), self.salt, 16, N=2**14, r=8, p=1)


def encrypt(self):

cipher = AES.new(self.key,AES.MODE_GCM)
cipher.update(b"header")
cipher_text,tag_mac = cipher.encrypt_and_digest(self.message_plain)
transmitted_message = cipher_text,tag_mac,self.salt,cipher.nonce
Receptor(transmitted_message)

class receiver():

def __init__(self,received_message):
# nonce = aes_cipher.nonce
self.cipher_text,self.tag_mac,self.salt,self.nonce = received_message
self.decrypt(self.cipher_text,self.tag_mac,self.salt,self.nonce)

def decrypt(self,cipher_text,tag_mac,salt,nonce):

try:
password = input("\nEnter your password\n\n>>> ").strip()
decryption_key = scrypt(password.encode("utf-8"), salt, 16, N=2**14, r=8, p=1)
cipher = AES.new(decryption_key,AES.MODE_GCM,nonce)
cipher.update(b"header")
plain_text = cipher.decrypt_and_verify(cipher_text,tag_mac)
plain_text = plain_text.decode("utf-8")
print(f"\nText -> {plain_text}\n")

except ValueError:
print("\nAn error has occurred..\n")

if __name__ == '__main__':
init = transmitter()

错误如下:

Traceback (most recent call last):
File ".\crypto.py", line 109, in <module>
init = Emisor()
File ".\crypto.py", line 16, in __init__
self.encrypt()
File ".\crypto.py", line 74, in encrypt
cipher_text,tag_mac = cipher.encrypt_and_digest(self.message_plain)
File "C:\Users\EQUIPO\AppData\Local\Programs\Python\Python37-32\lib\site-packages\Crypto\Cipher\_mode_gcm.py", line 547, in encryp
t_and_digest
return self.encrypt(plaintext, output=output), self.digest()
File "C:\Users\EQUIPO\AppData\Local\Programs\Python\Python37-32\lib\site-packages\Crypto\Cipher\_mode_gcm.py", line 374, in encryp
t
ciphertext = self._cipher.encrypt(plaintext, output=output)
File "C:\Users\EQUIPO\AppData\Local\Programs\Python\Python37-32\lib\site-packages\Crypto\Cipher\_mode_ctr.py", line 189, in encryp
t
ciphertext = create_string_buffer(len(plaintext))
TypeError: object of type '_io.TextIOWrapper' has no len()

我已经尝试了所有方法,但老实说,我不知道还能做什么。有谁知道哪里出了问题?

基本上,我想做的是将读取某个文件的结果保存在一个变量中。这样我就可以加密它。幸运的是,其余代码运行良好,只有那一段代码(我在问题中提出的第一个代码)出现了错误。

最佳答案

你需要改变这个:

with open(name, mode = "r") as self.message_plain:
self.message_plain.read().encode("utf-8")

进入这个:

with open(name, mode="r") as input_file:
self.message_plain = input_file.read().encode("utf-8")

第一个with block 在功能上等同于此:

self.message_plain = open(name, mode = "r")
self.message_plain.read().encode("utf-8")
self.message_plain.close()

这没有意义,因为它只是 self.message_plain放入文件对象中,不保存实际内容 read() .

第二个with block 在功能上等同于此:

input_file = open(name, mode = "r")
self.message_plain = input_file.read().encode("utf-8")
input_file.close()

这更有意义。

基本上,您使用的是 with statement 不正确,因为您更改了 self.message_plain 的类型至 <class '_io.TextIOWrapper'> .您可以通过打印 type(self.message_plain) 来检查这一点在with之后/之外陈述。但是 encrypt_and_digest方法需要一个类似字节的序列:

>>> help(cipher.encrypt_and_digest)
Help on method encrypt_and_digest in module Crypto.Cipher._mode_gcm:

encrypt_and_digest(plaintext, output=None) method of Crypto.Cipher._mode_gcm.GcmMode instance
Perform encrypt() and digest() in one step.

:Parameters:
plaintext : bytes/bytearray/memoryview
The piece of data to encrypt.
...

我还想就您的编码风格提出改进建议。

  1. Put spaces after commas .

    取而代之的是:

    self.cipher_text,self.tag_mac,self.salt,self.nonce = received_message

    这样写:

    self.cipher_text, self.tag_mac, self.salt, self.nonce = received_message
  2. Class names should use the CapWords convention.而不是:

    class transmitter

    改成

    class Transmitter
  3. 将您的变量初始化为您期望的类型。

    取而代之的是:

    self.message_plain = True

    将其初始化为空字符串 ( "" ) 或 ( None )。

关于python - 类型错误 : object of type '_io.TextIOWrapper' has no len (),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59524510/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com