|
发表于 2025-8-8 09:45:51
|
显示全部楼层
你的代码乱码问题主要是由于缓冲区空间不足和指针操作不当造成的。以下是详细分析和解决方案:
### 问题分析:
1. **缓冲区太小**:
`char strAdd;` 只声明了一个字符的空间,但你需要存储原密码 + 16字节的MD5值(32个十六进制字符 + 结束符)。这会导致缓冲区溢出。
2. **指针越界**:
`snprintf(p+i*2, "%02x", decrypt+i+4)` 中的 `decrypt+i+4` 会超出MD5结果的范围(MD5只有16字节,索引0~15)。
3. **十六进制转换错误**:
`%02x` 需要的是**字节值**(如 `decrypt[i]`),不是**地址**(`decrypt+i+4`)。
---
### 正确做法(参考课后答案思路):
**为什么需要 `temp2` 临时存储?**
因为MD5结果是**二进制数据**(每个字节范围0~255),直接拼接会包含不可打印字符。用 `snprintf` 转为十六进制字符串后(如 `0a`、`f3`),才能安全拼接。
#### 修正后的 `salt` 函数:
- void salt(unsigned char *mix, unsigned char *src)
- {
- unsigned char temp1[16]; // 存储MD5二进制结果
- unsigned char temp2[17]; // 存储十六进制字符串(16字符+结束符)
- int i, j;
- md5(temp1, src); // 计算第一次MD5
- // 将temp1[4]~[11]转为十六进制字符串
- for (i = 4, j = 0; i < 12; i++, j++)
- {
- snprintf(temp2 + j*2, 3, "%02x", temp1[i]); // 注意:%02x对应一个字节
- }
- // 拼接原密码 + 十六进制字符串
- strcpy(mix, src);
- strcat(mix, temp2); // temp2已是字符串
- }
复制代码
---
### 你的代码修正方案:
- char strAdd[128]; // 确保足够大(原密码长度 + 32 + 1)
- strcpy(strAdd, encrypt); // 复制原密码
- char *p = strAdd + strlen(encrypt); // 指向末尾
- // 只取decrypt[4]~[11](共8字节)
- for(int i = 4; i < 12; i++)
- {
- snprintf(p + (i-4)*2, 3, "%02x", decrypt[i]); // 关键:用decrypt[i]不是地址
- }
复制代码
---
### 关键点总结:
1. **空间分配**:
strAdd 必须用**数组**(如 `char strAdd[128]`)。
2. **正确取MD5中间部分**:
- 索引范围:`decrypt[4]` 到 `decrypt[11]`(共8字节)。
- 每个字节用 `%02x` 转为2个字符。
3. **`snprintf` 参数**:
- snprintf(目标地址, 剩余空间大小, "%02x", 字节值);
复制代码
示例:`snprintf(p, 3, "%02x", decrypt[4])` 会写入 `'0'`、`'a'` 和结束符 `'\0'`。
---
### 为什么乱码?
- 你的代码中 `decrypt+i+4` 是**地址值**(如 `0x7ffd`),不是MD5数据。
- 用 `%02x` 打印地址值会产生超长字符串,覆盖其他内存。
> 附件图片中的乱码正是因为缓冲区溢出和错误数据导致的。按上述修正即可解决。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 |
|