C++十六进制string转字节流

直接上代码, 函数里没有对字节流缓冲区的长度进行安全判断, 使用前要保证不会出现越界的情况

为了方便调试, 加了写入buffer前的格式化输出, 实际使用中可以注释掉

  1 #define ASCII_ZERO  48
  2 #define ASCII_SPACE 32
  3 #define ASCII_X     88
  4 #define ASCII_x     120
  5 
  6 #define NUM_TO_INT(Ascii,Multi)   ((Ascii - 48) * Multi)
  7 #define UPPER_TO_INT(Ascii,Multi) ((Ascii - 55) * Multi)
  8 #define LOWER_TO_INT(Ascii,Multi) ((Ascii - 87) * Multi)
  9 
 10 #define IS_NUM(x)           ((x >= 48) && (x <= 57) ? true : false)
 11 #define IS_UPPER(x)         ((x >= 65) && (x <= 70) ? true : false)
 12 #define IS_LOWER(x)         ((x >= 97) && (x <= 102) ? true : false)
 13 #define IS_ASCII_X(x)       (ASCII_x == x ? true : false)
 14 #define IS_BYTE_COMPLETE(x) (0 == x ? true : false)
 15 
 16 size_t String2ByteStream(const std::string &strByte, uint8_t *pByteStream)
 17 {
 18   if (nullptr == pByteStream) return 0;
 19 
 20   size_t  uiStreamLen = 0;
 21   size_t  uiMulti     = 16;
 22   uint8_t bBuffer     = 0x00;
 23 
 24   for(size_t idx = 0; idx < strByte.length(); ++idx)
 25   {
 26     size_t uiAscii = size_t(strByte[idx]);
 27 
 28     //已完成1字节, 重置缓存和系数
 29     if (IS_BYTE_COMPLETE(uiMulti))
 30     {
 31       printf("%02X ", bBuffer);
 32       pByteStream[uiStreamLen++] = bBuffer;
 33       bBuffer = 0x00;
 34       uiMulti = 16;
 35     }
 36 
 37     switch (uiAscii)
 38     {
 39     //空格, 检查是否存在半字节, 重置字节缓存和系数
 40     case ASCII_SPACE:
 41       if (uiMulti != 16)
 42       {
 43         //考虑 A 1B 这种情况, 算法从左向右计算, A实际应为低4位
 44         printf("%02X ", (bBuffer >> 4));
 45         pByteStream[uiStreamLen++] = (bBuffer >> 4);
 46       }
 47       bBuffer = 0x00;
 48       uiMulti = 16;
 49       break;
 50 
 51     //跳过16进制转义字符
 52     case ASCII_ZERO:
 53       if ((idx + 1) != strByte.length())
 54       {
 55         size_t uiNextAscii = size_t(strByte[idx + 1]);
 56         if (IS_ASCII_X(uiNextAscii))
 57         {
 58           ++idx;
 59           continue;
 60         }
 61       }
 62 
 63       bBuffer += NUM_TO_INT(uiAscii, uiMulti);
 64       uiMulti /= 16;
 65       break;
 66 
 67     //通常字符, 检查之后计算对应16进制值
 68     default:
 69       if (IS_NUM(uiAscii))
 70       {
 71         bBuffer += NUM_TO_INT(uiAscii, uiMulti);
 72       }
 73       else if (IS_UPPER(uiAscii))
 74       {
 75         bBuffer += UPPER_TO_INT(uiAscii, uiMulti);
 76       }
 77       else if (IS_LOWER(uiAscii))
 78       {
 79         bBuffer += LOWER_TO_INT(uiAscii, uiMulti);
 80       }
 81       else
 82       {
 83         //缓存没有改变,系数不变
 84         break;
 85       }
 86       uiMulti /= 16;
 87       break;
 88     }
 89   }
 90 
 91   //写入末尾字节
 92   if (1 == uiMulti)
 93   {
 94     //考虑 A 1B 这种情况, 算法从左向右计算, A实际应为低4位
 95     printf("%02X\n", (bBuffer >> 4));
 96     pByteStream[uiStreamLen++] = (bBuffer >> 4);
 97   }
 98   else if (0 == uiMulti)
 99   {
100     printf("%02X\n", bBuffer);
101     pByteStream[uiStreamLen++] = bBuffer;
102   }
103 
104   return uiStreamLen;
105 }

测试

结果如下

 

以上, 代码感觉不太美观, 如果有错误疏漏, 欢迎指正, 有更好的实现思路欢迎交流讨论

posted @ 2020-10-27 11:10  public_tsing  阅读(1443)  评论(0编辑  收藏  举报