起因

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))

基于Cython和内置distutils库,实现python源码加密(非混淆模式)的更多相关文章

  1. 用内置的库turtle来画一朵花,python3

    题目:用内置的库turtle来画一朵花 看了群主最后成像的图片,应该是循环了36次画方框,每次有10度的偏移. 当然不能提前看答案,自己试着写代码. 之前有用过海龟画图来画过五角星.奥运五环.围棋盘等 ...

  2. 查看python内部模块命令,内置函数,查看python已经安装的模块命令

    查看python内部模块命令,内置函数,查看python已经安装的模块命令 可以用dir(modules) 或者用 pip list或者用 help('modules') 或者用 python -m  ...

  3. 基于Zlib算法的流压缩、字符串压缩源码

    原文:基于Zlib算法的流压缩.字符串压缩源码 Zlib.net官方源码demo中提供了压缩文件的源码算法.处于项目研发的需要,我需要对内存流进行压缩,由于zlib.net并无相关文字帮助只能自己看源 ...

  4. 基于Docker的TensorFlow机器学习框架搭建和实例源码解读

    概述:基于Docker的TensorFlow机器学习框架搭建和实例源码解读,TensorFlow作为最火热的机器学习框架之一,Docker是的容器,可以很好的结合起来,为机器学习或者科研人员提供便捷的 ...

  5. 基于Ubuntu 14.04 LTS编译Android4.4.2源码

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/gobitan/article/details/24367439 基于Ubuntu 14.04 LTS ...

  6. Python源码剖析——01内建对象

    <Python源码剖析>笔记 第一章:对象初识 对象是Python中的核心概念,面向对象中的"类"和"对象"在Python中的概念都为对象,具体分为 ...

  7. python 内置标准库socketserver模块的思考

    socketserver模块简化了编写网络服务器的任务, 在很大程度上封装了一些操作, 你可以看成是事件驱动型的设计, 这很不错.它定义了两个最基本的类--服务器类 BaseServer, 请求处理类 ...

  8. 2.3 spring5源码系列---内置的后置处理器PostProcess加载源码

    本文涉及主题 1. BeanFactoryPostProcessor调用过程源码剖析 2. 配置类的解析过程源码 3. 配置类@Configuration加与不加的区别 4. 重复beanName的覆 ...

  9. 基于vue实现一个简单的MVVM框架(源码分析)

    不知不觉接触前端的时间已经过去半年了,越来越发觉对知识的学习不应该只停留在会用的层面,这在我学jQuery的一段时间后便有这样的体会. 虽然jQuery只是一个JS的代码库,只要会一些JS的基本操作学 ...

随机推荐

  1. 中介者模式c#(媒婆版)

    using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace 中介者模式{  ...

  2. linux下的文本操作之 文本查找——grep

    摘要:你有没有这样的应用场景:调试一个程序,出现debug的提示信息,现在你需要定位是哪个文件包含了这个debug信息,也就是说,你需要在一个目录下的多个文件(可能包含子目录)中查找某个字符串的位置: ...

  3. SQLSERVER带端口号的链接方式

    SQLSERVER带端口号的链接方式 <add key="BBAcnn" value="server=IP,端口号\实例名;database=TESTDB;uid= ...

  4. 查看JVM内存使用情况

    Runtime run = Runtime.getRuntime(); long max = run.maxMemory()/(1024*1024); long total = run.totalMe ...

  5. Cenots 7 Configure static IP

    For example: # cd /etc/sysconfig/ifcfg-enp3s0 # cat ifcfg-enp3s0 TYPE=EthernetBOOTPROTO=staticIPADDR ...

  6. 如何彻底删除TFS的工作项字段

    TFS的工作项字段可以在所有工作项类型之间共享.例如自定义了一个字段"验证迭代"(Mycompany.IterationValidation)那么在需求.Bug中都可以添加这个字段 ...

  7. Solr查询query效果对比

    q条件 默认分词(org.apache.solr.analysis.TokenizerChain) "parsedquery" IK分词(org.wltea.analyzer.lu ...

  8. 基于 Raphael 的 Web UI 设计 - 初稿

    基于 Raphael 的 UI 设计 - 初稿 还有很多地方需要完善,这次要把 Raphael 彻底用起来,^_^, 一定要150字哦,一图抵千字啊,^_^,不喜欢写字的,那么怎么凑够150字呢,说说 ...

  9. Bootstrap变形记

    bootstrap审美疲劳了,想个招换换样子,THINKING... 变形 >>> 哈,不用改已有代码,添加我的Harley.js即可,有空在玩... 真实好久不玩博客园了,200字 ...

  10. DataTable转List<T>

    /// <summary> /// DataTable转List<T> /// </summary> public static class TableToList ...