Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >ASN.1 编码基础数据类型

ASN.1 编码基础数据类型

作者头像
我与梦想有个约会
发布于 2023-10-20 10:30:46
发布于 2023-10-20 10:30:46
26200
代码可运行
举报
文章被收录于专栏:jiajia_dengjiajia_deng
运行总次数:0
代码可运行

这几天开始做项目了,涉及到项目传输时的报文设计,在C/S架构的项目设计中,传递数据一定要有一定的格式,这样服务端和客户端才能区分开来。除了格式以外还要考虑到传递的数据如果是指针怎么办?如果是NULL怎么办?等等问题,这些问题其实有很多中解决方案,本文就介绍一种 ASN.1 编码格式,当然本文没办法大篇幅的介绍 ASN.1 编码的格式、好处等等内容,网络上的资料有很多,本文主要是记录代码上如何实现对基础数据类型的编码,以备以后忘记了具体细节时回来查看。


相关头文件下载

点击下载:itcast_asn1_der 包含.h和.cpp

代码实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include “itcast_asn1_der.h”
typedef struct _tag_teacher
{
int age;
char name[20];
char* p;
char plen;
}Teacher;
int mywritefile(unsigned char *buf, int len)
{
FILE *fp = NULL;
#ifdef WIN32
fopen_s(&fp, “c:/teacher.ber”, “wb+);
#else
fp = fopen(“c:/teacher.ber”, “wb+);
#endif
if (fp == NULL)
{
printf(“fopen file error \n”);
return -1;
}
fwrite(buf, 1, len, fp);
fclose(fp);
return 0;
}
/*
函数功能:编码 Teacher 结构体,通过
参数介绍:
Teacher *pStruct:Teacher 类型的结构体指针
unsigned char** out:unsigned char 类型的空指针,用来接收内部处理完成后返回的数据
int* outlen:int 类型的指针,用来接收内部处理完成后数据的长度
*/
int EncodeStruct(Teacher *pStruct, unsigned char** out, int* outlen)
{
int ret = 0;// 记录返回值
ITCAST_ANYBUF *pHeadBuf = NULL;// 头节点
ITCAST_ANYBUF *pCur = NULL;// 游标,储存新编码的节点域并与头节点连接
ITCAST_ANYBUF *pTeacher = NULL;// 临时节点用来接收整条链表编码后的结果
if (out == NULL  outlen == NULL)
{
return -1;
}
// 如果传递的第一个参数是NULL,那么正常也对 NULL 进行编码
if (pStruct == NULL)
{
DER_ItAsn1_WriteNull(&pTeacher);
goto END;
}
// 编码第一个 int 域保存到第一个节点 pHeadBuf 中
ret = DER_ItAsn1_WriteInteger(pStruct->age, &pHeadBuf);
if (ret != 0)
{
printf(“func DER_ItAsn1_WriteInteger() err:%d\n”, ret);
return ret;
}
// 让游标指向头节点
pCur = pHeadBuf;
// 让头节点的下一个节点(pCur->next)接收编码name的数据
ret = EncodeChar(pStruct->name, strlen(pStruct->name), &pCur->next);
if (ret != 0)
{
DER_ITCAST_FreeQueue(pHeadBuf);
printf(“func EncodeChar() err:%d\n”, ret);
return ret;
}
// 连接链表,向前递进,编码指针域
pCur = pCur->next;
ret = EncodeChar(pStruct->p, pStruct->plen, &pCur->next);
if (ret != 0)
{
DER_ITCAST_FreeQueue(pHeadBuf);
printf(“func EncodeChar() err:%d\n”, ret);
return ret;
}
// 连接链表,向前递进,编码 plen
pCur = pCur->next;
ret = DER_ItAsn1_WriteInteger(pStruct->plen, &pCur->next);
if (ret != 0)
{
DER_ITCAST_FreeQueue(pHeadBuf);
printf(“func DER_ItAsn1_WriteInteger() err:%d\n”, ret);
return ret;
}
// 将整个链表一起编码
ret = DER_ItAsn1_WriteSequence(pHeadBuf, &pTeacher);
if (ret != 0)
{
DER_ITCAST_FreeQueue(pHeadBuf);
printf(“func DER_ItAsn1_WriteSequence() err:%d\n”, ret);
return ret;
}
END:
// 将数据传出
*out = ( unsigned char* ) malloc( pTeacher->dataLen );
#ifdef WIN32
memcpy_s(*out, pTeacher->dataLen, pTeacher->pData, pTeacher->dataLen);
#else
memcpy(*out, pTeacher->pData, pTeacher->dataLen);
#endif // WIN32
*outlen = pTeacher->dataLen;
// 释放内存
DER_ITCAST_FreeQueue(pHeadBuf);
DER_ITCAST_FreeQueue(pTeacher);
return ret;
}
int TeacherDecode(unsigned char* out, int outlen, Teacher** pTeacher)
{
int ret = 0;
return ret;
}
int main(int argc, char* argv[])
{
int ret = 0;
Teacher teacher;
teacher.age = 25;
#ifdef WIN32
strcpy_s(teacher.name, sizeof(teacher.name), “myCode”);
#else
strcpy(teacher.name, “myCode”);
#endif // WIN32
teacher.p = (char*)malloc(100);
#ifdef WIN32
strcpy_s(teacher.p, 100, “pStructTest”);
#else
strcpy(teacher.p, “pStructTest”);
#endif // WIN32
teacher.plen = strlen(teacher.p);
// 接收数据的变量
unsigned char*out = NULL;
intoutlen = 0;
// 编码结构体
ret = EncodeStruct(&teacher, &out, &outlen);
if (ret != 0)
{
free(teacher.p);
printf(“func EncodeStruct() err:%d\n”, ret);
return ret;
}
// 将编码后的数据写入到文件中,可通过 ber 查看工具进行查看
mywritefile(out, outlen);
// 解码
Teacher *pTeacher = NULL;
ret = TeacherDecode(out, outlen, &pTeacher);
if (teacher.age == pTeacher->age &&
strcmp(teacher.name, pTeacher->name) &&
strcmp(teacher.p, pTeacher->p) &&
teacher.plen == pTeacher->plen)
{
printf(“一样\n”);
}
else
{
printf(“不一样\n”);
}
// 释放内存
free(out);
free(teacher.p);
return 0;
}

代码编译

在 VS 中新建一个 win32 控制台空项目,新建 mian.c 文件将代码粘贴进去,然后在项目中右键导入现有项,将上面下载后得到的几个文件包含到项目目录中即可编译,根据自己的需要把注释的部分解除注释查看效果。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015-08-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
十分钟包会MySQL插件开发
请看下面的MySQL UDF插件模版,通过C执行shell语句。所以只要替换shell语句的位置,保存并编译。duang的一下,你的MySQL插件就成功出炉。
莫晓东do
2018/07/19
2.5K0
线性表链式存储
上文中我们介绍了线性表顺序储存的方式,并给大家画了一幅比较详细的图(虽然看着比较凌乱),本文介绍的是数据储存的另外一种方式“链式储存”,这相当于我们之前提到过的单向链表,但是,本文与上一篇文章一样,都将数据的储存和算法进行了分离。这才是我们真正应该晋级了解的东西,如果只是一个单向链表,不足以我们耗费这么多精力。
我与梦想有个约会
2023/10/20
1580
环保 HJ212协议解析
由于是做环保相关的,有时需要对212协议进行拆包和解包。HJ212协议是一种字符串协议,数据传输通讯包主要由包头、数据段长度、数据段、CRC校验、包尾组成,其中“数据段”内容包括请求编码、系统编码、命令编码、密码、设备唯一标识、总包数、包号、指令参数。请求编码为请求的时间戳,系统编码ST统一规定为22,命令编码CN为该数据包的时间类型,访问密码、设备唯一标识在对接时由平台提供,指令参数为数据内容。通讯协议的数据结构如图4所示。
ccf19881030
2020/09/22
3.4K0
环保 HJ212协议解析
数据结构基础详解:哈希表【C语言代码实践篇】开放地址法__拉链法_哈希表的创建_增删查操作详解
小徐在进步
2024/10/09
3230
数据结构基础详解:哈希表【C语言代码实践篇】开放地址法__拉链法_哈希表的创建_增删查操作详解
【C语言】实践:贪吃蛇小游戏(附源码)
贪吃蛇小游戏想必大家都玩过吧,现在就要C语言代码来实现一下贪吃蛇小游戏
星辰与你
2024/10/17
6650
【C语言】实践:贪吃蛇小游戏(附源码)
内存泄漏以及常见的解决方法
A memory leak is a particular type of unintentional memory consumption by a computer program where the program fails to release memory when no longer needed. This condition is normally the result of a bug in a program that prevents it from freeing up memory that it no longer needs.This term has the potential to be confusing, since memory is not physically lost from the computer. Rather, memory is allocated to a program, and that program subsequently loses the ability to access it due to program logic flaws.
全栈程序员站长
2022/07/12
1.5K0
耗时两天,优化失败
在上一篇文章基于线程池的线上服务性能优化中,我们提到了使用线程池进行某个业务功能优化,在上线之后,实时性提高了大概24-30倍样子,基本能够满足实时性要求。在正常运行了几天之后,突然收到了报警,提示popen失败,于是打开了日志,发现有如下提示:
高性能架构探索
2022/08/25
5860
耗时两天,优化失败
C++写Socket——TCP篇(0)建立连接及双方传输数据
这里主要是关于TCP的,TCP的特点什么的相关介绍在我另一篇博文里,所以这里直接动手吧。
太阳影的社区
2021/10/15
2.3K0
UPnP端口映射实现过程(二)
#define UPNPPORTMAP0 "WANIPConnection" #define UPNPPORTMAP1 "WANPPPConnection" #define UPNPGETEXTERNALIP "GetExternalIPAddress"/*"NewExternalIPAddress"*/ #define UPNPADDPORTMAP "AddPortMapping" #define UPNPDELPORTMAP "DeletePortMapping" #define
TSINGEYE清眸物联
2023/01/04
8010
漏洞分析 | OpenSSL国密爆出8.1分高危漏洞CVE-2021-3711
背景 OpenSSL是一个知名的开源安全套接字层密码库。全球成千上万的web服务器的网站加密技术使用OpenSSL。 网银、在线支付、电商网站、门户网站、电子邮件等互联网应用广泛使用OpenSSL实现数据的安全传输和安全存储。 历史上,OpenSSL多次出现安全漏洞。 2014年,OpenSSL爆出Heartbleed(心脏滴血)漏洞,网络出现了“致命内伤”。 心脏滴血称为互联网安全历史上最严重的漏洞之一,当时全球三分之二的网站可被该漏洞攻击。 心脏滴血漏洞的CVE编号是CVE-201
云鼎实验室
2021/09/03
2.5K0
EasyRTSPLive之跨平台ini配置及通道的方法
视频网关是一种协议转换器,又称为网间连接器,视频网关就是在网络层以上实现网络相互连接,也就是网络互连。是最复杂的网络互连设备,用于两个高层协议不同的网络互连。视频网关既可以用于广域网互连,也可以用于局域网互连。网关是一种充当转换重任的计算机系统或设备。使用在不同的通信协议、数据格式或语言,甚至体系结构完全不同的两种系统之间。
EasyNVR
2020/04/23
8170
C/C++ 实现正反向端口映射
通常服务器是放在内网中,内部局域网中,并且分配了私有IP地址,而如果想要在外部直接访问内部服务器则需要端口映射,端口映射也叫做端口转发,或者叫做虚拟服务器,在渗透时当我们拿到目标机器权限以后,目标机器实在内网环境中,如果想要外部直接访问内部的特定机器的特定端口,则需要使用映射来实现,常用的映射工具是LCX,或者自己实现。
王 瑞
2022/12/28
7070
我是一个线程(节选)
多线程编程在现代软件开发中是如此的重要,以至于熟练使用多线程编程是一名合格的后台开发人员的基本功,注意,我这里用的是基本功一词。它是如此的重要,所以您应该掌握它。本文将介绍多线程的方方面面,从基础的知识到高级进阶。让我们开始吧。
范蠡
2018/10/23
2.2K0
我是一个线程(节选)
实验设备管理系统C语言_实验室设备管理系统代码
实验设备管理系统设计 实验设备信息包括:设备编号,设备种类(如:微机、打印机、扫描仪等等),设备名称,设备价格,设备购入日期,是否报废,报废日期等。 主要功能: (1)能够完成对设备的录入和修改 (2)对设备进行分类统计 (3)设备的破损耗费和遗损处理 (4)设备的查询 要求:使用文件方式存储数据。
全栈程序员站长
2022/11/08
2.2K1
实验设备管理系统C语言_实验室设备管理系统代码
微光互联 TX800-U 扫码器无法输出中文到光标的问题
某检测场有一批扫码器,购于微光互联,型号 TX800-U,用于在不同办理窗口间扫描纸质材料上的二维码,简化录入过程。扫码器通过 USB 接入 PC 系统 (windows),自动安装驱动,接电即可使用,扫描的信息会直接输出在光标所在位置,扫码器大概长这样:
海海
2022/10/31
9360
微光互联 TX800-U 扫码器无法输出中文到光标的问题
C++ 使用Socket实现主机间的UDP/TCP通信
服务器端的代码做了跨平台(POSIX和WINDOWS),基于POSIX平台(Linux、Mac OS X、PlayStation等)使用sys/socket.h库,windows平台使用winsock2.h库。 客户端代码因为基本都在windows运行,所以没做跨平台,需要的话你可以参考服务器端代码自己做一下。 文中写的函数原型均为windows平台,部分函数的返回类型或参数类型在POSIX会有不同。
六月丶
2023/01/01
3.2K1
C++ 使用Socket实现主机间的UDP/TCP通信
一个工业级、跨平台、轻量级的 tcp 网络服务框架:gevent
作为公司的公共产品,经常有这样的需求:就是新建一个本地服务,产品线作为客户端通过 tcp 接入本地服务,来获取想要的业务能力。与印象中动辄处理成千上万连接的 tcp 网络服务不同,这个本地服务是跑在客户机器上的,Win32 上作为开机自启动的 windows 服务运行;Linux 上作为 daemon 在后台运行。总的说来就是用于接收几个产品进程的连接,因此轻量化是其最重要的要求,在这个基础上要能兼顾跨平台就可以了。其实主要就是 windows,再兼顾一点儿 linux。
海海
2022/08/19
1.3K0
一个工业级、跨平台、轻量级的 tcp 网络服务框架:gevent
记一次在Mac系统下因为栈上变量溢出导致的内存泄露问题
在Mac上测试TSM SDK C语言版本的SM2Encrypt接口时,遇到一个内存无法释放的问题:
密码学人CipherHUB
2022/11/23
1.9K3
记一次在Mac系统下因为栈上变量溢出导致的内存泄露问题
最简单的基于FFMPEG的视频编码器(YUV编码为H.264)
=====================================================
全栈程序员站长
2022/09/13
6770
最简单的基于FFMPEG的视频编码器(YUV编码为H.264)
【C语言】字符串函数「超详细」
🚩write in front🚩 🔎大家好,我是謓泽,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 🏅2021年度博客之星物联网与嵌入式开发TOP5~2021博客之星Top100~阿里云专家^ 星级博主~掘金⇿InfoQ创作者~周榜54»总榜2999🏅 🆔本文由 謓泽 原创 CSDN首发 🙉 如需转载还请通知⚠ 📝个人主页-謓泽的博客_CSDN博客💬 🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​ 📣系列专栏-【C】系列_謓泽的博客-CSDN博客🎓 📢本文 de 创作时间  ⇨
謓泽
2022/12/12
1.5K0
【C语言】字符串函数「超详细」
推荐阅读
相关推荐
十分钟包会MySQL插件开发
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验