C代码实现数据通信中的转义与解析(二)解析

在这里插入图片描述

作者|釜薪君
公众号|嵌入式杂牌军



前言


上篇中与小伙伴们分享一下数据通信过程中数据的转义,今天来它的后篇——数据的解析。



一、关于转义与解析的说明


1.为什么要进行转义与解析


数据通信中需要对有特定功能的数据在发送时进行转义,在接收时进行解析。


比如通信协议中将0x8a作为帧起始符号,将0x8c作为帧结束符号,为了避免混淆,当数据中也出现0x8a或0x8c时就要对这些字符进行转义,这样可以避免将数据误作为起始或结束帧。


转义可以类比C代码的转义字符。

2.什么是数据的转义


在数据发送时,将敏感功能编码相同的数据转换为协议可识别的数据的过程。

3.什么是数据的解析


在数据接收时,将转义数据恢复成原发送数据的过程。

二、实例代码


1.实例代码


转义规则如下:

   0x8a -> 0x8c0a     
   0x8b -> 0x8c0b      
   0x8c -> 0x8c0c  


数据中碰到十六进制的8a就将8a替换为8c0a,其他两个类似,不满足转义条件的数据保持不变。

解析规则如下:

   8c0a -> 8a     
   8c0b -> 8b      
   8c0c -> 8c


转义之后是字符串,字符串的替换处理起来比较方便所以,解析后是字符串,而并非是整型数据,想获得整型数据需要对数据进行转换,注意数据位数问题哈,这里就不转了。


说明都在代码注释中了。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#define MAXSIZE     500                             // 临时缓冲数组大小

/* 转义函数声明 */
void RecoveryData(char *str);
char *EscapeData(uint32_t dat);                  

int main(int argc, char *argv[])
{
     uint32_t inputdata = 0x128a8b8c;               // 要转义的数据

     char *p = malloc(100);

     printf("\n转义规则(整型数据): \n                      \
                                  \n   0x8a -> 0x8c0a      \
                                  \n   0x8b -> 0x8c0b      \
                                  \n   0x8c -> 0x8c0c      \
                                  \n   数据不满足条件不变   \
                                  \n");

     printf("\n转义前的数据:0x%x\n",inputdata);            // 打印转义前的数据

     strcpy(p,EscapeData(inputdata));                      // int转字符串后进行数据转义
     printf("转义后的数据:0x%s\n",p);                     // 打印转义后的数据

     printf("\n解析规则(字符串):   \n                      \
                                  \n   8c0a ->  8a         \
                                  \n   8c0b ->  8b         \
                                  \n   8c0c ->  8c         \
                                  \n   数据不满足条件不变   \
                                  \n");
     printf("\n解析前的数据:0x%s\n",p);                    // 打印解析前的数据(即转义后的数据)
     RecoveryData(p);                                       // 进行数据的解析
     printf("解析后的数据:0x%s\n",p);                      // 打印解析后的数据

     /* 上面打印的数据是字符串,需要的话可以将解析后的数据转回整型数据,注意数据的大小!*/

     free(p);

     return 0;
}

/* 数据转义,输入为整型,输出是字符串 */
char *EscapeData(uint32_t dat)
{
     uint8_t i;

     uint32_t tmp[4] = {0,0,0,0},array[10] = {0,0,0,0,0,0,0,0,0,0};

     char s0[10],s1[10],s2[10],s3[10];

     char *ret = malloc(100);

     /* 按字节分割32位数据 */
     tmp[0] =  dat & 0xFF;          // 最低位
     tmp[1] =  (dat >> 8) & 0xFF;   // 次低位
     tmp[2] =  (dat >> 16) & 0xFF;  // 次高位
     tmp[3] =  (dat >> 24) & 0xFF;  // 最高位

     for(i = 0; i < 4; i++)
     {
          if((tmp[i] == 0x8a) && (tmp[i] != 0x8b) && (tmp[i] != 0x8c))
          {
               array[i] = (0x8c << 8) | (0x8a^0x80); // 按转义条件进行转义 0x8a -> 0x8c 0x0a -> 0x8c0a
          }
          else if((tmp[i] == 0x8b) && (tmp[i] != 0x8a) && (tmp[i] != 0x8c))
          {
               array[i] = (0x8c << 8) | (0x8b^0x80); // 按转义条件进行转义 0x8b -> 0x8c 0x0b -> 0x8c0b
          }
          else if((tmp[i] == 0x8c) && (tmp[i] != 0x8a) && (tmp[i] != 0x8b))
          {
               array[i] = (0x8c << 8) | (0x8c^0x80); // 按转义条件进行转义 0x8c -> 0x8c 0x0c -> 0x8c0c
          }
          else
          {
               array[i] = tmp[i];                    // 不满足转义条件的数据不变
          }
     }

     /* 按字节进行整数转字符串 */
     sprintf(s0,"%02x",array[0]);
     sprintf(s1,"%02x",array[1]);
     sprintf(s2,"%02x",array[2]);
     sprintf(s3,"%02x",array[3]);

     ret = strcat(s3,strcat(s2,strcat(s1,s0)));   // 字符串拼接

     free(ret);

     return ret;
}

/* 数据解析,输入是字符串,所以用得是处理字符串的方式 */
void RecoveryData(char *str)
{
     char str1[] = "8c0a";                        // 查找的字符,要被替换的字符
     char str2[] = "8a";                          // 要替换的字符

     char str3[] = "8c0b";
     char str4[] = "8b";

     char str5[] = "8c0c";
     char str6[] = "8c";

     uint8_t i, j, k, SeachFlag = 1;
     uint8_t count = 0, gap = 0;
     char temp[MAXSIZE];

     // 8c0a -> 8a
     for(i = 0; i < strlen(str); i += gap)
     {
          if(str[i] == str1[0])
          {
               SeachFlag = 0;
               for(j = i, k = 0; k < strlen(str1); j++, k++)
               {
                    if(str[j] != str1[k])
                    {
                         SeachFlag = 1;
                         gap = k;
                         break;
                    }
               }

               if(0 == SeachFlag)                                      // 已找到待替换字符串并替换
               {
                    for(j = i + strlen(str1), k = 0; j < strlen(str); j++, k++)
                    {
                         temp[k] = str[j];                             // 保存原字符串中剩余的字符
                    }

                    temp[k] = '\0';                                   // 将字符数组变成字符串

                    for(j = i, k = 0; k < strlen(str2); j++, k++)
                    {
                         str[j] = str2[k];                             // 字符串替换
                         count++;
                    }

                    for(k = 0; k < strlen(temp); j++, k++)
                    {
                         str[j] = temp[k];                             // 剩余字符串回接
                    }

                    str[j] = '\0';                                    // 将字符数组变成字符串
                    gap = strlen(str);
             }
        }
        else
        {
              gap = 1;
        }
    }

    // 8c0b -> 8b
    for(i = 0; i < strlen(str); i += gap)
    {
         if(str[i] == str3[0])
         {
               SeachFlag = 0;
               for(j = i, k = 0; k < strlen(str3); j++, k++)
               {
                     if(str[j] != str3[k])
                     {
                          SeachFlag = 1;
                          gap = k;
                          break;
                     }
               }

               if(0 == SeachFlag)                                      // 已找到待替换字符串并替换
               {
                    for(j = i + strlen(str3), k = 0; j < strlen(str); j++, k++)
                    {
                         temp[k] = str[j];                             // 保存原字符串中剩余的字符
                    }

                    temp[k] = '\0';                                   // 将字符数组变成字符串

                    for(j = i, k = 0; k < strlen(str4); j++, k++)     // 字符串替换
                    {
                         str[j] = str4[k];
                         count++;
                    }

                    for(k = 0; k < strlen(temp); j++, k++)
                    {
                         str[j] = temp[k];                            // 剩余字符串回接
                    }

                    str[j] = '\0';                                   // 将字符数组变成字符串
                    gap = strlen(str3);
              }
        }
        else
        {
              gap = 1;
        }
    }

    // 8c0c -> 8c
    for(i = 0; i < strlen(str); i += gap)
    {
         if(str[i] == str5[0])
         {
               SeachFlag = 0;
               for(j = i, k = 0; k < strlen(str5); j++, k++)
               {
                     if(str[j] != str5[k])
                     {
                          SeachFlag = 1;
                          gap = k;
                          break;
                     }
               }

               if(0 == SeachFlag)                                  // 已找到待替换字符串并替换
               {
                     for(j = i + strlen(str5), k = 0; j < strlen(str); j++, k++)
                     {
                          temp[k] = str[j];                         // 保存原字符串中剩余的字符
                     }

                     temp[k] = '\0';                               // 将字符数组变成字符串

                     for(j = i, k = 0; k < strlen(str6); j++, k++) // 字符串替换
                     {
                          str[j] = str6[k];
                          count++;
                     }

                     for(k = 0; k < strlen(temp); j++, k++)        // 剩余字符串回接
                     {
                          str[j] = temp[k];
                     }

                     str[j] = '\0';                                // 将字符数组变成字符串
                     gap = strlen(str5);
               }
         }
         else
         {
              gap = 1;
         }
    }
}


2.运行结果


在这里插入图片描述


今天就到这吧,希望对小伙伴有所帮助哈!


欢迎关注公众号~

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值