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)
有两件事让我感到丑陋:
有没有更好的办法?最好不要使用我必须添加依赖的东西(因为我希望以最小的跨平台问题发布此代码).我的按位数学很可怕;)
注意:数据已经过预先验证,全部为小写,并且是正确的十六进制对的字符串.
/* 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控制台输入一起使用,如果传递了无效字符,则会崩溃.
另外:感谢那些指出一些严重错别字的人.