从十六进制表示形式解码时,我需要将char * s = "2f0a3f"这样的(可能很长)字符串转换为它表示的实际字节。目前,我正在执行此操作,但是感觉很笨拙和错误。

  size_t hexlength = strlen(s);
  size_t binlength = hexlength / 2;

  unsigned char * buffer = malloc(binlength);
  long i = 0;
  char a, b;

  for (; i < hexlength; i += 2) {
    a = s[i + 0]; b = s[i + 1];
    buffer[i / 2] =
      ((a < '9' ? a - '0' : a - 'a' + 10) << 4) + (b < '9' ? b - '0' : b - 'a' + 10);
  }

关于这一点,有两件事让我感到震惊:
  • 每次插入缓冲区
  • 时我被二除的方式
  • 找出十六进制数字的十进制值的条件逻辑

  • 有没有更好的办法?最好不要使用我必须添加的依赖项(因为我想以最小的跨平台问题发布此代码)。我的按位数学太糟糕了;)

    注意:数据已预先验证为全部小写,并且是正确的十六进制对字符串。

    最佳答案

    /* allocate the buffer */
    char * buffer = malloc((strlen(s) / 2) + 1);
    
    char *h = s; /* this will walk through the hex string */
    char *b = buffer; /* point inside the buffer */
    
    /* offset into this string is the numeric value */
    char xlate[] = "0123456789abcdef";
    
    for ( ; *h; h += 2, ++b) /* go by twos through the hex string */
       *b = ((strchr(xlate, *h) - xlate) * 16) /* multiply leading digit by 16 */
           + ((strchr(xlate, *(h+1)) - xlate));
    

    编辑以添加

    在80x86汇编语言中,strchr()的核心基本上是一条指令-它不会循环。

    另外:这不进行边界检查,不适用于Unicode控制台输入,并且如果传递了无效字符,则将崩溃。

    另外:感谢那些指出一些严重错别字的人。

    关于c - 将十六进制字符串转换为字节字符串,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12535320/

    10-15 00:33
    查看更多