上文介绍了命令行方式来对文件进行加解密操作。本文将继续在此基础上,实现一个快速简易的GUI界面方便操作,先上代码看效果。

import argparse
import configparser
import json
import os
import struct
import sys
from configparser import ConfigParser
from pathlib import Path
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from gooey import Gooey, GooeyParser
from matplotlib import widgets
defaultsize = 64*1024
# 密钥随便写,使用时只使用前16字节
key = 'stayhungrystayfoolish'
realkey = key[:16].encode('utf-8')
def encrypt_file(key, in_filename, out_filename=None, chunksize=defaultsize):
    """
    对文件进行加密
    Args:
        key (str): 16字节密钥
        in_filename (str): 待加密文件
        out_filename (str, optional): 加密后输出的文件
        chunksize (int, optional): 块大小,缺省64k
    """
    if not out_filename:
        out_filename = in_filename + '.enc'
    iv = os.urandom(16)
    encryptor = AES.new(key, AES.MODE_CBC, iv)
    filesize = os.path.getsize(in_filename)
    with open(in_filename, 'rb') as infile:
        with open(out_filename, 'wb') as outfile:
            outfile.write(struct.pack('<Q', filesize))
            outfile.write(iv)
            pos = 0
            while pos < filesize:
                chunk = infile.read(chunksize)
                pos += len(chunk)
                if pos == filesize:
                    chunk = pad(chunk, AES.block_size)
                outfile.write(encryptor.encrypt(chunk))
def decrypt_file(key, in_filename, out_filename=None, chunksize=defaultsize):
    """
    解密文件
    Args:
        key (str): 16字节密钥
        in_filename (str): 待解密文件
        out_filename (str, optional): 解密后输出的文件
        chunksize (int, optional): 块大小,缺省64K
    """
    if not out_filename:
        out_filename = in_filename + '.dec'
    with open(in_filename, 'rb') as infile:
        filesize = struct.unpack('<Q', infile.read(8))[0]
        iv = infile.read(16)
        encryptor = AES.new(key, AES.MODE_CBC, iv)
        with open(out_filename, 'wb') as outfile:
            encrypted_filesize = os.path.getsize(in_filename)
            pos = 8 + 16  # the filesize and IV.
            while pos < encrypted_filesize:
                chunk = infile.read(chunksize)
                pos += len(chunk)
                chunk = encryptor.decrypt(chunk)
                if pos == encrypted_filesize:
                    chunk = unpad(chunk, AES.block_size)
                outfile.write(chunk)
@Gooey(language='chinese')
def parse():
    parser = GooeyParser(description=u'aes handler')
    parser.add_argument("-d", "--decry", action="store_true",
                        help="解密模式")
    parser.add_argument("-e", "--encry", action="store_true",
                        help="加密模式")
    parser.add_argument("-i", "--input", type=str,
                        help="要处理的文件", widget='FileChooser')
    parser.add_argument("-o", "--output", type=str,
                        help="要输出的文件", widget='FileSaver')
    args = parser.parse_args()
    print(args)
    # 判断参数输入情况,如果没有参数,则显示帮助。
    if len(sys.argv) == 1:
        parser.print_help()
        return
    # 解密模式,获得输入与输出文件后,调用算法解密
    if args.decry:
        inputfilename = Path(args.input)
        if inputfilename.exists():
            decrypt_file(realkey, in_filename=args.input,
                         out_filename=args.output)
        else:
            print(f'{args.input}不存在')
    # 加密模式,获得输入与输出文件后,调用算法加密
    if args.encry:
        inputfilename = Path(args.input)
        if inputfilename.exists():
            encrypt_file(realkey, in_filename=args.input,
                         out_filename=args.output)
        else:
            print(f'{args.input}不存在')
parse()

可以看出,基本上代码不用太改,直接就可以升级为GUI应用,确实非常方便,运行效果如下图所示。

Python工具箱系列(十四)

要知道,python的GUI实在是令人感到一言难尽,不仅需要配置的东西很多,而且还经常出现各类错误,根本无法与微软的.Net相比,也无法与B/S架构的前端相比。通常情况下,本系列不再介绍GUI编程方面的知识。但是这个工具包非常简洁明快,推荐使用。windows下使用以下命令完成相关环境准备。

pip install Gooey 

ubuntu 18.04环境有些复杂,建议以下安装步骤。

sudo apt-get install python-wxtools
# method1
apt-get install pkg-config
# method2
wget http://launchpadlibrarian.net/477064124/pkg-config_0.29.2-1ubuntu1_amd64.deb
dpkg -i pkg-config_0.29.2-1ubuntu1_amd64.deb
pkg-config --version
apt-get install -y libgtk-3-dev
# 检验与设置
pkg-config --cflags --libs gtk+-3.0
# 前面全是准备
pip install wxpython
pip install matplotlib
pip install gooey

安装成功后,也可以获得与windows下类似的界面。