【问题标题】:How to convert Hex char into bytes like \x90\x90?如何将十六进制字符转换为 \x90\x90 等字节?
【发布时间】:2018-01-29 19:40:17
【问题描述】:

我正在寻找一种将十六进制字符转换为 \x90\x0d\x41 等字节的方法,当我使用 printf() 时,会打印二进制数据?

char *hex = "909090904241";

当我需要得到\x90\x90\x90\x90\x42\x42 时,当我打印时,我得到二进制数据。

【问题讨论】:

  • 一次循环遍历 2 个字符并以 16 为底调用 strtoul
  • “当我需要得到 '\x90\x90\x90\x90\x42\x42' 并且当我打印时我得到二进制数据”需要更具体。请发布显示问题的Minimal, Complete, and Verifiable example。将预期输出和实际输出显示为问题中的文本
  • 为什么期望x42\x42 来自"4241"
  • @chux 我很抱歉.. 我想要 \x42\x41

标签: c string hex byte


【解决方案1】:
int hex_to_bytes(const char* hex, uint8_t** buf_ptr, size_t** len_ptr) {
   size_t len = strlen(hex);
   if (len % 2)
      goto error1;

   len /= 2;
   char* buf = malloc(len);
   char hex_byte[3];
   hex_byte[2] = 0;
   for (size_t i=len; i--; ) {
      hex_byte[0] = *(hex++);
      hex_byte[1] = *(hex++);
      char* end_ptr;
      buf[i] = strtoul(hex_byte, &end_ptr, 16);
      if (end_ptr != hex_byte+2)
         goto error2;
   }

   *buf_ptr = buf;
   *len_ptr = len;
   return 1;

error2:
   free(buf);
error1:
   *buf_ptr = NULL;
   *len_ptr = 0;
   return 0;
}


uint8_t* buf;
size_t len;
if (!hex_to_bytes(hex, &buf, &len)) {
   ... handle error ...
}

... Use buf and len ...
free(buf);

请注意,buf 不是以 nul 结尾的。当输入可能是 "000000" 时,我没有看到将其设为空终止字符串的意义。

【讨论】:

  • @yano,是的,刚刚注意到并修复了。
【解决方案2】:

对于字符串中的每个字符,首先通过将其 ASCII 减去字符 '0''A' 将其转换为数字。然后将每个值分配到目标数组中,并根据需要进行移位。

以下假设为 ASCII,并且输入字符串仅包含 0-9 和 A-F 范围内的字符。

char *str="909090904241";
unsigned char a[strlen(str)/2+1] = {0};
int i;

for (i=0;i<strlen(str);i++) {
    unsigned char num = (str[i] >= '0' && str[i] <= '9') ? str[i] - '0' : str[i] - 'A' + 10;
    a[i/2] |= num << (4 * (1 - (i % 2)));   // shift even index bits by 4, odd index by 0
}
for (i=0;i<strlen(str)/2+1;i++) {
    printf("%02x ", a[i]);
}
printf("\n");

输出:

90 90 90 90 42 41 

【讨论】:

    【解决方案3】:

    所以基本上我有一个包含十六进制字节的变量,当我打印它们时,我得到二进制表示

    #include<stdio.h>
    
    char *hex_bytes = "\x90\x90\x90\x41";
    
    int main () {
        printf(hex_bytes);
        return 0 ;
    

    }

    我想对这样的十六进制字符做同样的事情

    char *hex = "9090904241";
    

    谢谢你,HM

    【讨论】:

      【解决方案4】:

      循环遍历字符串并在新字符串中追加一段在前面添加 \x 的片段,如下所示:

      const char *hex = "909090904241";
      char* result = malloc((strlen(hex) * 2 + 1)* sizeof(char));
      result[0] = 0;
      char piece[] = "\\x00";
      for (int i = 0; i < strlen(hex); i+=2) {
        piece[2] = hex[i];
        piece[3] = hex[i+1];
        strcat(result, piece);
      }
      

      【讨论】:

      • 正确,我忘记了。已添加。
      • 在循环中使用n=strlen(hex)strcat(result, piece); 可以得到 O(n*n) 的解决方案。对于长字符串,这可能会很慢。 O(n) 很容易得到。
      猜你喜欢
      • 2017-08-23
      • 1970-01-01
      • 2023-03-07
      • 2022-06-18
      • 2019-07-27
      • 2013-02-07
      • 1970-01-01
      • 2014-03-19
      相关资源
      最近更新 更多