使用cython的代码保护方案

简介: 建模开发平台即将推出了镜像构建的功能,以方便用户将开发好的代码迁移至其他环境执行。但在迁移过程中难免会有代码保护的需求,现提供一种基于cython的代码保护方案,能够在一定程度上解决代码保护的问题。

参考文档:

https://cython.org/

https://github.com/cython/cython

https://zhuanlan.zhihu.com/p/54296517


Cython介绍

Cython是一个类似于Python的编程语言,它是基于Python语言的扩展和优化。Cython语言是一种静态类型语言,同时也支持Python的动态类型特性,Cython代码会被转换成C语言代码,再编译成机器码,因此其执行速度比Python要快。

虽然Cython 的主要目的是带来性能的提升,但是基于它的原理:将 .py/.pyx 编译为 .c 文件,再将 .c 文件编译为 .so(Unix) 或 .pyd(Windows),其带来的另一个好处就是难以破解。但需要注意的是,cython本质上并非提供加密功能,而是通过编译成二进制文件后,提高他人阅读核心代码的难度,使用此方法加密代码还要注意代码安全。


方法

1)编写 setup.py:

可根据cython官方文档的指引,对您的代码进行编译。以下代码可供参考:

此脚本将会找到当前目录下所有含__init__.py文件的目录,并对他们进行编译,并在原地生成.so文件。

#encoding=utf-8fromsetuptoolsimportsetup, find_packagesfromsetuptools.extensionimportExtensionfromCython.BuildimportcythonizefromCython.Distutilsimportbuild_extfrompathlibimportPathimportshutilimportsys, os# some global variable, don't change them if you don't know what they meanmy_build_dir="build"classMyBuildExt(build_ext):
defrun(self):
build_ext.run(self)
build_dir=Path(self.build_lib)
root_dir=Path(__file__).parenttarget_dir=build_dirifnotself.inplaceelseroot_dirformoduleinmy_packages:
module=module.replace(".","/")
module_path=Path(module)
print(">>find modeule path:"+str(module_path))
self.copy_file(module_path/'__init__.py', root_dir, target_dir)
self.copy_file(module_path/'__main__.py', root_dir, target_dir)
forpinPath('.').iterdir():
ifp.is_file() andp.suffixnotin [".py", ".pyc"] andp.namenotinexclude_list:
self.copy_file(p, root_dir, target_dir)
print("copy end")
defcopy_file(self, path, source_dir, destination_dir):
ifnot (source_dir/path).exists():
returnshutil.copyfile(str(source_dir/path), str(destination_dir/path))
deffind_scrips():
scrips_list= []
forpinPath('.').iterdir():
ifp.is_file() and (p.namenotinexclude_list):
ifp.suffixin [".py"] and (notp.name.startswith(".")):
scrips_list.append(p.name)
print("find scrips:")
print(scrips_list)
print(exclude_list)
returnscrips_listif__name__=="__main__":
my_project_name="test"my_clang="gcc "ifos.path.isdir(my_build_dir):
print("Exist build dir, auto remove")
shutil.rmtree(my_build_dir)
print("===============start=================")
exclude_list= ["setup.py", ".DS_Store"]
os.environ["CC"]=my_clangmy_packages=find_packages()
print("packages:")
print(my_packages)
ext=[]
#找到所有的packageformoduleinmy_packages:
module=module.replace(".","/")
ext.append(Extension(module+".*", [module+"/*.py"]))
#找到根目录下的脚本ext.extend(find_scrips())
print("Extension:")
print(ext)
setup(
name=my_project_name,
ext_modules=cythonize(
ext,
build_dir=my_build_dir,
compiler_directives=dict(
always_allow_keywords=True            )),
cmdclass=dict(
build_ext=MyBuildExt        ),
packages=find_packages(where=".")
    )
print("===============end=================")

2)编译为 .c,再进一步编译为 .so 或 .pyd:

python setup.py build_ext --inplace

3)删除python源码,通过.so的方式进行执行:

find . -name'*py[c~]'-delete

4)编写启动脚本,执行过程中调用启动脚本:

from real_main import main
import sys
if __name__ =='__main__':
    main(sys.argv[1:])


注意事项

Cython 源代码的语法是 Python语法的一个超集,也就是说,任何可以在 Python 中使用的语法,也可以在 Cython 中使用。但是,以下几种 Python语法在 Cython 中是不支持的:

1.动态类型变量声明:在 Cython 中,变量必须是静态类型,需要在声明时指定数据类型。

2.不支持 eval() 函数和 exec语句:因为 Cython 是一种编译型语言,无法像 Python一样动态生成代码。

3.不支持生成器表达式和列表推导式:Cython 中不能直接使用生成器表达式和列表推导式,但是可以使用类似于 Python 中的 for 循环语句来达到相同的效果。

4.不支持一些 Python 内置函数:例如 zip(), filter(), map() 等,但是 Cython 提供了自己的实现,用于替代这些函数。

5.不支持 slots 特殊变量:Cython 中不支持 slots 特殊变量来限制类的属性,但是可以使用 cdef class 来实现类的属性限制。

6.不支持一些 Python 模块和库:例如 asyncio, logging 等,因为这些模块和库在 Cython 中不可用。

7.不支持 Python 的全局解释器锁(GIL):Cython 中没有 GIL,因此可以使用 Python 的多线程模块来实现并发编程。

相关文章
|
7月前
|
开发者 Python
提升代码效率的利器:Python装饰器详解
本文深入探讨Python中的装饰器(decorators)机制,介绍其原理、用法和实际应用场景。通过学习装饰器的高级特性,开发者可以有效提升代码的可读性、简洁性和灵活性,从而更高效地编写Python程序。
|
7月前
|
开发者 Python
函数与模块:编写高效的Python代码
【4月更文挑战第8天】本文介绍了Python中提升代码效率和可读性的关键——函数和模块。函数是可重复调用的代码段,用于封装逻辑,减少重复,提高结构清晰度。通过`def`定义函数,使用`return`返回值,支持位置、关键字、默认和不定长参数。模块是包含Python代码的文件,用于组织代码,可导入使用。通过`import`导入模块,创建自定义模块以分解大型项目。熟悉Python标准库中的模块能提升开发效率。掌握函数和模块的使用对编写高效、易维护的代码至关重要。
56 2
|
7月前
|
存储 缓存 算法
优化Python代码性能的7个技巧
在日常的Python开发中,优化代码性能是一个重要的课题。本文介绍了7个实用的技巧,帮助开发者提高Python代码的执行效率,包括利用生成器表达式、使用适量的缓存、避免不必要的循环等。通过本文的指导,读者可以更好地理解Python代码性能优化的方法,提升自身的编程水平。
|
7月前
|
缓存 监控 算法
优化Python代码性能的10个技巧
提高Python代码性能是每个开发者都需要关注的重要问题。本文将介绍10个实用的技巧,帮助你优化Python代码,提升程序的运行效率和性能表现。无论是避免内存泄漏、减少函数调用次数,还是使用适当的数据结构,都能在不同场景下发挥作用,使你的Python应用更加高效稳定。
|
7月前
|
算法 编译器 开发者
如何提高Python代码的性能:优化技巧与实践
本文探讨了如何提高Python代码的性能,重点介绍了一些优化技巧与实践方法。通过使用适当的数据结构、算法和编程范式,以及利用Python内置的性能优化工具,可以有效地提升Python程序的执行效率,从而提升整体应用性能。本文将针对不同场景和需求,分享一些实用的优化技巧,并通过示例代码和性能测试结果加以说明。
|
7月前
|
算法 Java 编译器
优化Python代码性能的实用技巧
提高Python代码性能是每个开发者的关注焦点之一。本文将介绍一些实用的技巧和方法,帮助开发者优化他们的Python代码,提升程序的执行效率和性能。
|
3月前
|
编译器 Linux C语言
编译并运行 Cython 代码的几种方式
编译并运行 Cython 代码的几种方式
66 0
|
5月前
|
缓存 算法 大数据
优化Python代码执行效率的技巧与实践
在Python编程中,优化代码的执行效率是提升应用性能和用户体验的关键。本文探讨了几种有效的技巧和实践方法,帮助开发者们更好地理解和应用Python语言的优化策略,从而提升程序的运行效率和响应速度。
|
5月前
|
机器学习/深度学习 人工智能 数据挖掘
Numba是一个Python库,用于对Python代码进行即时(JIT)编译,以便在硬件上高效执行。
Numba是一个Python库,用于对Python代码进行即时(JIT)编译,以便在硬件上高效执行。
|
6月前
|
测试技术 Python
Python教程:利用timeit模块对代码进行性能测试
在Python中,了解代码的性能是优化和改进的关键。timeit模块是Python标准库中的一个工具,用于测量代码片段的执行时间。本文将介绍timeit模块的各种接口、命令行使用方法以及如何对代码中的函数或类进行性能测试。
105 3