1. 前言
众多周知,由于 Python 的动态特性和开源特点,导致 Python 代码很难做到很好的加密,从而在项目开发,尤其是项目支付过程中,Python代码的加密问题一直是急需解决的问题。本文针对以Python2.7为基础介绍一款代码加密工具-cython
,利用cython
将Python代码打包为二进制动态理解库。
2. Cython简介
- Cython语言使得Python语言的C扩展与Python本身一样简单。
- Cython是基于Pyrx的源代码转换器,但支持更多的边缘功能和优化。
- Cython语言是Python语言的一个超集(几乎所有的Python代码是有效的,但Cython Cython代码)还支持可选的静态类型来调用C函数,使用C++类和声明快C类型变量和类的属性。这允许编译器从Cython代码生成非常高效的C代码。这使得Cython编写外部C / C++库代码的理想语言,和快速的C模块,提高Python代码的执行速度。
- Cython是一个针对Python编程语言和扩展的Cython编程语言(基于Pyrex)的优化静态编译器。它使得为Python编写C扩展像编写Python本身一样简单
3. Cython安装
pip install Cython
4. 实践
4.1 第一种方法
- 执行命令:
cython test.py
- 结果:会在同一目录下面生成test.c文件
- 执行命令:
gcc -c -fPIC -I /usr/include/python2.7 test.c
- 结果: 在同一目录下面生成test.o文件
- 执行命令:
gcc -shared test.o -c test.so
- 结果: 在同一目录下面生成test.so文件
最后,生成的test.so文件就是需要的文件
4.2 第二种方法
编写打包脚本如下:
[setup.py]
from distutils.core import setup
from Cython.Build import cythonize
setup(
name = "test",
ext_modules = cythonize("test.py")
)
- 执行命令:
python setup.py build_ext --inplace
但是,这种办法是对单独文件进行编译,下面介绍一种批量的办法,编写脚本如下:
#-*- coding:utf-8 -*-_
import os
import re
from distutils.core import Extension, setup
from Cython.Build import cythonize
from Cython.Compiler import Options
# __file__ 含有魔术变量的应当排除,Cython虽有个编译参数,但只能设置静态。
exclude_so = ['__init__.py', 'run.py']
sources = 'backend'
extensions = []
remove_files = []
for source,dirnames,files in os.walk(sources):
for dirpath, foldernames, filenames in os.walk(source):
if 'test' in dirpath:
break;
for filename in filter(lambda x: re.match(r'.*[.]py$', x), filenames):
file_path = os.path.join(dirpath, filename)
if filename not in exclude_so:
extensions.append(
Extension(file_path[:-3].replace('/', '.'), [file_path], extra_compile_args = ["-Os", "-g0"],
extra_link_args = ["-Wl,--strip-all"]))
remove_files.append(file_path[:-3]+'.py')
remove_files.append(file_path[:-3]+'.pyc')
Options.docstrings = False
compiler_directives = {'optimize.unpack_method_calls': False, 'always_allow_keywords': True}
setup(
# cythonize的exclude全路径匹配,不灵活,不如在上一步排除。
ext_modules = cythonize(extensions, exclude = None, nthreads = 20, quiet = True, build_dir = './build',
language_level = 2, compiler_directives = compiler_directives))
# 删除py和pyc文件
for remove_file in remove_files:
if os.path.exists(remove_file):
os.remove(remove_file)
- 执行命令:
python setup.py build_ext --inplace
- 结果:最后生成.so文件,删除中间结果。
5. 后记
cython除了可以将python代码加密成二进制动态链接库之外,还能够提高代码的执行效率,不过需要在代码中使用cython来进行编写,有兴趣的同学可以参看cython官方文档。
愿与大家共同进步!