国产压缩包工具——JlmPackCore SDK说明(三)——JlmPack_Unpack函数说明

news2024/12/24 3:43:11

一、JlmPack_Unpack函数说明

在这里插入图片描述
JlmPack_Unpack函数是解压jlm文件的核心函数,但是在加密状态下,必须有正确的密码才能解密,该函数具有一定的权限管控条件,部分也需要开发者通过上层系统进行控制。库函数名:

JLMPACK_API int JlmPack_Unpack(VARIABLES* vars);

(1)输入参数说明
在库函数中的所有的输入参数均为VARIABLES* vars,VARIABLES为结构体是一个输入参数结构体,各函数复用,只是用的对象不相同。结构体说明如下:

/**************************************************************************************
VARIABLES变量传递,函数不同则对变量要求不同,请参考各函数的说明
***************************************************************************************/
typedef struct
{
	/**************************************************************************
	* 授权文件YESINE.license的路径,该路径必须正确而且证书也必须是正确有效才能使用本SDK中的所有函数
	**************************************************************************/
	unsigned char* licenseFilePath;
	/**************************************************************************
	* 总字节数totalBytes,和累计字节数Cumulative,主要用于进度条的计算
	**************************************************************************/
	unsigned long long totalBytes;
	unsigned long long cumulativeBytes;
	/**************************************************************************
	* jlmFile为JLM文件格式信息
	* jlmExtra为JLM文件扩展信息
	**************************************************************************/
	JLM_FILE* jlmFile;                              // 输入或输出jlm文件头信息,见结构体JLM_FILE
	JLM_EXTRA* jlmExtra;                            // 输入或输出jlm文件扩展信息,见结构体JLM_EXTRA
	/**************************************************************************
	* RandomBytes为编码前或译码后的随机数数组,随机数是抗量子破解的核心
	* RandomBytes_size为随机数数组中字节个数
	**************************************************************************/
	unsigned char* RandomBytes;                     // 输入或输出随机数,用于生成密钥
	int RandomBytes_size;                           // 输入或输出随机数的字节数
	/**************************************************************************
	* Passwords为编码或译码的密码数组,将根据用户的需要是否
	* Passwords_size为密码数组中字节个数,Passwords_size >= 0且Passwords_size < 64,不建议太长怕忘记后无法找回
	**************************************************************************/
	unsigned char* Passwords;                       // 输入加解密密码,译码时密码是解密的关键
	int Passwords_size;                             // 输入加解密密码长度
	/**************************************************************************
	* jlmFileUrl为编码后或解码前的jlm文件的路径和文件名,可以包括".jlm"
	* 支持XXX.jlm首包路径,也支持XXX_packX.jlm子包路径,任何这样的路径输入给jlmFileUrl均可定位到首包的路径
	**************************************************************************/
	unsigned char* jlmFileUrl;
	/**************************************************************************
	* pathList为编码前或解码后的各类文件和文件夹的路径列表,pathList中允许.jlm文件
	* pathListSize为pathList中路径的个数
	* 注意:编码时pathList为各类文件和文件夹的路径,所以pathListSize大于等于
	* 译码时pathList只能是译码后的文件夹路径,且pathListSize只能等于1
	**************************************************************************/
	unsigned char** pathList;                          // 待编码文件的路径列表或译码后存放文件的文件夹路径,pathList[i]代表一个路径
	int pathListSize;                               // pathList中路径个数
	/**************************************************************************
	* 签名的数字证书哈希值(数据指纹),用于计算JLM_FILE.cer
	**************************************************************************/
	unsigned char* license;                       // 签名的数字证书哈希值(数据指纹),用于计算JLM_FILE.license
	int license_size;                             // 签名的数字证书哈希值字节长度,fatherCer_size为0时说明无签名,此时JLM_FILE.cer为全0序列
	/**************************************************************************
	* rule为目录权限规则,用于管理目录打开条件,请参考SDK说明书
	**************************************************************************/
	short rule;                                     // 权限编号
	/**************************************************************************
	* IdList为待处理的ID列表,比如删除某些ID、追加文件到某个ID下、译码某些ID对应的文件夹或文件等
	* IdList_Size为IdList中ID的个数
	**************************************************************************/
	int* IdList;                                    // ID列表,主要用于译码、删除和增加,创建JLM文件时IdList无效
	int IdList_Size;                                // IdList中ID的个数
	/**************************************************************************
	* 临时运算变量,重复使用
	**************************************************************************/
	unsigned char* InByteArray;                     // 用于压缩和加密编码的临时输入,包括了文件复制等等
	unsigned int InByteArray_Size;
	unsigned char* OutByteArray;                    // 用于解压和解密译码的临时输出,包括了文件复制等等
	unsigned int OutByteArray_Size;
	unsigned char* WriteOrReadBuff;                 // 用于写文件,大小和OutByteArray、InByteArray一致
	unsigned int WriteOrReadBuff_Size;
	/**************************************************************************
	* 日志输入信息
	**************************************************************************/
	JLM_LOG* log;                                   // 日志文件

}VARIABLES;

在JlmPack_Unpack函数中主要用到如下几个参数:
a、unsigned char* licenseFilePath; 为商业授权证书的路径,由上层软件自行指定存放位置,允许存放在服务器上实时下载,商业证书的大小一般在2KB以下。
b、unsigned long long totalBytes;和unsigned long long cumulativeBytes; 这两个参数需要配合使用,为进度条提供计算参数,方便异步更新进度条,totalBytes为当前需要译码的总字节数,cumulativeBytes为累计已经译码的字节数。
c、JLM_FILE* jlmFile; 是jlm压缩包文件的核心结构体,在JlmPack_Unpack函数中用于存放从jlm文件中读取到的文件头数据。
d、JLM_EXTRA* jlmExtra ; 自定义定义的版权信息,在JlmPack_Unpack函数属于输出参数,不能为空,无论jlm文件中是否存在JLM_EXTRA,均需开辟缓存。
e、unsigned char* RandomBytes;和int RandomBytes_size; 这两个参数是成对使用的,在JlmPack_Unpack函数属于运算缓存,有必要但是不会直接解码出随机数。
f、unsigned char* Passwords;和int Passwords_size; 这两个参数是成对使用的,在JlmPack_Unpack函数属于输入,用于解密各个独立随机加密的文件和目录。请牢记自己的密码,我们无法提供解密服务!
g、unsigned char* jlmFileUrl; 待解密的jlm文件路径,这个绝对不能为空,比如可以输入D:\test.jlm,也可以输入test_packX.jlm(其中X代表1,2,3…)各个卷,函数能自动找到首个卷test.jlm。
h、unsigned char** pathList和int pathListSize; 这两个参数是成对使用的,在JlmPack_Unpack函数中pathListSize只能等于1,且pathList[0]存放解压的路径。
i、unsigned char* license;和int license_size; 这两个参数是成对使用的,是商业授权证书的数字指纹缓存地址,可以为空,如果存在商业授权证书,则目录对象将采用商业证书的数字指纹进行签名,并且该签名后的文件可以保存到服务端,配合JLM_LOG结构体中的consistencyMark实现文件的管控和追踪。license需要通过jlmpack官网根证书签名,实名认证和实时校验,允许license签名子证书,需要在官网后台完成。
j、int* IdList;和int IdList_Size; 这两个参数是成对使用的,待译码的文件夹或文件的id列表,因为在译码时获得了目录对象,每个目录均有唯一的id号,如果时文件夹则译码出该文件夹下的全部文件,如果时文件则译码当前文件。
其他的运算缓存和JlmPack_Create相同,采用相同的大小。
(2)返回int参数
返回0表示无错,大于0则表示存在错误,请查看SDK中的错误编号说明(Error number specification).txt文件检查,注意SDK中的错误不会上报到jlmpack的官网,大家通过官网留言。
(3)安全方案
1)用Passwords直接解密jlm文件的目录信息,如果解密错误返回无法解密,尝试次数限制,超过限制自毁文件。
2)如果解密正确,则可获得CatalogInfor对象以及rule的值,如果rule表达了需要强制服务器校验,则进行第3步,否则直接译码。
3)将rule、JLM_FILE.cer、JLM_FILE.consistencyMark和Username、Mac(本地获取)、CPU编号(本地获取)等等信息经过随机加密后推送给后台系统进行验证。
4)验证失败返回NULL,则函数JlmPack_Unpack函数将根据rule进行动作,比如自毁文件,警告必须处于网络正常状态等等。
5)如果验证成功,则返回当前文件在服务器上的全部日志信息,包括了解压过的时间、对象(如终端,用户等)等列表(默认会返回当前最新的十条数据,其他的只能到官网上查询)

二、JlmPack_Unpack函数用法

JlmPack_Unpack函数在main.c中也有测试实例,具体方法如下:

int Unpack() { // 5
	// 设置为""的目的是跟随系统,支持windows和linux
	setlocale(LC_ALL, ""); //en_US.UTF-8

	VARIABLES* vars = NULL;
	int i, errSign = 0;
	unsigned char* ucPassword = "123456";

	vars = (VARIABLES*)malloc(sizeof(VARIABLES));
	if (vars == NULL) goto ERR;

	// 设置里面的参数
	vars->RandomBytes_size = RANDOM_BYTE_LIMIT;   // 编码和解码这个值必须相同
	vars->Passwords_size = strlen(ucPassword) + 1;
	vars->pathListSize = 1;
	vars->rule = 0;
	vars->license_size = 0;
	vars->IdList_Size = 2;

	vars->pathList = (unsigned char**)malloc(vars->pathListSize * sizeof(unsigned char*));
	if (vars->pathList == NULL) goto ERR;
	for (i = 0; i < vars->pathListSize; ++i) {
		vars->pathList[i] = (unsigned char*)malloc(URL_BYTE_LIMIT);
		if (vars->pathList[i] == NULL) goto ERR;
	}
	vars->jlmFile = (JLM_FILE*)malloc(sizeof(JLM_FILE));
	if (vars->jlmFile == NULL) goto ERR;
	// vars->jlmExtra = NULL;
	vars->jlmExtra = (JLM_EXTRA*)malloc(sizeof(JLM_EXTRA));
	if (vars->jlmExtra == NULL) goto ERR;
	// 开辟随机数的缓存空间
	vars->RandomBytes = (unsigned char*)malloc(vars->RandomBytes_size * sizeof(unsigned char));
	vars->Passwords = (unsigned char*)malloc(vars->Passwords_size * sizeof(unsigned char));
	if (vars->RandomBytes == NULL || vars->Passwords == NULL) goto ERR;
	// 开辟jlm路径的缓存空间
	vars->jlmFileUrl = (unsigned char*)malloc(URL_BYTE_LIMIT);
	if (vars->jlmFileUrl == NULL) goto ERR;
	// 同上
	vars->license = (unsigned char*)malloc(JLM_FILE_HASH_BYTE_LIMIT);
	if (vars->license == NULL) goto ERR;
	vars->licenseFilePath = (unsigned char*)malloc(URL_BYTE_LIMIT);
	if (vars->licenseFilePath == NULL) goto ERR;
	// 开辟临时运算缓存,译码过程中开辟相同的缓存大小即可
	vars->WriteOrReadBuff_Size = vars->OutByteArray_Size = vars->InByteArray_Size = BINARY_FILE_MAX_LIMIT;
	vars->InByteArray = (unsigned char*)malloc(vars->InByteArray_Size * sizeof(unsigned char));
	vars->OutByteArray = (unsigned char*)malloc(vars->OutByteArray_Size * sizeof(unsigned char));
	vars->WriteOrReadBuff = (unsigned char*)malloc(vars->WriteOrReadBuff_Size * sizeof(unsigned char));
	if (vars->InByteArray == NULL || vars->OutByteArray == NULL || vars->WriteOrReadBuff == NULL) goto ERR;
	// 开辟日志文件
	vars->log = (JLM_LOG*)malloc(sizeof(JLM_LOG));
	if (vars->log == NULL) goto ERR;
	// ID列表
	vars->IdList = (int*)malloc(vars->IdList_Size * sizeof(int));
	if (vars->IdList == NULL)  goto ERR;
	// 复制密码,去除“\0”
	strcpy(vars->Passwords, ucPassword);
	// 区分windows和linux
#ifdef _WINDOWS
	printf("_WINDOWS\n");
	const char* licensePath = "D:\\yesine_jlmpack_test.license";
	const char* jlmFileUrl = "D:\\test.jlm";
	//const char* jlmFileUrl = "D:\\test_pack4.jlm";
	const char* outurl = "D:\\testDecode\\"; // 解码的文件夹路径
	// 输入解码ID号
	vars->IdList[0] = 0; //2
	vars->IdList[1] = 18;

#elif defined(_LINUX)
	printf("_LINUX\n");
	const char* licensePath = "/home/wangjielin/Desktop/yesine_jlmpack_test.license";
	const char* jlmFileUrl = "/home/wangjielin/Desktop/test.jlm";
	//const char* jlmFileUrl = "/home/wangjielin/Desktop/test_pack3.jlm";
	const char* outurl = "/home/wangjielin/Desktop/testDecode/"; // 解码的文件夹路径
	// 输入解码ID号,由于linux和windows的排序可能不一致,译码同一个东西
	vars->IdList[0] = 0;
	vars->IdList[1] = 18;

#endif
	strcpy(vars->licenseFilePath, licensePath);
	// jlm的文件路径
	strcpy(vars->jlmFileUrl, jlmFileUrl);
	// 把outurl赋值给vars->pathList[0]
	strcpy(vars->pathList[0], outurl);

	printf("vars->pathList[0] = %s\n", vars->pathList[0]);

	// 给vars->IdList中的数据
	errSign = JlmPack_Unpack(vars);
	printf("errSign = %d\n", errSign);

	if (errSign == 0) {
		printf("译码成功!\n");
		printf("vars->log->type = %d\n", vars->log->type);
		printf("vars->log->fileName = %s\n", vars->log->fileName);
		printf("vars->log->consistencyMark = ");
		for (i = 0; i < PACK_FILE_HASH_BYTE_LIMIT; ++i) {
			printf("%02X,", vars->log->consistencyMark[i]);
		}
		printf("\n");
		printf("vars->log->datetime = %lld\n", vars->log->datetime);
		printf("vars->totalBytes = %lld, vars->cumulativeBytes = %lld\n", vars->totalBytes, vars->cumulativeBytes);
	}

ERR:
	if (vars) {
		if (vars->InByteArray) free(vars->InByteArray);
		if (vars->OutByteArray) free(vars->OutByteArray);
		if (vars->WriteOrReadBuff) free(vars->WriteOrReadBuff);
		if (vars->log) free(vars->log);
		if (vars->jlmFile) free(vars->jlmFile);
		if (vars->jlmExtra) free(vars->jlmExtra);
		if (vars->RandomBytes)  free(vars->RandomBytes);
		if (vars->Passwords)  free(vars->Passwords);
		if (vars->jlmFileUrl)  free(vars->jlmFileUrl);
		if (vars->license) free(vars->license);
		if (vars->licenseFilePath) free(vars->licenseFilePath);
		if (vars->IdList) free(vars->IdList);
		if (vars->pathList) {
			for (i = vars->pathListSize - 1; i >= 0; --i) if (vars->pathList[i]) free(vars->pathList[i]);
			free(vars->pathList);
		}
		free(vars);
	}
}

三、注意事项

1、解密过程一般需要密码。
2、所有开辟的空间需要在外部释放。
3、一定要注意Config.h文件中的约束条件。
4、可自定义的结构体一定要把自定义的部分放在结构体的后面。
5、在特殊场景下,必须考虑安全认证的完整性,需要服务端做支持。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1887657.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

做了个三相电量采集器开源出来,可以方便监测家里用电情况

做了个三相电能采集器&#xff0c;可以测3相的电流、电压、功率、功率因数、用电量&#xff0c;数据上传到HomeAssistant&#xff0c;方便观察家里用电量和实时用电功率。 使用3个pzem004t电参数传感器测量&#xff0c;通过串口与ESP32-C3通信&#xff0c;然后通过WiFi上传至H…

WordPress网站如何做超级菜单(Mega Menu)?

大多数的网站菜单都是像以下这种条状的形式&#xff1a; 这种形式的是比较中规中矩的&#xff0c;大多数网站都在用的。当然还有另外一种菜单的表现形式&#xff0c;我们通常叫做“超级菜单”简称Mega Menu。网站的超级菜单&#xff08;Mega Menu&#xff09;是一种扩展的菜单&…

使用ElementUI组件库

引入ElementUI组件库 1.安装插件 npm i element-ui -S 2.引入组件库 import ElementUI from element-ui; 3.引入全部样式 import element-ui/lib/theme-chalk/index.css; 4.使用 Vue.use(ElementUI); 5.在官网寻找所需样式 饿了么组件官网 我这里以button为例 6.在组件中使用…

数组-移除元素

移除元素 移除元素&#xff08;leetcode27&#xff09; var removeElement function(nums, val) {const n nums.length;let left 0;for (let right 0; right < n; right) {if (nums[right] ! val) {nums[left] nums[right];left;}}return left; };删除有序数组中的重复…

GPT-4o不仅能写代码,还能自查Bug,程序员替代进程再进一步!

目录 1 CriticGPT 01 综合性&#xff08;Comprehensiveness&#xff09;&#xff1a; 02 幻觉问题&#xff08;Hallucinates a problem&#xff09;&#xff1a; 2 其他 CriticGPT 案例 随着人工智能&#xff08;AI&#xff09;技术不断进步&#xff0c;AI在编程领域的应用…

hive中cast()函数

CAST函数用于将某种数据类型的表达式显式转换为另一种数据类型。CAST()函数的参数是一个表达式&#xff0c;它包括用AS关键字分隔的源值和目标数据类型。 语法&#xff1a;CAST (expression AS data_type) expression&#xff1a;任何有效的SQServer表达式。 AS&#xff1a;用…

ATFX汇市:欧元区CPI与失业率数据同时发布,欧元或迎剧烈波动

ATFX汇市&#xff1a;CPI数据是中央银行决策货币政策的主要依据&#xff0c;失业率数据是中央银行判断劳动力市场健康状况的核心指标。欧元区的CPI和失业率数据将在今日17:00同时发布&#xff0c;在欧央行6月6日降息一次的背景下&#xff0c;两项数据将显著影响国际市场对欧央行…

2024 年江西省研究生数学建模竞赛题目 A题交通信号灯管理---完整文章分享(仅供学习)

问题&#xff1a; 交通信号灯是指挥车辆通行的重要标志&#xff0c;由红灯、绿灯、黄灯组成。红灯停、绿灯行&#xff0c;而黄灯则起到警示作用。交通信号灯分为机动车信号灯、非机动车信号灯、人行横道信号 灯、方向指示灯等。一般情况下&#xff0c;十字路口有东西向和南北向…

HR人才测评,如何考察想象力?

什么是想象力&#xff1f; 想象力是指&#xff0c;人们通过在已有物质的基础上&#xff0c;通过大脑想象、加工、创造出新事物的能力&#xff0c;举一个非常简单的例子&#xff0c;在提到鸟这种生活的时候&#xff0c;大家会联想到各种各样不同鸟的品种。 在企业招聘中常常应…

3.1 数据结构-线性表

上午10-12分的选择题&#xff0c;下午15分的大题 大纲 线性结构 顺序存储和链式存储区别 单链表的插入和删除 真题 线性结构 - 栈和队列 真题 串

实现WebSocket聊天室功能

实现WebSocket聊天室功能 什么是WebSocket&#xff1f;WebSocket的工作原理服务器端实现客户端实现 在现代Web开发中&#xff0c;实时通信已经变得越来越重要。传统的HTTP协议由于其无状态和单向通信的特点&#xff0c;无法很好地满足实时通信的需求。而WebSocket协议则应运而生…

【java计算机毕设】仓库管理系统 MySQL springboot vue3 Maven 项目源码代码

目录 1项目功能 2项目介绍 3项目地址 1项目功能 【java计算机毕设】仓库管理系统MySQL springboot vue3 Maven小组项目设计源代码 2项目介绍 系统功能&#xff1a; vue3仓库管理系统&#xff0c;主要功能包含&#xff1a;个人信息管理&#xff0c;仓库管理&#xff0c;员工…

【你也能从零基础学会网站开发】理解DBMS数据库管理系统架构,从用户到数据到底经历了什么

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;程序猿、设计师、技术分享 &#x1f40b; 希望大家多多支持, 我们一起学习和进步&#xff01; &#x1f3c5; 欢迎评论 ❤️点赞&#x1f4ac;评论 &#x1f4c2;收藏 &#x1f4c2;加关注 其实前面我们也…

300关卡成语释义典故题库ACCESS\EXCEL数据库

成语典故指关于成语产生、形成、流传的故事传说。成语有很大一部分是从古代相承沿用下来的&#xff0c;它既代表了一个故事典故&#xff0c;又是一种现成的话&#xff0c;很多又有比喻引申意义而被广泛引用。 今天又获得了一个成语游戏的数据&#xff0c;即根据成语典故或者释…

CID引流电商:助力传统电商突破重围实现持续增长

摘要&#xff1a;面临流量成本攀升和市场份额被挤压的挑战&#xff0c;传统电商急需突破重围。CID引流电商通过跨平台引流和精准定位&#xff0c;助力商家实现持续增长&#xff0c;丰富营销手段&#xff0c;创新商业模式。CID引流电商为传统电商的长远发展注入新动力。 在电商…

TFD那智机器人仿真离线程序文本转换为现场机器人程序

TFD式样那智机器人离线程序通过Process Simulation、DELMIA等仿真软件为载体给机器人出离线&#xff0c;下载下来的文本程序&#xff0c;现场机器人一般是无法导入及识别出来的。那么就需要TFD on Desk TFD控制器来进行转换&#xff0c;才能导入现场机器人读取程序。 导入的文…

Lesson 45 The boss‘s letter

Lesson 45 The boss’s letter 词汇 can 能够 n. 罐&#xff0c;听 用法&#xff1a;1. 情态动词&#xff1a;can 动词原形    例句&#xff1a;我能跑。       I can run.    2. a can of … 一罐……    例句&#xff1a;我要一罐可乐。       I wan…

全平台7合一自定义小程序源码系统功能强大 前后端分离 带完整的安装代码包以及搭建教程

系统概述 这款全平台 7 合一自定义小程序源码系统是专为满足各种业务需求而设计的。它整合了多种功能&#xff0c;能够在不同平台上运行&#xff0c;为用户提供了全方位的体验。无论你是企业主、开发者还是创业者&#xff0c;这款系统都能为你提供强大的支持。 代码示例 系统…

手写一个类似@RequestParam的注解(用来接收请求体的参数)

一、本文解决的痛点 按照大众认为的开发规范&#xff0c;一般post类型的请求参数应该传在请求body里面。但是我们有些post接口只需要传入一个字段&#xff0c;我们接受这种参数就得像下面这样单独创建一个类&#xff0c;类中再添加要传入的基本类型字段&#xff0c;配合Reques…

在卷积神经网络(CNN)中为什么可以使用多个较小的卷积核替代一个较大的卷积核,以达到相同的感受野

在卷积神经网络&#xff08;CNN&#xff09;中为什么可以使用多个较小的卷积核替代一个较大的卷积核&#xff0c;以达到相同的感受野 flyfish 在卷积神经网络&#xff08;CNN&#xff09;中&#xff0c;可以使用多个较小的卷积核替代一个较大的卷积核&#xff0c;以达到相同的…