admin管理员组文章数量:1650775
Python是一门解释型语言,当我们想让其他人运行我们的代码时,如果直接将.py源代码发送给他人,那么源代码将没有任何安全性可言,也就是任何一个人都可以打开源代码一看究竟,任何人都可以随意修改源代码。因此当我们想保护我们的源代码(算法保护)或者防止用户篡改源代码时,可以将Python源代码编译生成.pyd库文件或者.so库文件(Windows平台生成pyd文件,Linux生成so文件)。
事实上,只是我们表面上看Python是直接解释源代码,而实际上python解释器只会加载字节码。当我们import某个模块时,总是会在模块所在的目录创建一个__pycache__目录,里面存放着被加载模块的字节码文件。
Python有以下几种类型的文件:
- py:Python控制台程序的源代码文件
- pyw:Python带用户界面的源代码文件
- pyx:Python包源文件
- pyc:Python字节码文件(可通过逆向编译来得到源码)
- pyo:Python优化后的字节码文件(可通过逆向编译来得到源码)
- pyd:在Windows平台上Python的库文件(Python版DLL)
- so:在Linux平台上是so文件
加密单个文件
编写setup.py文件
from setuptools import setup # 可以使用setuptools中的setup
# from distutils.core import setup # 也可以使用distutils.core中的setup
from Cython.Build import cythonize
setup(ext_modules = cythonize(["model_extract.py"]), script_args=['build_ext', '--inplace'])
命令行运行文件,会在文件目录下生成.so或.pyd加密文件
python setup.py build_ext --inplace
加密整个项目
实际上setup中可以配置很多参数,进而可以满足我们对整个项目轻松进行加密。
import shutil
import os
from setuptools import setup
# from distutils.core import setup
from distutils.extension import Extension
from distutilsmand.clean import clean
from Cython.Distutils import build_ext
MODULE_NAME = "mytest" # 给项目名字
SRC_DIR = "src" # 要加密代码的目录,个人倾向于把源码统一放在src文件夹下
IGNORE_FILES = ["__init__.py"] # 一般不对该文件加密
# 对src文件夹下文件进行遍历,找到以py结尾的文件
def traverse_path(dir, files=None, folders=None, extension_list=('py',)):
if folders is None:
folders = []
if files is None:
files = []
folders.append(dir)
for file in os.listdir(dir):
path = os.path.join(dir, file)
if os.path.isfile(path):
if '.' in path:
_, extension = path.rsplit('.', 1)
if extension.lower() in extension_list and file not in IGNORE_FILES:
files.append(path)
elif os.path.isdir(path):
traverse_path(path, files, folders, extension_list)
# ex_files参数可以支持不在src文件夹下的文件进行加密
def get_extensions(ex_files = []):
py_files = ex_files
traverse_path(SRC_DIR, files=py_files) # traverse_path函数对py_files进行更新
ext_names = map(lambda x: x.replace(os.path.sep, '.')[:-3], py_files)
def make_extension(ext_name):
ext_path = ext_name.replace('.', os.path.sep) + '.py'
return Extension(ext_name, [ext_path], include_dirs=['.'])
extensions = map(lambda x: make_extension(x), ext_names)
return list(extensions)
# ex_folders参数可以支持不在src文件夹下的文件进行加密
def get_packages(ex_folders = []):
folders = ex_folders
traverse_path(SRC_DIR, folders=folders) # traverse_path对folders进行更新
packages = map(lambda x: x.replace('/', '.'), folders)
return list(packages)
# 对加密后的py,pyc和c文件进行清除
class CleanCode(object):
def clean_build(self, distribution):
clean_command = clean(distribution)
clean_command.all = True
clean_command.finalize_options()
clean_command.run()
def delete_source_code(self, target_dir):
source_file_list = []
traverse_path(target_dir, files=source_file_list, extension_list=('py', 'pyc', 'c'))
for source_file in source_file_list:
if os.path.basename(source_file) not in IGNORE_FILES:
os.remove(source_file)
def copy_so(self, build_path, source_code_path):
self._copy_so(build_path, build_path, source_code_path)
def _copy_so(self, target_dir, build_base_dir, target_base_dir):
for file in os.listdir(target_dir):
path = os.path.join(target_dir, file)
if os.path.isfile(path) and path.endswith('.so'):
new_path = path.replace(build_base_dir, target_base_dir)
shutil.copyfile(path, new_path)
elif os.path.isdir(path):
self._copy_so(path, build_base_dir, target_base_dir)
# 继承Cython的build_ext类
class CustomBuildExt(build_ext, CleanCode):
def run(self):
build_ext.run(self)
source_code_path = SRC_DIR
build_path = os.path.join(self.build_lib, SRC_DIR)
self.copy_so(build_path, source_code_path)
self.clean_build(self.distribution)
self.delete_source_code(source_code_path)
ext_modules = get_extensions()
setup(
name=MODULE_NAME,
packages=get_packages(),
ext_modules=ext_modules,
cmdclass={'build_ext': CustomBuildExt} # 自定义的CustomBuildExt
)
项目中用因为用到了Extension类,可能需要在ext_modules那一行后面加上下面这个代码:
ext_modules = get_extensions()
for e in ext_modules:
e.cython_directives = {'language_level': "3"}
具体参考example
版权声明:本文标题:利用Cython加密文件和项目 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/xitong/1729527202a1204711.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论