ASN.1-报文编解码

前言

由于跨平台或者跨语言数据传输中存在操作系统不同,大小端问题,字节对齐不一样等各种原因,所以我们需要对数据进行序列化处理

几种常用的序列号方式
  1. XML类似于HTML,与HTML很相似,但是用它来序列化对象的时候,就显得很复杂
  2. JSON使用起来很简单,他的产生来自于一种关联数组,其本质是采用“键值对”的方式描述对象
  3. Protocol Buffer是一个高效的数据化数据存储格式,用于结构化数据串行化,很适合做数据储存或RPC数据交换格式
  4. ASN.1抽象语法标记
ASN.1

定义:他是描述在网络上传输信息格式的标准方法,描述了一种对数据进行编码,传输,解码的数据格式,他提供了一套完整的描述对象的结构

ASN.1的两部分
  1. 一部分描述信息内数据,数据结构及序列格式(属性)
  2. 一部分描述如何将各部分组成消息(方法)
编码格式
TAGLENGTHVALUE
数据类型数据长度数据的值

数据类型的表示:他在内部用int来表示数据类型,使用的是位操作来表示数据类型

核心思路

他就是将每一个数据转化为TLV格式,然后通过链表这个数据结构将数据连接起来,最后将整个链表再打包为TLV格式,下面是一个TLV数据的结构体

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;
常用的API接口

ITCAST_INT DER_ItAsn1_WriteInteger(ITCAST_UINT32 integer, ITASN1_INTEGER **ppDerInteger);
函数说明:对整形数据进行编码操作
函数参数:
integer: 输入参数, 表示待编码的整形数据
ppDerInteger: 传输参数, 编码之后的数据
返回值:
成功或者失败


ITCAST_INT DER_ItAsn1_ReadInteger(ITASN1_INTEGER *pDerInteger, ITCAST_UINT32 *pInteger);
函数说明: 对整形数据解码
参数说明:
pDerInteger: 传入参数, 表示待解码的数据
pInteger: 传出参数, 表示解码之后的数据
返回值:
成功或者失败
ITCAST_ANYBUF p;
ITCAST_UINT32 aa;
例如: DER_ItAsn1_ReadInteger(&p, &aa);


ITCAST_INT DER_ItAsn1_WritePrintableString(ITASN1_PRINTABLESTRING *pPrintString, ITASN1_PRINTABLESTRING **ppDerPrintString);
函数说明:编码字符串数据
函数参数:
pPrintString: 输入参数, 表示要编码的数据
ppDerPrintString: 输出参数, 表示编码之后的数据
返回值:
成功或者失败


ITCAST_INT DER_ItAsn1_ReadPrintableString(ITASN1_PRINTABLESTRING *pDerPrintString, ITASN1_PRINTABLESTRING **ppPrintString);
函数说明: 解码函数, 将ANYCAST_ANYBUF类型解码到第二个参数
参数说明:
pDerPrintString: 输入参数, 表示待解码的数据
ppPrintString: 输出参数, 存放解码之后的数据
返回值:
成功或者失败


ITCAST_INT DER_ITCAST_String_To_AnyBuf(ITCAST_ANYBUF **pOriginBuf, unsigned char * strOrigin, int strOriginLen);
函数说明: 将char *---->ITCAST_ANYBUF类型
函数参数:
pOriginBuf: 传出参数, ITCAST_ANYBUF指针
strOrigin: 传入参数, 待转换的字符串
strOriginLen: 传入参数, strOrigin的字符串长度
返回值:
成功或者失败


int EncodeChar(char *pData, int dataLen, ITCAST_ANYBUF **outBuf);
函数说明: 将char *类型数据进行编码
函数参数:
pData: 输入参数, 指的是待编码的字符串
dataLen: 输入参数, 指的是pData的长度
outBuf: 输出参数, ITCAST_ANYBUF类型的数据, TLV格式


int DecodeChar(ITCAST_ANYBUF *inBuf, char **Data, int *pDataLen);


ITCAST_INT DER_ItAsn1_WriteSequence(ITASN1_SEQUENCE *pSequence, ITCAST_ANYBUF **ppDerSequence);
函数说明: 序列化链表, 将链表序列化成字节流数据
函数参数:
pSequence: 输入参数, 待序列化的数据
ppDerSequence: 输出参数, 序列化之后的数据


ITCAST_INT DER_ItAsn1_ReadSequence(ITCAST_ANYBUF *pDerSequence, ITASN1_SEQUENCE **ppSequence);
函数说明: 反序列化
参数说明:
pDerSequence:输入参数, 开始需要将char *—>ITCAST_ANYBUF类型
ppSequence: 输出参数, 获得链表头节点

ITCAST_INT DER_ITCAST_FreeQueue(ITCAST_ANYBUF *pAnyBuf);
释放内存

测试函数
	typedef struct _Teacher
	{
		char name[64];
		int age;
		char *p;
		long plen;
	}Teacher;
*/
int encodeTeacher(Teacher * p, char ** outData, int * outlen)
{
	ITCAST_ANYBUF *head = NULL;
	ITCAST_ANYBUF *temp = NULL;
	ITCAST_ANYBUF *next = NULL;

	//编码name
	//ITCAST_INT DER_ItAsn1_WritePrintableString(ITASN1_PRINTABLESTRING *pPrintString, ITASN1_PRINTABLESTRING **ppDerPrintString);
	//char *---->ITCAST_ANYBUF
	DER_ITCAST_String_To_AnyBuf(&temp, p->name, strlen(p->name)+1);
	DER_ItAsn1_WritePrintableString(temp, &head);
	DER_ITCAST_FreeQueue(temp);
	next = head;

	//编码age
	DER_ItAsn1_WriteInteger(p->age, &next->next);
	next = next->next;

	//编码p
	//int EncodeChar(char *pData, int dataLen, ITCAST_ANYBUF **outBuf);
	EncodeChar(p->p, strlen(p->p)+1, &next->next);
	next = next->next;

	//编码plen
	DER_ItAsn1_WriteInteger(p->plen, &next->next);

	//序列化
	DER_ItAsn1_WriteSequence(head, &temp);

	//输出参数赋值
	*outData = temp->pData;
	*outlen = temp->dataLen;

	//释放内存
	DER_ITCAST_FreeQueue(head);

	return 0;
}

int decodeTeacher(char * inData, int inLen, Teacher ** p)
{
	ITCAST_ANYBUF *head = NULL;
	ITCAST_ANYBUF *temp = NULL;
	ITCAST_ANYBUF *next = NULL;

	Teacher *pt = (Teacher *)malloc(sizeof(Teacher));
	if (pt == NULL)
	{
		return -1;
	}

	//将inData反序列化成链表
	//将char *--->ITCAST_ANYBUF类型
	DER_ITCAST_String_To_AnyBuf(&temp, inData, inLen);
	DER_ItAsn1_ReadSequence(temp, &head);
	DER_ITCAST_FreeQueue(temp);
	next = head;

	//解码name
	DER_ItAsn1_ReadPrintableString(next, &temp);
	memcpy(pt->name, temp->pData, temp->dataLen);
	next = next->next;
	DER_ITCAST_FreeQueue(temp);

	//解码age
	DER_ItAsn1_ReadInteger(next, &pt->age);
	next = next->next;

	//解码p
	int len = 0;
	DecodeChar(next, &pt->p, &len);
	next = next->next;

	//解码plen
	DER_ItAsn1_ReadInteger(next, &pt->plen);

	//给输出参数赋值
	*p = pt;

	//释放内存
	DER_ITCAST_FreeQueue(head);

	return 0;
}

void freeTeacher(Teacher ** p)
{
	if ((*p) != NULL)
	{
		if ((*p)->p != NULL)
		{
			free((*p)->p);
		}
		free(*p);
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值