首页 > 编程语言 >Python工具箱系列(十三)

Python工具箱系列(十三)

时间:2022-11-08 15:55:05浏览次数:46  
标签:__ 文件 docx Python filename 十三 import python 工具箱

上文介绍了使用AES算法进行文件加解密的代码。但是如果在代码中写死了(hardcode)文件名,每次要加解密文件都要去改python源代码,显然有些太笨了。为此,可以使用命令行参数来在不改动源代码的情况下,对命令行参数所指定的文件进行加/解密操作。也可以指定加解密后输出的文件名称,以方便使用。

我们如下约定:

  • python文件名为aeshandler.py
  • -i,表示输入文件名
  • -o,表示输出文件名
  • -e,表示加密
  • -d,表示解密

使用python经典的命令行框架argparse,它是python标准库的一部分,也就是说安装好python3.8就自带这个框架,不需要再安装什么。程序员经常说:talk is cheap,show me your code。所以将代码如下所示。

import argparse
import os
import struct
import sys
from pathlib import Path

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad

__authors__ = 'tianbin'
__version__ = 'version 0.9'
__license__ = 'free'

defaultsize = 64*1024


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)


if __name__ == '__main__':
    
    # 密钥随便写,使用时只使用前16字节
    key = 'stayhungrystayfoolish'
    realkey = key[:16].encode('utf-8')

    def parser():
        """
        分析用户命令行
        """
        parser = argparse.ArgumentParser()
        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="要处理的文件")
        parser.add_argument("-o", "--output", type=str,
                            help="要输出的文件")

        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}不存在')

    parser()

命令执行的效果如下:

# 以下命令显示帮助信息
python .\aeshandler.py                         
usage: aeshandler.py [-h] [-d] [-e] [-i INPUT] [-o OUTPUT]

optional arguments:
  -h, --help            show this help message and exit
  -d, --decry           解密模式
  -e, --encry           加密模式
  -i INPUT, --input INPUT
                        要处理的文件
  -o OUTPUT, --output OUTPUT
                        要输出的文件

# 以下命令加密指定的文件,加密后的文件为test1.docx
python .\aeshandler.py -e -i ../resources/神龟虽寿.docx -o test1.docx
Namespace(decry=False, encry=True, input='../resources/神龟虽寿.docx', output='test1.docx')

# 以下命令解密指定的文件,要解密的文件为test1.docx,解密后的文件为test2.docx
python .\aeshandler.py -d -i test1.docx -o test2.docx                
Namespace(decry=True, encry=False, input='test1.docx', output='test2.docx')

通过命令行参数的使用,可以为用户提供了最大的灵活性。通过命令行,再结合SHELL脚本等,可以批量处理大量的文件、目录,因此命令行仍然是专家、高手的最爱。

标签:__,文件,docx,Python,filename,十三,import,python,工具箱
From: https://www.cnblogs.com/shanxihualu/p/16869984.html

相关文章

  • python 检索网络
    importrequests,datetime,re,psutilimportscapy_http.httpashttpfromscapy.allimport*fromlxmlimportetreeimportwarningswarnings.filterwarnings("igno......
  • python 函数装饰器
    #函数传入的参数可以是函数deffunc1():print('1')deffunc2(func):#func为函数func()print('2')func2(func1)#12 deffunc1(func):......
  • Python2调用xlwt库的报错:“UnicodeDecodeError: 'ascii' codec can't decode byte 0xe
    问题描述:Python2调用xlwt库的报错,报错提示“UnicodeDecodeError:'ascii'codeccan'tdecodebyte0xe5inposition0:ordinalnotinrange(128)”编码问题。 ......
  • python第三十课---面向对象的魔法方法,元类相关知识
    昨日内容回顾派生方法实战案例1.继承某个类2.重写被继承类里面的某个方法3.在方法内添加一些额外的操作4.最后利用super重新调用被继承类里面的方法"""super:子类......
  • 重温Python基础——操作列表
    哈喽兄弟们,今天咱们来复习一下Python基础中的列表操作,不知道各位还记得多少呢?遍历整个列表加粗样式遍历列表的所有元素,对每一个元素进行相同的操作,是我们常常所需要......
  • 使用python绘制折线图
    一、基础命令 在我们使用深度学习时,肯定会用到绘图命令,绘制loss与val_loss等等,以此查看模型的效果。plt.plot(x,y,lw=,ls=,c=,alpha=,label=)x:x坐标的数据y:y坐标......
  • 解决python脚本运行后产生的 xx object has no attribute '***'的问题
     在调试自动化脚本时,总是出现某代码执行第一次没有问题,执行第二次时会出现 xxobjecthasnoattribute '***'的问题,如图:  百度之后得到两种解释:第一种是因为自......
  • python PDF转图片
    pythonPDF转图片准备工作下载模块pdf2imagepipinstallpdf2image下载依赖(不下载会报错)Macbrewinstallpoppler代码实现frompdf2imageimportconvert_......
  • 【转载】Python格式化4种方式
    Python格式化字符串的4种方式一:%号    %号格式化字符串的方式从Python诞生之初就已经存在时至今日,python官方也并未弃用%号,但也并不推荐这种格式化方式。 #1、格......
  • 流畅的python_不要使用可变类型作为参数默认值
    可变参数作为对象的默认值的时候创建不同的对象(均为默认值)的时候,默认值会具有相同的引用deff(a=[]):a.append(1)returnaprint(f())print(f())print......