python代码加密cython_基于Cython和内置distutils库,实现python源码加密(非混淆模式)...

起因

python本身只能做混淆,不能加密,多年的商业软件开发导致有某种“洁癖”:欲将py编译打包

尝试

pyinstaller原理是freeze打包pyc文件,利用工具可完美逆行出源码

各种混淆脚本,版本兼容很差,配置繁琐

cython 常规使用只能编译单个特殊模块

解决

反复尝试摸索后,还是利用了cython和distutils库,自动化识别并转换py到c源码并编译,放出源码供大家参考

"""

利用cython和distutils编译py到pyd[so] 注意安装cython及本地平台对应编译器

http://flywuya.cnblogs.com/

"""

import os

import shutil

from distutils.core import setup

from distutils.command.build_ext import build_ext

from Cython.Build import cythonize

BUILD_CONFIG = {

'SupportExt': ['.py', '.pyx'],

'CopyOnlyFile': ['__main__.py', '__init__.py'],

'CopyOnlyDir': ['assets'],

'IgnoreDir': ['dist', 'build', '__pycache__'],

}

def copy_tree(src, dst):

""" not like shutil.copytree, dst can be exists """

assert os.path.exists(src)

assert os.path.isdir(src)

os.makedirs(dst, exist_ok=True)

for fn in os.listdir(src):

s = os.path.join(src, fn)

t = os.path.join(dst, fn)

if os.path.isfile(s):

shutil.copy2(s, t)

elif os.path.isdir(s):

copy_tree(s, t)

def build_module(source_file, dst_dir, tmp_dir):

""" cythonize && build ext """

assert os.path.isfile(source_file)

assert not os.path.isabs(source_file)

assert os.path.exists(dst_dir)

os.makedirs(tmp_dir, exist_ok=True)

build_cython = os.path.join(tmp_dir, 'build.cython')

build_temp = os.path.join(tmp_dir, 'build.temp')

build_lib = dst_dir

ext_modules = cythonize(

source_file,

build_dir=build_cython,

language_level=3,

)

class build_here(build_ext):

def initialize_options(self):

super().initialize_options()

self.build_temp = build_temp

self.build_lib = build_lib

setup(

ext_modules=ext_modules,

script_args=['build_ext'],

cmdclass=dict(build_ext=build_here)

)

def build_modules(source_dir, dst_dir, tmp_dir):

""" scan && build modules in source_dir """

assert os.path.exists(source_dir)

assert not os.path.isabs(source_dir)

assert not os.path.isabs(dst_dir)

os.makedirs(dst_dir, exist_ok=True)

for root, dirs, files in os.walk(source_dir):

rel_pth = root[len(source_dir)+1:]

for ignore in BUILD_CONFIG['IgnoreDir']:

if ignore in dirs:

dirs.remove(ignore)

for dn in dirs:

if dn in BUILD_CONFIG['CopyOnlyDir']:

copy_tree(

os.path.join(root, dn),

os.path.join(dst_dir, rel_pth, dn)

)

dirs.remove(dn)

for fn in files:

_, ext = os.path.splitext(fn)

os.makedirs(

os.path.join(dst_dir, rel_pth),

exist_ok=True

)

if fn in BUILD_CONFIG['CopyOnlyFile']:

shutil.copy2(

os.path.join(root, fn),

os.path.join(dst_dir, rel_pth, fn)

)

elif ext.lower() in BUILD_CONFIG['SupportExt']:

build_module(

os.path.join(root, fn),

dst_dir,

os.path.join(tmp_dir, rel_pth),

)

else:

shutil.copy2(

os.path.join(root, fn),

os.path.join(dst_dir, rel_pth, fn)

)

if __name__ == "__main__":

# 这里填写要编译的目录

tasks = [

'app',

]

others = [

'requirements.txt',

'packages',

]

BUILD_CONFIG['CopyOnlyFile'].extend(['settings.py'])

for task in tasks:

build_modules(

task,

os.path.join('dist', task),

os.path.join('build', task),

)

for other in others:

if os.path.isfile(other):

bn = os.path.basename(other)

shutil.copy2(other, os.path.join('dist', bn))

elif os.path.isdir(other):

bn = os.path.basename(other)

copy_tree(other, os.path.join('dist', bn))

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值