当前位置: 首页 > news >正文

python源码保护

文章目录

  • 代码混淆
  • 打包exe
  • 编译为字节码
  • 源码加密

项目发布部署时,为防止python源码泄漏,可以通过几种方式进行处理

代码混淆

修改函数、变量名

打包exe

通过pyinstaller 将项目打包为exe可执行程序,不过容易被反编译。

编译为字节码

py_compile
compileall
模块
容易被反编译

源码加密

  1. pyarmor 加密
    官网
    官方文档
  • 源码加密
  • 设置程序的许可方式,如设置使用期限、绑定环境设备(磁盘、mac/ip、网卡)等;

安装

pip install pyarmor

加密单个py文件

# 终端命令
# 加密一个文件
pyarmor obfuscate index.py  

加密后的文件:
dist / index.py 加密文件,内部的函数、类等仍可以像python源码一样导入,前提是要记得里面都有哪些类。
dist / pytransform包 后续需要放入python搜索路径或者能被搜索找到
 
加密整个项目的py文件
在这里插入图片描述

# 递归地加密,项目中的每个包都会进行加密
pyarmor obfuscate --recursive index.py 

加密结果:
在这里插入图片描述
加密后的py文件能像正常源码一样使用,前提是pytransform包可以被搜索到。
试用版加密整个项目时,有最大字节限制(32768)!!

 
生成许可文件,并使用:

# 生成许可, 放入licenses目录
pyarmor licenses --expired "2025-01-01" --bind-disk "100304xxxx" --bind-mac "70:f1:a1:23:f0:94" --bind-ipv4 "200.10.139.23"# 使用许可 加密
pyarmor obfuscate --with-license licenses/regcode-01/license.lic index.py

在这里插入图片描述

 
默认安装的pyarmor是试用版,有些限制,如单次加密最多32768字节。
购买地址
 
 
2. Nuitka 将python转为C,再编译为二进制文件(操作系统的动态链接库),反编译难度大
linux- .so
win- dll/pyd
方法实现:
在这里插入图片描述

在这里插入图片描述
jmpy3 库
在这里插入图片描述

参考

# -*- coding: utf-8 -*-
"""
@summary: 加密python代码为pyd/so
"""
import os
import re
import shutil
import tempfile
from distutils.command.build_py import build_py
from distutils.core import setup
from typing import Union, Listfrom Cython.Build import cythonizefrom jmpy.log import loggerdef get_package_dir(*args, **kwargs):return ""# 重写get_package_dir, 否者生成的so文件路径有问题
build_py.get_package_dir = get_package_dirclass TemporaryDirectory(object):def __enter__(self):self.name = tempfile.mkdtemp()return self.namedef __exit__(self, exc_type, exc_value, traceback):shutil.rmtree(self.name)def search(content, regexs):if isinstance(regexs, str):return re.search(regexs, content)for regex in regexs:if re.search(regex, content):return Truedef walk_file(file_path):if os.path.isdir(file_path):for current_path, sub_folders, files_name in os.walk(file_path):for file in files_name:file_path = os.path.join(current_path, file)yield file_pathelse:yield file_pathdef copy_files(src_path, dst_path):if os.path.isdir(src_path):if os.path.exists(dst_path):shutil.rmtree(dst_path)def callable(src, names: list):if search(src, dst_path):return namesreturn ["dist", ".git", "venv", ".idea", "__pycache__"]shutil.copytree(src_path, dst_path, ignore=callable)else:if not os.path.exists(dst_path):os.makedirs(dst_path)shutil.copyfile(src_path, os.path.join(dst_path, os.path.basename(src_path)))def get_py_files(files, ignore_files: Union[List, str, None] = None):"""@summary:---------@param files: 文件列表#param ignore_files: 忽略的文件,支持正则---------@result:"""for file in files:if file.endswith(".py"):if ignore_files and search(file, regexs=ignore_files):  # 该文件是忽略的文件passelse:yield filedef filter_cannot_encrypted_py(files, except_main_file):"""过滤掉不能加密的文件,如 log.py __main__.py 以及包含 if __name__ == "__main__": 的文件Args:files:Returns:"""_files = []for file in files:if search(file, regexs="__.*?.py"):continueif except_main_file:with open(file, "r", encoding="utf-8") as f:content = f.read()if search(content, regexs="__main__"):continue_files.append(file)return _filesdef encrypt_py(py_files: list):encrypted_py = []with TemporaryDirectory() as td:total_count = len(py_files)for i, py_file in enumerate(py_files):try:dir_name = os.path.dirname(py_file)file_name = os.path.basename(py_file)os.chdir(dir_name)logger.debug("正在加密 {}/{},  {}".format(i + 1, total_count, file_name))setup(ext_modules=cythonize([file_name], quiet=True, language_level=3),script_args=["build_ext", "-t", td, "--inplace"],)encrypted_py.append(py_file)logger.debug("加密成功 {}".format(file_name))except Exception as e:logger.exception("加密失败 {} , error {}".format(py_file, e))temp_c = py_file.replace(".py", ".c")if os.path.exists(temp_c):os.remove(temp_c)return encrypted_pydef delete_files(files_path):"""@summary: 删除文件---------@param files_path: 文件路径 py 及 c 文件---------@result:"""try:# 删除python文件及c文件for file in files_path:os.remove(file)  # py文件os.remove(file.replace(".py", ".c"))  # c文件except Exception as e:passdef rename_excrypted_file(output_file_path):files = walk_file(output_file_path)for file in files:if file.endswith(".pyd") or file.endswith(".so"):new_filename = re.sub("(.*)\..*\.(.*)", r"\1.\2", file)os.rename(file, new_filename)def start_encrypt(input_file_path,output_file_path: str = None,ignore_files: Union[List, str, None] = None,except_main_file: int = 1,
):assert input_file_path, "input_file_path cannot be null"assert (input_file_path != output_file_path), "output_file_path must be diffent with input_file_path"if output_file_path and os.path.isfile(output_file_path):raise ValueError("output_file_path need a dir path")input_file_path = os.path.abspath(input_file_path)if not output_file_path:  # 无输出路径if os.path.isdir(input_file_path):  # 如果输入路径是文件夹 则输出路径为input_file_path/dist/project_nameoutput_file_path = os.path.join(input_file_path, "dist", os.path.basename(input_file_path))else:output_file_path = os.path.join(os.path.dirname(input_file_path), "dist")else:output_file_path = os.path.abspath(output_file_path)# 拷贝原文件到目标文件copy_files(input_file_path, output_file_path)files = walk_file(output_file_path)py_files = get_py_files(files, ignore_files)# 过滤掉不需要加密的文件need_encrypted_py = filter_cannot_encrypted_py(py_files, except_main_file)encrypted_py = encrypt_py(need_encrypted_py)delete_files(encrypted_py)rename_excrypted_file(output_file_path)logger.debug("加密完成 total_count={}, success_count={}, 生成到 {}".format(len(need_encrypted_py), len(encrypted_py), output_file_path))

相关文章:

python源码保护

文章目录代码混淆打包exe编译为字节码源码加密项目发布部署时,为防止python源码泄漏,可以通过几种方式进行处理代码混淆 修改函数、变量名 打包exe 通过pyinstaller 将项目打包为exe可执行程序,不过容易被反编译。 编译为字节码 py_comp…...

第51讲:SQL优化之COUNT查询的优化

文章目录 1.COUNT查询优化的概念2.COUNT函数的用法1.COUNT查询优化的概念 在很多的业务场景下可能需要统计一张表中的总数据量,当表的数据量很大时,使用COUNT统计表数据量时,也是非常耗时的。 MyISAM引擎会把一个表的总行记录在磁盘中,当执行count(*)的时候会直接从磁盘中…...

ArrayBlockingQueue

同步队列超出长度时,不同的返回形式可以分为以下四种。 会抛异常不会抛异常,有返回值死等,直到可以插入值或者取到值设置等待超时时间添加方法add()offfer()put()offer(E e,long timeout, TimeUnit unit)删除方法remove()poll()take()poll(l…...

DeepLabV3+:对预测处理的详解

相信大家对于这一部分才是最感兴趣的,能够实实在在的看到效果。这里我们就只需要两个.py文件(deeplab.py、predict_img.py)。 创建DeeplabV3类 deeplab.py的作用是为了创建一个DeeplabV3类,提供一个检测图片的方法,而…...

【Git】与“三年经验”就差个分支操作的距离

前言 Java之父于胜军说过,曾经一位“三年开发经验”的程序员粉丝朋友,刚入职因为不会解决分支问题而被开除,这是不是在警示我们什么呢? 针对一些Git的不常用操作,我们通过例子来演示一遍 1.版本回退 1.1已提交但未p…...

【经验】win10设置自启动

方法一:自启动文件夹 按下winr快捷键,弹出运行窗口,输入:shell:startup,弹出自启动文件夹窗口,将要开机自启的程序或快捷方式复制到此窗口中即可。 自启动文件夹路径:C:\Users\【用户名】\Ap…...

Linux SPI-NAND 驱动开发指南

文章目录Linux SPI-NAND 驱动开发指南1 概述1.1 编写目的1.2 适用范围1.3 相关人员3 流程设计3.1 体系结构3.2 源码结构3.3 关键数据定义3.3.1 flash 设备信息数据结构3.3.2 flash chip 数据结构3.3.3 aw_spinand_chip_request3.3.4 ubi_ec_hdr3.3.5 ubi_vid_hdr3.4 关键接口说…...

【THREE.JS学习(3)】使用THREEJS加载GeoJSON地图数据

本文接着系列文章&#xff08;2&#xff09;进行介绍&#xff0c;以VUE2为开发框架&#xff0c;该文涉及代码存放在HelloWorld.vue中。相较于上一篇文章对div命名class等&#xff0c;该文简洁许多。<template> <div></div> </template>接着引入核心库i…...

在windows搭建Redis集群并整合入Springboot项目

搭建集群配置规划Redis集群编写bat来启动每个redis服务安装Ruby安装Redis的Ruby驱动出现错误镜像过期SSL证书过期安装集群脚本redis-trib启动每个节点并执行集群构建脚本测试搭建是否成功配置springboot项目中配置规划Redis集群 我们搭建三个节点的集群&#xff0c;每个节点有…...

C++【内存管理】

文章目录C内存管理一、C/C内存分布1.1.C/C内存区域划分图解&#xff1a;1.2.根据代码进行内存区域分析二、C内存管理方式2.1.new/delete操作内置类型2.2.new和delete操作自定义类型三、operator new与operator delete函数四、new和delete的实现原理4.1.内置类型4.2.自定义类型4…...

Spring Cloud Nacos源码讲解(六)- Nacos客户端服务发现

Nacos客户端服务发现源码分析 总体流程 首先我们先通过一个图来直观的看一下&#xff0c;Nacos客户端的服务发现&#xff0c;其实就是封装参数、调用服务接口、获得返回实例列表。 ​ 但是如果我们要是细化这个流程&#xff0c;会发现不仅包括了通过NamingService获取服务列表…...

华为OD机试题,用 Java 解【计算最大乘积】问题

最近更新的博客 华为OD机试 - 猴子爬山 | 机试题算法思路 【2023】华为OD机试 - 分糖果(Java) | 机试题算法思路 【2023】华为OD机试 - 非严格递增连续数字序列 | 机试题算法思路 【2023】华为OD机试 - 消消乐游戏(Java) | 机试题算法思路 【2023】华为OD机试 - 组成最大数…...

蓝牙运动耳机哪个好,比较好的运动蓝牙耳机

很多想选择蓝牙运动耳机的朋友都不知道应该如何选择&#xff0c;运动首先需要注意的就是耳机的防水能力以及耳机佩戴舒适度&#xff0c;在运动当中会排出大量的汗水&#xff0c;耳机防水等级做到越高&#xff0c;可以更好地保护耳机不受汗水浸湿&#xff0c;下面就分享五款适合…...

苹果设计可变色Apple Watch表带,智能穿戴玩法多

苹果最新技术专利显示&#xff0c;苹果正在为 Apple Watch 设计一款可变色的表带&#xff0c;可以根据佩戴者所穿着的服装、所在的环境等自动改变颜色。据介绍&#xff0c;这款表带里的灯丝具有电致变色功能&#xff0c;可以通过施加不同的电压&#xff0c;来实现显示多种颜色或…...

Elasticsearch集群Yellow亚健康状态修复

Elasticsearch集群Yellow亚健康状态修复问题背景排查流程解决办法问题背景 Elasticsearch集群健康状态为Yellow&#xff0c;涉及到多个索引。 排查流程 在浏览器打开Kibana Console进行问题排查&#xff0c;console地址为&#xff1a; http://{Kibana_IP}:5601/app/dev_too…...

第52讲:SQL优化之UPDATE更新操作的优化

文章目录 1.UPDATE更新语句的优化2.UPDATE更新语句优化案例1.UPDATE更新语句的优化 我们在使用UPDATE更新语句更改表中数据时,可能会导致表中产生行级锁或者是表级锁。 UPDATE语句的优化就是为了避免表中出现表级锁,从而影响并发的性能。 当UPDATE语句更新表数据时,WHERE…...

logback 自定义日志输出到数据库

项目日志格式 Spring Boot 的默认日志输出类似于以下示例&#xff1a; 2021-12-14 22:40:14.159 INFO 20132 --- [ main] com.kuangstudy.SpringbootApplication : Started SpringbootApplication in 2.466 seconds (JVM running for 3.617)输出以下项目&…...

< elementUi 组件插件: el-table表格拖拽修改列宽及行高 及 使用注意事项 >

elementUi 组件插件&#xff1a; el-table拖拽修改列宽及行高 及 使用注意事项&#x1f449; 资源Js包下载及说明&#x1f449; 使用教程> 实现原理> 局部引入> 全局引入 &#xff08;在main.js中&#xff09;&#x1f449; 注意事项往期内容 &#x1f4a8;&#x1f4…...

微信小程序的分享朋友圈

分享朋友圈官方API&#xff1a;分享到朋友圈 1、分享到朋友圈接口设置事项&#xff1a; 2、onShareTimeline()注意事项&#xff1a; 3、分享朋友圈后&#xff0c;测试发现&#xff0c;没有数据请求。 用户在朋友圈打开分享的小程序页面&#xff0c;并不会真正打开小程序&…...

华为OD机试真题Python实现【 寻找路径】真题+解题思路+代码(20222023)

寻找路径 题目 二叉树也可以用数组来存储,给定一个数组,树的根节点的值储存在下标 1, 对于储存在下标 n 的节点,他的左子节点和右子节点分别储存在下标 2*n 和 2*n+1, 并且我们用 -1 代表一个节点为空。 给定一个数组存储的二叉树,试求从根节点到最小的叶子节点的路径,…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中&#xff0c;性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期&#xff0c;开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发&#xff0c;但背后往往隐藏着系统资源调度不当…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...