You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言hexlify与unhexlify函数转换异常问题求助

分析你的hexlify/unhexlify代码问题

我帮你找出了代码里几个关键问题,正是这些问题导致只有部分十六进制字符能正常转换,其他字符会失败:

1. 缺少必要的头文件

你的代码使用了malloc()、strlen()和system(),但没有包含对应的头文件:

  • malloc()和system()需要<stdlib.h>
  • strlen()需要<string.h>
    缺少头文件会导致函数隐式声明,可能引发未定义行为。

2. a2v()函数未处理大写十六进制字符,分支逻辑有问题

当前a2v()只处理了小写a-f,如果输入是大写A-F,会直接返回0,导致转换错误。另外,原代码的else只绑定第二个if,逻辑不够清晰,还会把非法字符误判为0,建议调整:

int a2v(char c) {
    if ((c >= '0') && (c <= '9')) {
        return c - '0';
    }
    if ((c >= 'a') && (c <= 'f')) {
        return c - 'a' + 10;
    }
    if ((c >= 'A') && (c <= 'F')) { // 新增处理大写十六进制的分支
        return c - 'A' + 10;
    }
    return -1; // 用-1标识非法字符,避免和合法的0混淆
}

3. unhexlify()函数的潜在越界与错误处理缺失

  • 没有检查输入字符串长度是否为偶数:如果输入长度是奇数,i+1会访问超出字符串范围的内存,导致崩溃。
  • 没有检查malloc()返回值:如果内存分配失败,bstr会是NULL,后续操作直接崩溃。
  • 循环条件里重复调用strlen():每次循环都会重新计算字符串长度,影响效率,建议先把长度存起来。

修改后的unhexlify():

char *unhexlify(char *hstr) {
    if (!hstr) return NULL;
    size_t hlen = strlen(hstr);
    // 检查十六进制字符串长度是否为偶数
    if (hlen % 2 != 0) {
        fprintf(stderr, "Error: Hex string length must be even.\n");
        return NULL;
    }
    size_t blen = hlen / 2;
    char *bstr = malloc(blen + 1);
    if (!bstr) {
        fprintf(stderr, "Error: Memory allocation failed.\n");
        return NULL;
    }
    char *pbstr = bstr;
    for (size_t i = 0; i < hlen; i += 2) {
        int high = a2v(hstr[i]);
        int low = a2v(hstr[i+1]);
        // 检查字符是否合法
        if (high == -1 || low == -1) {
            fprintf(stderr, "Error: Invalid hex character at position %zu or %zu.\n", i, i+1);
            free(bstr);
            return NULL;
        }
        *pbstr++ = (high << 4) | low; // 用位或比加法更安全,逻辑上更准确
    }
    *pbstr = '\0';
    return bstr;
}

4. hexlify()函数的位操作错误(核心问题)

这是导致大部分转换失败的关键原因:

  • 你用了(bstr[i] >> 4) & 0xFF,但我们只需要取高4位,应该用0x0F。如果char是有符号类型,当字符值大于0x7F时,右移会进行符号扩展,导致结果变成0xFF之类的数值,超出hex数组的索引范围(数组只有16个元素,索引0-15),直接引发数组越界。
  • 取低4位时,应该用bstr[i] & 0x0F,而不是0xFF。

修改后的hexlify():

char *hexlify(char *bstr) {
    if (!bstr) return NULL;
    size_t blen = strlen(bstr);
    char *hstr = malloc(blen * 2 + 1);
    if (!hstr) {
        fprintf(stderr, "Error: Memory allocation failed.\n");
        return NULL;
    }
    char *phstr = hstr;
    for (size_t i = 0; i < blen; i++) {
        // 转成unsigned char避免符号扩展问题
        unsigned char c = (unsigned char)bstr[i];
        *phstr++ = v2a((c >> 4) & 0x0F); // 取高4位
        *phstr++ = v2a(c & 0x0F); // 取低4位
    }
    *phstr = '\0';
    return hstr;
}

5. 其他小问题优化

  • main()里的input字符串末尾的\0是多余的,字符串字面量会自动添加终止符。
  • 没有释放malloc分配的内存,会导致内存泄漏,建议在程序结束前加上释放逻辑。
  • 二进制字符串可能包含不可打印字符,直接用printf("%s")会显示乱码,建议用十六进制逐个字节打印。

完整修改后的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int a2v(char c) {
    if ((c >= '0') && (c <= '9')) {
        return c - '0';
    }
    if ((c >= 'a') && (c <= 'f')) {
        return c - 'a' + 10;
    }
    if ((c >= 'A') && (c <= 'F')) {
        return c - 'A' + 10;
    }
    return -1;
}

char v2a(int c) {
    const char hex[] = "0123456789abcdef";
    // 确保索引合法,避免越界
    if (c < 0 || c >= 16) {
        return '?';
    }
    return hex[c];
}

char *unhexlify(char *hstr) {
    if (!hstr) return NULL;
    size_t hlen = strlen(hstr);
    if (hlen % 2 != 0) {
        fprintf(stderr, "Error: Hex string length must be even.\n");
        return NULL;
    }
    size_t blen = hlen / 2;
    char *bstr = malloc(blen + 1);
    if (!bstr) {
        fprintf(stderr, "Error: Memory allocation failed.\n");
        return NULL;
    }
    char *pbstr = bstr;
    for (size_t i = 0; i < hlen; i += 2) {
        int high = a2v(hstr[i]);
        int low = a2v(hstr[i+1]);
        if (high == -1 || low == -1) {
            fprintf(stderr, "Error: Invalid hex character at position %zu or %zu.\n", i, i+1);
            free(bstr);
            return NULL;
        }
        *pbstr++ = (high << 4) | low;
    }
    *pbstr = '\0';
    return bstr;
}

char *hexlify(char *bstr) {
    if (!bstr) return NULL;
    size_t blen = strlen(bstr);
    char *hstr = malloc(blen * 2 + 1);
    if (!hstr) {
        fprintf(stderr, "Error: Memory allocation failed.\n");
        return NULL;
    }
    char *phstr = hstr;
    for (size_t i = 0; i < blen; i++) {
        unsigned char c = (unsigned char)bstr[i];
        *phstr++ = v2a((c >> 4) & 0x0F);
        *phstr++ = v2a(c & 0x0F);
    }
    *phstr = '\0';
    return hstr;
}

int main() {
    char *title = "... Trying to convert hex into binary string and back again ?! ...";
    printf("%s\n\n", title);
    char *input = "0123456789abcdef";
    printf("Original: %s (%zu)\n\n", input, strlen(input));
    
    char *input_bin = unhexlify(input);
    if (!input_bin) {
        return 1;
    }
    printf("Bin: ");
    // 用十六进制打印每个字节,避免不可打印字符乱码
    for (size_t i = 0; i < strlen(input_bin); i++) {
        printf("%02X ", (unsigned char)input_bin[i]);
    }
    printf("(%zu)\n\n", strlen(input_bin));
    
    char *input_hex = hexlify(input_bin);
    if (!input_hex) {
        free(input_bin);
        return 1;
    }
    printf("Hex: %s (%zu)\n\n", input_hex, strlen(input_hex));
    
    // 释放内存
    free(input_bin);
    free(input_hex);
    system("pause");
    return 0;
}

内容的提问来源于stack exchange,提问作者Kevin Menegatti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:55:12