我正在尝试制作一个简单的应用程序来加密文本。我不知道怎么了。
起初它确实可以运行,但是当按下“加密”按钮时,会提示错误,提示未定义密钥和文件名。
#!/usr/bin/python
import os
from Crypto.Cipher import AES
from Crypto.Hash import SHA256
from Crypto import Random
from appJar import gui
import datetime
import csv
def encrypt(key, filename):
chunksize = 64*1024
outputFile = "(encrypted)"+filename
filesize = str(os.path.getsize(filename)).zfill(16)
IV = Random.new().read(16)
encryptor = AES.new(key, AES.MODE_CBC, IV)
with open(filename, 'rb') as infile:
with open(outputFile, 'wb') as outfile:
outfile.write(filesize.encode('utf-8'))
outfile.write(IV)
while True:
chunk = infile.read(chunksize)
if len(chunk) == 0:
break
elif len(chunk) % 16 != 0:
chunk += b' ' * (16 - (len(chunk) % 16))
outfile.write(encryptor.encrypt(chunk))
with gui('Encryption App', '400x200', font={'size':18}) as app:
app.label('Simple encryption app')
app.entry('Type text to encrypt: ', label=True, focus=True)
filename = app.entry('Save as: ',label=True)
key = app.entry("Password", label=True, secret=True)
app.buttons(['Encrypt', 'Cancel'], [encrypt(app.entry('Save as: '),app.entry('Password: ')), app.stop])
运行时,显示错误消息:
2019-07-07 17:40:44,862 appJar:ERROR [Line 40->1784/__exit__]: ContextManager failed: Can't convert 'Entry' object to str implicitly
Traceback (most recent call last):
File "/home/skyandstars/Desktop/new_score.py", line 40, in <module>
app.buttons(['Encrypt', 'Cancel'], [encrypt(app.entry('Save as: '),app.entry('Password: ')), app.stop])
File "/home/skyandstars/Desktop/new_score.py", line 14, in encrypt
outputFile = "(encrypted)"+filename
TypeError: Can't convert 'Entry' object to str implicitly
答案 0 :(得分:0)
我检查了
def encrypt(key, filename):
print(filename, type(filename))
它显示filename
是tkinter.Entry
,而不是字符串,因此您不能在
Entry
"(encrypted)"+filename
要从Entry
获取字符串,必须在所有位置使用filename.get()
outputFile = "(encrypted)" + filename.get()
filesize = str(os.path.getsize( filename.get() )).zfill(16)
或者您可以在函数encrypt
的开头进行操作
filename = filename.get()
您对key
有相同的问题
编辑:运行代码时,我从tkinter看到其他常见错误。
按钮需要回调-这意味着不带()
且不带参数的函数名称-如app.stop
-但您使用encrypt(..)
。它在开始时运行encrypt(..)
,并为按钮分配None
,因为entry(..)
返回None
。
您可以使用lambda
创建不带参数的函数,并分配不包含()
的函数
new_function = lambda:encrypt(app.entry('Save as: '), app.entry('Password: '))
[new_function, app.stop]
或直接
[lambda:encrypt(app.entry('Save as: '), app.entry('Password: ')), app.stop]
编辑:另一个错误。您创建了两次条目entry('Save as: ')
entry('Password: ')
。将显示一对,并在其中输入文字。您在
[lambda:encrypt(app.entry('Save as: '), app.entry('Password: ')), app.stop]
但是当您按下按钮时它们是空的,因此您会在函数中得到空字符串。
您只需要使用一对
filename = app.entry('Save as: ', label=True)
key = app.entry("Password", label=True, secret=True)
app.buttons(['Encrypt', 'Cancel'], [lambda:encrypt(key, filename), app.stop])
您甚至可以在此位置使用get()
而不是在encrypt
内部使用
filename = app.entry('Save as: ', label=True)
key = app.entry("Password", label=True, secret=True)
app.buttons(['Encrypt', 'Cancel'], [lambda:encrypt(key.get(), filename.get()), app.stop])
完整代码
#!/usr/bin/python
import os
from Crypto.Cipher import AES
from Crypto.Hash import SHA256
from Crypto import Random
from appJar import gui
import datetime
import csv
def encrypt(key, filename):
chunksize = 64*1024
outputFile = "(encrypted)" + filename
filesize = str(os.path.getsize(filename)).zfill(16)
IV = Random.new().read(16)
encryptor = AES.new(key, AES.MODE_CBC, IV)
with open(filename, 'rb') as infile:
with open(outputFile, 'wb') as outfile:
outfile.write(filesize.encode('utf-8'))
outfile.write(IV)
while True:
chunk = infile.read(chunksize)
if len(chunk) == 0:
break
elif len(chunk) % 16 != 0:
chunk += b' ' * (16 - (len(chunk) % 16))
outfile.write(encryptor.encrypt(chunk))
with gui('Encryption App', '400x200', font={'size':18}) as app:
app.label('Simple encryption app')
app.entry('Type text to encrypt: ', label=True, focus=True)
filename = app.entry('Save as: ', label=True)
key = app.entry("Password", label=True, secret=True)
func = lambda:encrypt(key.get(), filename.get())
app.buttons(['Encrypt', 'Cancel'], [func, app.stop])
答案 1 :(得分:0)
在appJar中添加小部件时,例如:app.entry('test')
,将返回小部件。因此,在您的代码中,当您引用filename
时,它指向的是实际的输入框。
如果要在输入框中输入文本,则必须在需要时使用app.getEntry('test')
或更新的语法:app.entry('test')
因此,在您的加密函数中,不要使用filename
变量,而应使用app.entry('Save as: ')