我为SimpleCrypt库创建了一个包装器,它允许轻松地加密/解密字符串。
使用该应用程序的方法如下:
//To encrypt
python encryptor.py file_name -e
//To decrypt
python encryptor.py file_name -d基本上,为了加密,我读取该文件,对其进行加密,并创建一个扩展名为.enc的新文件,这样显然(对我来说)它已经被加密了。
我不是在寻找一个超级安全的应用程序,我在辅导,当我离开我的笔记本时,我不想让学生检查他们未来的考试或诸如此类的东西。因此,这是一个小项目,我自己的乐趣,保护文件不受非IT人员。
我想我已经涵盖了每一种情况(拒绝许可、文件不存在、密码错误等等)。
我认为代码看起来会更好,但我最感兴趣的是是否遗漏了一些我不知道的bug (正如我说的,我尽我所能测试了应用程序),或者我忽略了一些Python基础知识。
encryptor.py
import sys
import os.path
import getpass
import simplecrypt
ReadMode = "r"
WriteMode = "w"
EncryptArg = "-e"
DecryptArg = "-d"
PermissionDenied = 13
FileDoesNotExist = 2
def main():
if not len(sys.argv) == 3:
print "Incorrect number of arguments."
print "Expected file-path encrypt/decrypt"
exit(1)
filepath = sys.argv[1]
encrypt_or_decrypt = sys.argv[2]
if not (encrypt_or_decrypt == EncryptArg or encrypt_or_decrypt == DecryptArg):
print "2nd argument provided is invalid, expected -e or -d, received : " + encrypt_or_decrypt
exit(1)
requires_encryption = encrypt_or_decrypt == EncryptArg
try:
stream = open(filepath, ReadMode)
file_content = stream.read()
stream.close()
if requires_encryption:
password = getpass.getpass("Password to decrypt : ")
encrypted_content = simplecrypt.encrypt(password, file_content)
write_stream = open(filepath + ".enc", WriteMode)
write_stream.write(encrypted_content)
write_stream.close()
else:
if not filepath[-4:0] == ".enc":
print "File was not encrypted using this application. Expected .enc format."
exit(1)
decrypted_content = None
try:
password = getpass.getpass("Password : ")
decrypted_content = simplecrypt.decrypt(password, file_content)
except simplecrypt.DecryptionException:
print "Password is invalid."
exit(1)
write_stream = open(filepath[:-4], WriteMode)
write_stream.write(decrypted_content)
stream.close()
os.remove(filepath)
except IOError, ioError:
if ioError.errno == PermissionDenied:
print "You do not have permission to access this file. Consider using sudo"
elif ioError.errno == FileDoesNotExist:
print "File does not exist."
else:
raise ioError
exit(1)
if __name__ == '__main__':
main()发布于 2017-08-10 08:55:53
-c标志将是很好的。对于大多数*nix命令行应用程序,您可以使用类似于encryptor -ec path的工具来完成这一任务。因此,我强烈建议使用析解析解析。使用类似于: def make_parser():解析器= argparse.ArgumentParser(prog='encryptor') parser.add_argument(' file _path',type=str,help='Path to file to file,以便加密或解密‘)。parser.add_argument('-c',‘-清理’,action='store_false',help=‘停止程序清理’)group = parser.add_mutually_exclusive_group(required=True) group.add_argument('-d',‘- decrypt’,action='store_true',help=‘指定程序应该在解密模式下运行’)。group.add_argument('-e',‘- encrypt’,action='store_true',help=‘指定程序应该在加密模式下运行’)。返回解析器UPPER_SNAKE_CASE,因此我建议您将ReadMode等更改为这种格式。目前,我把这个变量读成了一个类。open的参数,open(..., 'r')比open(..., READ_MODE)简单得多。当不使用'r'时,变量名只会随着时间的推移变得更糟--抽象到公共常量模块,重命名以更好地指定文件,等等。with,我以前写过一个相当通用的答案为什么你要这么做,不管怎么说,你并没有正确地使用它。相反,您需要使用以下之一:#选项1流= open(filepath,'r') try: content = stream.read()最后: stream.close() #选项2加上open(filepath,'r')作为流: content = stream.read()exit(1)的粉丝。Python有相当好的错误,虽然它们可能更多地针对开发人员,但它们也可以提供给最终用户。但最糟糕的是,如果以后要调试为什么会出现错误,则必须手动更改程序中的每个exit(1),以获得有用的堆栈跟踪。相反,只需包装您的主,打印错误,然后exit。try: main(),除了异常e: print(str(e))引发SystemExit(1)总之,我会用这样的方法:
import argparse
import getpass
import simplecrypt
def main(args):
if args.decrypt and not args.filepath.endswith('.enc'):
raise ValueError('Expected .enc format file to decrypt.')
with open(args.filepath, 'r') as stream:
file_content = stream.read()
password = getpass.getpass('Password: ')
if args.encrypt:
file_path = args.filepath + '.enc'
content = simplecrypt.encrypt(password, file_content)
else:
file_path = args.filepath[:-4]
content = simplecrypt.decrypt(password, file_content)
with open(file_path, 'w') as write_stream:
write_stream.write(content)
if args.cleanup:
os.remove(args.filepath)
def make_parser():
parser = argparse.ArgumentParser(prog='encryptor')
parser.add_argument('file_path', type=str,
help='Path to file to encrypt or decrypt.')
parser.add_argument('-c', '--cleanup', action='store_false',
help='Stop program cleanup.')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-d', '--decrypt', action='store_true',
help='Specify program should run in decrypt mode.')
group.add_argument('-e', '--encrypt', action='store_true',
help='Specify program should run in encrypt mode.')
return parser
if __name__ == '__main__':
args = make_parser().parse_args()
try:
main(args)
except Exception as e:
print(str(e))
exit(1)发布于 2017-08-10 01:38:26
如果您使用析解析解析破解argv,您将享受到一些好处,包括免费获得帮助。
定义read & WRITE_MODE可能有点过头了,因为open(f, 'w')是一个标准成语。无论如何,如果您愿意的话,您有机会让with为您关闭文件。例如:
with open(filepath + ".enc", "wb") as write_stream:
write_stream.write(encrypted_content)您可能需要二元模式:"wb“而不是"w”。
考虑抛出一个异常来代替调用exit(1)。
对于filepath[-4:0] == ".enc"执行测试,您可以编写:filepath.endswith(".enc")。
这里有一个幻数,对应于len(".enc"):filepath[:-4]。考虑更改强制测试,使其使用regex,re.compile(r'^(.+)\.enc$')。然后,在指定文件路径时,可以使用match对象的组(1)。
ioError标识符(或根据PEP8)的io_error是准确的,但可能长一点-- err就足够了。最好使用“as”关键字:
except IOError as err:https://codereview.stackexchange.com/questions/172517
复制相似问题