ASN.1-报⽂编解码
前⾔
由于跨平台或者跨语⾔数据传输中存在操作系统不同,⼤⼩端问题,字节对齐不⼀样等各种原因,所以我们需要对数据进⾏序列化处理
⼏种常⽤的序列号⽅式
1. XML类似于HTML,与HTML很相似,但是⽤它来序列化对象的时候,就显得很复杂
2. JSON使⽤起来很简单,他的产⽣来⾃于⼀种关联数组,其本质是采⽤“键值对”的⽅式描述对象
3. Protocol Buffer是⼀个⾼效的数据化数据存储格式,⽤于结构化数据串⾏化,很适合做数据储存或RPC数据交换格式
4. ASN.1抽象语法标记
ASN.1
定义:他是描述在⽹络上传输信息格式的标准⽅法,描述了⼀种对数据进⾏编码,传输,解码的数据格
式,他提供了⼀套完整的描述对象的结构
ASN.1的两部分
1. ⼀部分描述信息内数据,数据结构及序列格式(属性)
2. ⼀部分描述如何将各部分组成消息(⽅法)
编码格式
TAG LENGTH VALUE
数据类型数据长度数据的值
数据类型的表⽰:他在内部⽤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);
write的返回值
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);
return0;
}
}
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);
return0;
}
void freeTeacher(Teacher ** p)
{
if((*p)!=NULL)
{
if((*p)->p !=NULL)
{
free((*p)->p);
}
free(*p);
}
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。