一、前言
- 我有个python脚本每天要定时运行,
- 脚本别人也能看到代码的内容,
- 但是脚本里涉及到了重要数据库和网站的账密,
- 如果打包成exe,体积和效率和稳定性都不理想,
- 怎么办!!!
- 神器 pyarmor 基于源代码的加密,让你的脚本即便裸奔也足够安全
二、准备必要的库
- 安装python(废话...)
- 安装pyarmor库
$ pip install pyarmor
安装完成,红色的部分不用管,这是因为我之前就安装过旧版本的pyarmor-webui ,卸载重装作为演示,报出新老版本不兼容了,不用管。
* 3.安装shutil库,这个是复制文件夹的库,需要备份就必须要安装了
$ pip install shutilwhich
三、打包单个python文件
比如有个main.py在【D:\DEMO】中,内容为:
# main.py
print('这是一个被加密的文件')
调出控制台,cd到文件位置,输入
$ pyarmor gen main.py
此时,D:\DEMO中将会生成dist文件夹,里面有两个文件:
看下此时的main.py内容:
已经是被加密过了,加密过的文件可以直接运行,效果不变:
pyarmor厉害的一点在于,不仅仅是源代码是被加密的,连运行的过程都是被加密的,对于95%的人来说已经足够安全了吧。现在可以把dist里面的所有文件(包括pyarmor_runtime_000000)拷贝给任何人了,只要对方的环境可以正常运行未加密的,那他就一定可以运行这份加密的,对方不需要安装pyarmor。
四、打包整个python项目
准备两个文件,其一是你的python代码(或者一整个项目文件夹),其二是我下面的python脚本。
我做了一个项目包,第一个是mypkg文件夹,里面有pkg1.py这个文件,文件内容是:
# mypkg -> pkg1.py
def run():
print('这里有很重要的密码!!')
另一个就是main.py
# main.py
from mypkg.pkg1 import run
if __name__ == '__main__':
run()
结构就是这样的
运行main.py,执行结果是
这里有很重要的密码!!
以上都只是是模拟大多数情况下的python项目文件,期望得到的效果是mypkg里面的所有内容全部加密,而外层的main.py是不加密的。
在main.py文件同目录下,新建一个比如名为"run_pyarmor.py"的文件,内容为:
# coding=utf-8
# @author:JW-Panda
import os
import time
import shutil
p1 = os.getcwd()
p2 = os.path.join(p1, 'dist')
p3 = os.path.join(p1, 'mypkg')
print(f'path1: {p1}\npath2: {p2}\npath3: {p3}')
def bak_unlock(n):
"""
自动备份未加密的文件
:param n: 最大保留数量,超出则删除最旧的文件
:return:
"""
bak_unlocked_address = os.path.join(p1, 'bak_unlocked')
if not os.path.exists(bak_unlocked_address):
os.mkdir(bak_unlocked_address)
new_path = os.path.join(bak_unlocked_address, time.strftime('%Y%m%d—%H%M%S', time.localtime(time.time())))
print('new_path: ', new_path)
n2 = os.path.join(new_path, 'mypkg')
os.mkdir(new_path)
os.mkdir(n2)
b_path = os.path.join(p1, 'bak_unlocked')
print(b_path)
l_dir = sorted(os.listdir(b_path))
if len(l_dir) > n:
need_del = l_dir[:len(l_dir) - n]
print('超出最大文件夹备份需要删除的:', need_del)
for i in need_del:
f = os.path.join(b_path, i)
shutil.rmtree(f)
print(f, ' 已删除')
for i in unlock_filelist:
shutil.copyfile(i, os.path.join(new_path, i))
for i in os.listdir(p3):
if i == '__pycache__':
continue
n1 = os.path.join(p3, i)
shutil.copyfile(n1, os.path.join(n2, i))
def reset_pkg():
if os.path.exists(path=p2):
print('移除旧文件')
shutil.rmtree(p2)
s = f"""d:
cd {p1}
pyarmor gen -O dist {p3}
echo 打包已完成!
start {p2}"""
# print(s)
with open('加密打包.bat', 'w', encoding='gbk') as f:
f.write(s)
os.system('加密打包.bat')
for i in unlock_filelist:
shutil.copyfile(i, 'dist/' + str(i))
if __name__ == '__main__':
unlock_filelist = ['main.py'] # 将外层不需要加密的文件名写在列表里
bak_unlock(10) # 设定最大自动备份数量
reset_pkg()
执行结果:
运行结束之后会自动弹出被加密的项目所有内容:
同时会在相同目录下生成自动备份的文件夹,具体如下图所示:
五、小结
关于pyarmor其实还有更加高级的用法,比如可以绑定目标设备的CPU序列号,拷贝到其他地方就不能用了;比如可以设置授权时效,超出时效就不能用了;比如可以同时对打包成exe的文件进行加密;比如可以根据优先效率还是优先加密难度进行不同的模式加密,具体大家可以到官网:Pyarmor - 加密 Python 脚本 (dashingsoft.com)查看更为详细的技术文档。
最后,这个库只要加密的整体文件在32M以内就是免费的,专业版收费,但基础版已经能够满足大多数独立开发者的使用场景了,快来试试吧!