从十六进制表示形式解码时,我需要将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/