起因

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. 最意想不到的5个APP UI 设计范例

    现如今,智能手机已成为人们生活中不可或缺的一个物件,琳琅满目的手机APP充斥着各大应用市场.对于普通人来说,他们的衣食住行因此而变得简单方便:对设计师们来说,他们则面临更多的机遇和挑战.每位设计师都梦 ...

  2. Python中ndarray数组切片问题a[-n -x:-y]

    先看看如下代码: >>a=np.arange(10)>>a array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])>>a[-7:] array( ...

  3. Smart Thread Pool (智能线程池)

    STPStartInfo stp = new STPStartInfo();   stp.DisposeOfStateObjects = true;   stp.CallToPostExecute = ...

  4. Linux设备驱动模型底层架构及组织方式

    1.什么是设备驱动模型? 设备驱动模型,说实话这个概念真的不好解释,他是一个比较抽象的概念,我在网上也是没有找到关于设备驱动模型的一个定义,那么今天就我所学.所了解 到的,我对设备驱动模型的一个理解: ...

  5. 团体程序设计天梯赛L2-021 点赞狂魔 2017-04-18 11:39 154人阅读 评论(0) 收藏

    L2-021. 点赞狂魔 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 微博上有个"点赞"功能,你可以为你 ...

  6. 咏南中间件当作WEB SERVER使用方法

    咏南中间件当作WEB SERVER使用方法 1)开启咏南中间件 2)浏览器打开http://localhost:5566/web?page=echo.html

  7. Postgres 主从配置(五)

    PostgreSQL 9.4 新增的一个特性, replication slot,  1. 可以被流复制的sender节点用于自动识别它xlog中的数据在下面的standby中是否还需要(例如, st ...

  8. 由于没有公钥,无法验证下列签名 Ubuntu

    问题:执行 apt-get update 时错误 W: GPG 错误:https://apt.dockerproject.org ubuntu-trusty InRelease: 由于没有公钥,无法验 ...

  9. C# 图书整理

    C#测试驱动开发C#设计模式C#高级编程单元测试之道C#版:使用Nunit 继续添加......

  10. 记开发个人图书收藏清单小程序开发(六)Web开发

    Web页面开发暂时是没有问题了,现在开始接上Ptager.BL的DB部分. 首先需要初始化用户和书房信息.因为还没有给其他多余的设计,所以暂时只有个人昵称和书房名称. 添加 Init Razor Pa ...