如何从字符串提取十六进制值并实现bit_decrypt解密函数?
用sscanf实现空格分隔十六进制字符串的解密函数
嘿,这个需求用sscanf()完全能搞定,而且思路挺清晰的。我给你拆解一下具体步骤,再附上完整的可运行代码,你一看就明白啦~
核心思路
输入是空格分隔的两位十六进制数,我们可以通过循环调用sscanf()逐个读取每个十六进制值,同时利用sscanf()的特殊格式符跟踪处理进度,直到遍历完整个字符串。最后把读取到的ASCII值组装成解密后的字符串即可。
具体实现步骤
1. 统计有效十六进制数的数量
首先需要遍历一遍输入字符串,统计有多少个合法的两位十六进制数——这样我们就能准确分配内存,避免浪费或者溢出。这里会用到sscanf()的%n格式符,它能记录本次调用处理了多少个字符。
2. 动态分配内存
根据统计的数量,为解密后的字符串分配内存(记得多留一个字节存字符串结束符\0)。
3. 循环读取并转换
再次遍历输入字符串,用%hhx格式符读取两位十六进制数,转换成对应的ASCII字符并存入结果数组,同时移动指针到下一个待处理的位置。
完整代码示例
#include <stdio.h> #include <stdlib.h> #include <string.h> char* bit_decrypt(const char* text) { // 空输入直接返回NULL if (text == NULL) return NULL; // 第一步:统计十六进制数的个数 int count = 0; const char* ptr = text; int bytes_processed; unsigned char temp; // 临时存储读取的十六进制值 while (sscanf(ptr, "%hhx%n", &temp, &bytes_processed) == 1) { count++; ptr += bytes_processed; // 跳过连续的多余空格(可选,但能处理极端情况) while (*ptr == ' ') ptr++; } // 分配内存:count个字符 + 1个结束符 char* decrypted_str = (char*)malloc(count + 1); if (decrypted_str == NULL) { perror("内存分配失败"); return NULL; } // 第二步:读取每个十六进制值并转换为字符 ptr = text; int index = 0; while (sscanf(ptr, "%hhx%n", &temp, &bytes_processed) == 1) { decrypted_str[index++] = (char)temp; ptr += bytes_processed; while (*ptr == ' ') ptr++; } decrypted_str[index] = '\0'; // 必须添加字符串结束符 return decrypted_str; } // 测试用例 int main() { const char* encrypted_text = "48 65 6C 6C 6F 20 57 6F 72 6C 64"; // 对应"Hello World" char* result = bit_decrypt(encrypted_text); if (result != NULL) { printf("解密结果:%s\n", result); free(result); // 务必释放动态分配的内存,避免泄漏 } return 0; }
关键细节解释
%hhx:这个格式符专门用来读取两位十六进制数,并将其存入unsigned char类型变量(完美匹配ASCII值0-255的范围,避免int类型的冗余)。%n:这是sscanf()的隐藏利器——它不会消耗输入内容,而是把本次调用成功处理的字符数存入后面的int变量。我们用它来移动指针,确保每次都从下一个未处理的位置开始读取。- 内存管理:必须由调用者负责
free()返回的指针,否则会造成内存泄漏。如果内存分配失败,函数会返回NULL,记得在调用时做判空处理。 - 容错处理:如果输入字符串中包含非十六进制字符,
sscanf()会停止读取,此时解密结果会是截止到有效字符的部分。如果需要严格校验输入,可以在循环中检查sscanf()的返回值,当返回0时判定为无效输入并返回错误。
内容的提问来源于stack exchange,提问作者wannacode1881
相关产品推荐
相关产品推荐

