【练习准备】简单结构体的编码解码(ASN.1-DER-TLV编码解码案例)

在进行简单结构体的编码解码之前我们先来了解一下什么是ASN.1?什么是DER?什么是TLV?

01 ASN.l抽象语法标记ASN.1

抽象语法标记(Abstract Syntax Notation One) ASN.1是一种 ISO/ITU-T 标准,描述了一种对数据进行表示、编码、传输和解码的数据格式。它提供了一整套正规的格式用于描述对象的结构,而不管语言上如何执行及这些数据的具体指代,也不用去管到底是什么样的应用程序。
ASN.1是描述在网络上传输信息格式的标准方法。它有两部分:一部分描述信息内数据,数据类型及序列格式;另一部分描述如何将各部分组成消息。它原来是作为X.409的一部分而开发的,后来才自己独立成为一个标准。ASN.1在OSI的ISO 8824/ITU X.208(说明语法)和ISO 8825/ITU X.209(说明基本编码规则)规范。
例如:

Report ::= SEQUENCE {
   
author OCTET STRING,
title OCTET STRING,
body OCTET STRING,
biblio Bibliography
}

在这个例子中,"Report"是由名字类型的信息组成的,而SEQUENCE表示消息是许多数据单元构成的,前三个数据单元的类型是OCTET STRING,而最后一个数据类型见下面的ASN.1语法表示它的意义:

Bibliography ::= SEQUENCE {
   
author OCTET STRING
title OCTET STRING
publisher OCTET STRING
year OCTET STRING
}

ASN.1中定义的数据类型既有简单的基本数据类型,也有复杂的结构类型。

  1. 基本类型是不可再再分的,包括:
    o 布尔型(BOOLEAN)
    o 整型(INTEGER)
    o 实型(REAL)
    o 位串类型(BITSTRING)
    o 8位位组类型(OCTET STRING)
    o 枚举类型(ENUMERATED)
    o 空类型(NULL)
    o 对象标识符(OBJECT IDENTIFIER)
  2. 除基本类型,ASN.1还定义了多种复杂的结构类型,例如:
    o SEQUENCE:有序的数据集合(序列),由不同类型的数据组成。SEQUENCE结构强调内部成员的排序
    o SEQUENCE OF:有序的数据集合,类似于C语言的数组,由同一类型的数据组成。
    o SET:由不同类型的数据组成的集合,用来描述复杂的信息对象,对内部成员的顺序不作要求,类似于C语言的结构体类型
    o CHOICE:选择结构,在列出的内部成员中,只能选择其中之一,类似于C语言中的共用体类型

ASN.1可以实现跨平台的编码解码的结果唯一性。

02 BER编码规则

	DER报文编码方式,唯一标识符编码,消除二义性。

001 基本规则在这里插入图片描述

002 样例及原理

比如对老师的结构体进行编码:

typedef struct _Teacher
{
   
	char name[64];
	int age ;
	char *p;
}Teacher;

假设:
Teacher.name是myname,标签是10,长度是7;
Teacher.age是25岁,标签是11,长度是4;
Teacher—>p所指的内容是 aaaaaaa,标签是12,长度是1024;
一般编码之前不管是Java类还是C/C++写的结构体都会先转成ASN.1语法,然后进行统一编码。

Teacher::=SEQUENCE{
   
	name OCTET STRING
	age  INTERGER
	p    OCTET STRING
}

然后看下图对其进行编码:
在这里插入图片描述

03 实现简单结构体的编码解码

在这个案例中,我们对于结构体的编码解码调用开源的DER编码,解码的API函数,如下:
在这里插入图片描述
这个后面会上传上来
在这里插入图片描述
(一般在工程开发中也是这样做,现在模拟一个简单的工程开发,对老师的结构体进行编码,解码操作,然后对比编码前和解码后的value是否一样)

01_简单结构体编码解码.c

#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "itcast_asn1_der.h"
#include "itcastderlog.h"


typedef struct _Teacher
{
   
	char	name[64];
	int		age;
	char	*p;
	int		plen;
}Teacher;
int mywritefile(unsigned char *buf, int len)
{
   
	FILE *fp = NULL;
	fp = fopen("c:/teacher.ber", "wb+");
	if (fp == NULL)
	{
   
		printf("fopen file error \n");
		return -1;
	}
	fwrite(buf, 1, len, fp);
	fclose(fp);
	return 0;
}

/* 
typedef struct ITCAST_ANYBUF_{
	unsigned char *pData;
	ITCAST_UINT32     dataLen;
	ITCAST_UINT32     unusedBits;  // for bit string
	ITCAST_UINT32     memoryType;
	ITCAST_UINT32     dataType;
	struct ITCAST_ANYBUF_ *next;    //for sequence and set 
	struct ITCAST_ANYBUF_ *prev;
}ITCAST_ANYBUF;

ITCAST_INT
DER_ItAsn1_WritePrintableString(ITASN1_PRINTABLESTRING *pPrintString, ITASN1_PRINTABLESTRING **ppDerPrintString);
*/
//报文编码
int Teacher_Encode(Teacher *pstruct, unsigned char **p, int *len)//一级指针输入,二级指针输出
{
   //Teacher_Encode(&t1, &out, &outlen);
	int					ret = 0;
	ITCAST_ANYBUF		*pTmp = NULL, *pHeadBuf = NULL;
	ITCAST_ANYBUF		*pTmpBuf = NULL;
	ITCAST_ANYBUF		*pOutData = NULL;
  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力做一个code杠精

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值