文章目录
- 1. 引言
- 2. py文件编译为pyd文件步骤
- 2.1 环境准备
- 2.2 准备setup.py文件
- 2.3 进行编译
- 3. 测试代码
1. 引言
在实际的Python开发中,为了防止Python脚本源码暴露,常常需要对python源码文件进行加密保护,Python的原始文件格式为.py
,可以通过编译生成 .pyc
/.pyo
/.pyd
等类型的文件,其中,.pyc
/.pyo
是python字节码文件,但由一些较低版本的解释器编译的字节码可以通过 uncompyle6 库进行反编译,而 .pyd
是 windows 平台上的 python 动态链接库文件,通常包含了编译后的二进制代码,相比于 .pyc
文件更难反编译,因为其中包含的是机器码而不是字节码(可以被反汇编,但难度大)。
因此,接下来我们将介绍如何将.py
文件编译为 .pyd
文件,并通过相应代码演示具体过程。
2. py文件编译为pyd文件步骤
2.1 环境准备
编译为 .pyd
文件需要用到 Cython 库,且由于 Cython 编译器需要使用 C/C++ 编译器来将 Cython 代码编译成动态链接库文件,因此还需要在环境中准备 C/C++ 编译器。
- 安装 Cython:通过
pip install cython
即可实现安装; - 安装 C/C++ 编译器:Microsoft C++ 生成工具是 Windows 平台上常用的 C/C++ 编译器之一,也是Visual Studio的一部分,因此通常通过安装 Visual Studio 来实现安装(下载地址)。
2.2 准备setup.py文件
假设现有一个待加密的名为 example.py
的文件,文件内容如下:
import numpy as npdef cal(array_):print("Mean of array: ", np.mean(array_))print("Median of array: ", np.median(array_))
有待加密文件后,需准备 setup.py
文件,文件内容如下:
from distutils.core import setup
from Cython.Build import cythonizesetup(ext_modules=cythonize(["example.py"]))
其中的 distutils
是 python 的内置库,将待加密文件的文件名如上所示设置即可,如果有多个.py
文件,则将多个文件名用逗号隔开。
2.3 进行编译
打开 cmd 窗口,将当前目录切换到上面提到的 example.py
和 setup.py
的所在目录,执行以下命令:
python setup.py build_ext --inplace
运行时生成的信息,说明加密完成。此时加密得到 example.cp310-win_amd64.pyd
,如果该文件不在当前工作目录中,则到 build 文件的 lib.win-amd64-cpython-310 当中查找。这里的 310 指的是 python 版本为 3.10,之所以有这个版本区别,是要求调用相应 pyd
文件的环境和编译 pyd
的 python 的环境版本要一致。如果在不同环境版本之间编译和调用,可以考虑用环境管理根据:安装conda并搭建python环境(入门教程)
此时将得到的 example.cp310-win_amd64.pyd
文件中的 .cp310-win_amd64
部分删除,得到 example.pyd
,其使用方法与普通的 py
文件一致。
3. 测试代码
上面加密的代码中定义了一个函数,当传入一个数组或者列表后,打印传入数据的平均值,和中位数值。切换到 .pyd
所在的目录下,运行如下测试代码:
import exampleexample.cal([1,5,3,2,0])
打印结果如下:
Mean of array: 2.2
Median of array: 2.0
除了后缀不同,加密后的文件应该与加密前文件名保持一致,否则会在引用时出错,当 example.py
和 example.pyd
同在一个目录下时,上述测试代码中的 import example
会优先引用 .pyd
文件。