Python的脚本文件是开源的,量化策略的安全性没有保障。因此需要保护源码。那么要对Python代码进行混淆、加密保护。
混淆代码,我准备使用pyminifier。而加密处理,就比较麻烦。
Python有py、pyc、pyw、pyo、pyd等文件格式。
其中,pyc是二进制文件。但很容易被反编译。
pyw也不行,只是隐藏命令行界面而已,可以作为入口脚本。
pyo和pyc差不多,也容易被反编译。
最后剩下pyd格式。pyd格式是D语言(C/C++综合进化版本)生成的二进制文件,实际也会是dll文件。该文件目前位置没找到可以被反编译的消息,只能被反汇编。Sublime text编辑器也是使用该格式。
Python有以下几种类型的文件:
- py:Python控制台程序的源代码文件
- pyw:Python带用户界面的源代码文件
- pyx:Python包源文件
- pyc:Python字节码文件(可通过逆向编译来得到源码)
- pyo:Python优化后的字节码文件(可通过逆向编译来得到源码)
- pyd:在Windows平台上Python的库文件(Python版DLL)
- so:在Linux平台上是so文件
Python的py文件生成pyd文件步骤如下。
1、安装Cython
可以使用pip命令安装Cython。
- pip install cython
2、处理vcvarsall.bat
若不处理,可能会出现“Unable to find vcvarsall.bat”错误。
安装Cython之后,还需要指定vcvarsall.bat的位置。
vcvarsall.bat是VC编译Python环境的文件之一。而vcvarsall.bat需要安装VC For Python2.7。我的Python是2.7,刚好可以使用这个。至于3.x版本不知道微软更新了没有。
下载地址:VCForPython27.msi
安装成功之后,再修改设置。让Cython可以找到vcarsall.bat。此处有两种方案。
方案2:修改注册表
我采用方案1,亲测可用。方案2未测试,看似可用。
3、创建工作目录并生成pyd文件
这里有一个坑。程序所在的目录路径不能包含中文文字。所以我在E盘下创建一个test文件夹,用于放置要处理的python文件。
简单写了一个测试文件(命名为test.py):
#coding:utf-8
def hello():
print("Hello world")
input("<press ENTER to quit>")
在该目录下,再新建一个py文件(命名为setup.py):
from distutils.core import setup
from Cython.Build import cythonize
setup(
name = 'Hello world app',
ext_modules = cythonize("test.py"),
)
或者代码(文件名test_2.py):
# -*- coding: utf-8 -*
from distutils.core import setup
from Cython.Build import cythonize
def py2c(file):
# 返回distutils.extension.Extension对象列表
cpy = cythonize(file)
setup(
name = 'pyd的编译', # 包名称
version = "1.0", # 包版本号
ext_modules= cpy, # 扩展模块
author = "zc",#作者
author_email='xxx@xxx.com' #作者邮箱
)
if __name__ == '__main__':
file = "test.py"
py2c(file)
接着,再打开cmd,跳到该目录并执行如下命令:
python setup.py build_ext --inplace
# 或者
python setup_2.py build_ext --inplace
最终生成pyd文件
其中,build是生成过程使用到的临时文件。test.c也是临时文件,可以打开看看传说中的D语言代码。
test.pyd是我们所需的文件。
pyd文件可以像平常一样使用import引入模块的方式正常使用。
后来,我尝试使用py2exe打包pyd文件。还需要创建一个入口脚本(命名为index.py):
import test
if __name__=="__main__":
test.hello()
为了方便打包,我重新创建一个目录。把index.py和test.pyd复制到该目录。
如何安装和使用py2exe这里我就不说了,自行百度一下。
分别用test.pyd和未处理的test.py打包效果如下:
1)用test.pyd
直接可以在index.exe对应的位置找到该文件。
2)用test.py
在该目录下没有test.py文件。该文件在library.zip中。
测试结果,用py2exe可以正常使用pyd文件。
ps:若用Cython出现如下错误,说明文件的编号和python脚本设置 #coding设置的编码不一致。保存一致编码即可解决该问题。
Decoding error, missing or incorrect coding=<encoding-name> at top of source (cannot decode with encoding 'utf8': invalid start byte)