Python脚本实现异或方法加密和解密文本文件,通过Cython编译为so文件加密Python脚本
文本加密和解密 异或是一种简单的加密算法,根据异或的运算规则,通过密钥对明文信息进行异或运算,可以得到加密后的密文信息。 同时由于异或运算的可逆性,用同一密钥对密文信息再次进行异或运算,可以得到明文信息。
Python实现 以下是对文本文件异或加密及解密的Python实现,Encrypt_Decrypt_Text.py。 此脚本里设定的字符编码是UTF-8,可以按需修改。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 # Python # Encrypt or decrypt text file with a password # coding=utf-8 import os import sys EncodeSet = "UTF-8" def encrypt(String, Password, Seed): if (len(Password) == 0): sys.stderr.write("Password can't be empty. Exit.") exit() Key_Int = ord(Password[Seed % len(Password)]) String_Byte = String.encode(EncodeSet) String_Int = int.from_bytes(String_Byte, 'big') String_Encrypt = String_Int ^ Key_Int return String_Encrypt def decrypt(String, Password, Seed): if (len(Password) == 0): sys.stderr.write("Password can't be empty. Exit.") exit() Key_Int = ord(Password[Seed % len(Password)]) String_Decrypt = String ^ Key_Int Length = (String_Decrypt.bit_length() + 7) // 8 Decrypt_Byte = int.to_bytes(String_Decrypt, Length, 'big') Decrypt = Decrypt_Byte.decode(EncodeSet) return Decrypt def encrypt_file(Input, Password): Input = os.path.abspath(Input) Encrypt_Output_File = Input + ".encrypt" Input_File = open(Input, "rt", encoding = EncodeSet) Output_File = open(Encrypt_Output_File, "wt", encoding = EncodeSet) Counter = 0 for Line in Input_File: Counter = Counter + 1 Line = Line.strip("\r").strip("\n") for Word in Line: Word_Encrypt = encrypt(Word, Password, Counter) Output_File.write(str(Word_Encrypt) + " ") Output_File.write("\n") Input_File.close() Output_File.close() return Encrypt_Output_File def decrypt_file(Input, Password): Input = os.path.abspath(Input) Decrypt_String = "" Input_File = open(Input, "rt", encoding = EncodeSet) Counter = 0 for Line in Input_File: Counter = Counter + 1 Line = Line.strip("\r").strip("\n") Line = Line.strip(" ") for Word in Line.split(" "): Word_Decrypt = decrypt(int(Word), Password, Counter) Decrypt_String = Decrypt_String + Word_Decrypt Decrypt_String = Decrypt_String + "\n" Input_File.close() Decrypt_String = Decrypt_String.strip("\r").strip("\n") return Decrypt_String
使用示例 加密 以下是加密脚本示例,Encrypt.py。 encrypt_file函数返回的是加密文件路径,路径是[原文件路径].encrypt。
1 2 3 4 5 6 7 8 9 10 11 12 # Python # -*- coding:utf-8 -*- import Encrypt_Decrypt_Text import sys Input = sys.argv[1] Password = sys.argv[2] Encrypt_File_Path = Encrypt_Decrypt_Text.encrypt_file(Input, Password) print(Encrypt_File_Path)
解密 以下是解密脚本示例,Decrypt.py。 函数返回解密后的字符串,建议在脚本中解密后直接调用字符串,不要重新保存成文件。 假如密码错误,会报错或返回乱码。
1 2 3 4 5 6 7 8 9 10 11 12 # Python # -*- coding:utf-8 -*- import Encrypt_Decrypt_Text import sys Input = sys.argv[1] Password = sys.argv[2] Decrype_File_Content = Encrypt_Decrypt_Text.decrypt_file(Input, Password) print(Decrype_File_Content)
脚本加密 用于文本文件加密的密钥,如果以明文方式写在脚本里等于没有加密。 所以需要对调用解密过程的python脚本再通过Cython加密,那么脚本里密钥的也加密了。
安装Cython 1 2 # Python python -m pip install Cython
Cython脚本 以下是将python脚本编译为so文件的脚本,Cpython_so.py。 以下脚本会生成so文件和清理中间文件,调用此脚本方法见”调用Cython脚本”部分。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 # Python import sys import os import re import argparse ############################################################## Help ############################################################# parser=argparse.ArgumentParser( description="Description: Generate .so from .py. Version of .so is base of python version.", prog="Cpython_so.py", usage="python Cpython_so.py [-h] [-V] -i <python script> -o <Output Dir>", formatter_class=argparse.RawTextHelpFormatter ) parser.add_argument('-V','--version',action="version",version="Version 1.0.0") parser.add_argument('-i','--input',required=True,type=str,help="File: python script") parser.add_argument('-o','--output_dir',required=True,type=str,help="Dir: Output directory path") if len(sys.argv[1:]) == 0: parser.print_help() parser.exit() args=parser.parse_args() ############################################################## Run ############################################################## Input_Dir = os.path.dirname(os.path.abspath(args.input)) Output_Dir = os.path.abspath(args.output_dir) if (Input_Dir == Output_Dir): sys.stderr.write("Output directory can't be same as python script. Exit.\n") exit(1) if not (os.path.exists(args.output_dir)): os.mkdir(args.output_dir) Module = re.sub(".py$", "", os.path.basename(args.input)) # Copy Original Script To Work Dir Py_Script = os.path.abspath(args.output_dir) + "/" + os.path.basename(args.input) Command_Cp = "cp " + args.input + " " + Py_Script os.system(Command_Cp) # Generate .so From .py Cpython_Script = os.path.abspath(args.output_dir) + "/Cpython_Setup.py" Cpython_Script_File = open(Cpython_Script, "w") Cpython_Script_File.write("from distutils.core import setup" + "\n") Cpython_Script_File.write("from Cython.Build import cythonize" + "\n") Cpython_Script_File.write("" + "\n") Cpython_Script_File.write("setup(ext_modules = cythonize(\"" + Py_Script + "\"))" + "\n") Cpython_Script_File.write("" + "\n") Cpython_Script_File.close() Py_Version = "python" + ".".join([str(sys.version_info[0]),str(sys.version_info[1])]) Command_Cpython = Py_Version + " " + Cpython_Script + " build_ext --inplace" os.system(Command_Cpython) # Move Result .so And Clean Temp Dir So_File = os.getcwd() + "/" + Module + "*.so" C_File = os.path.abspath(args.output_dir) + "/" + Module + ".c" Temp_Dir = os.getcwd() + "/" + "build" Command_Move = "mv " + So_File + " " + os.path.abspath(args.output_dir) os.system(Command_Move) Commad_Clean = "rm -rf " + " ".join([Py_Script, Cpython_Script, Temp_Dir, C_File]) os.system(Commad_Clean) # Generate .py And .sh To Run .so So_Py_Script = os.path.abspath(args.output_dir) + "/" + Module + ".py" So_Sh_Script = os.path.abspath(args.output_dir) + "/" + Module + ".sh" So_Py_Script_File = open(So_Py_Script, "w") So_Py_Script_File.write("import " + Module + "\n\n") So_Py_Script_File.close() So_Sh_Script_File = open(So_Sh_Script, "w") So_Sh_Script_File.write(Py_Version + " " + So_Py_Script + "\n") So_Sh_Script_File.close() Command_Chmod = "chmod +x " + So_Py_Script + " " + So_Sh_Script os.system(Command_Chmod)
调用Cython脚本 可以写个shell调用,也可以直接命令行调用。 -i 是待加密的python脚本路径,-o 是加密后脚本的输出目录路径。 不同Python版本加密生成的so文件不一定通用,加密前脚本用哪个Python版本调用,就用哪个版本调用Cython脚本。 加密后的.so文件可以作为模块调用,使用方法可参考输出目录生成的.sh文件。
1 2 3 4 5 6 7 # Shell # 系统默认的Python版本 python Cpython_so.py -i ../../Cpython_Setup/Step1_Python_To_so/Store_Tumor_Report.py -o ./Test_2.7 # 指定用Python 3.6版本 python3.6 Cpython_so.py -i ../../Cpython_Setup/Step1_Python_To_so/Store_Tumor_Report.py -o ./Test_3.6
参考资料
异或加密(XOR)原理及实现
Python 循环异或对文件进行加解密
Python程序加密-cython