将十六进制字符串转换为字节串

d11*_*wtq 6 c

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);
  }
Run Code Online (Sandbox Code Playgroud)

有两件事让我感到丑陋:

  1. 每当我进入缓冲区时,我将除以2的方式
  2. 用于计算十六进制数字的十进制值的条件逻辑

有没有更好的办法?最好不要使用我必须添加依赖的东西(因为我希望以最小的跨平台问题发布此代码).我的按位数学很可怕;)

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

egr*_*nin 6

/* 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));
Run Code Online (Sandbox Code Playgroud)

编辑添加

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

另外:这不进行边界检查,不能与Unicode控制台输入一起使用,如果传递了无效字符,则会崩溃.

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