你的程序崩溃可能是由于几个原因。让我们逐步检查代码并找出问题所在。
j
变量的定义和初始化: 在rc4_init
函数中,你使用了{0}
来初始化j
,这不是有效的语法。正确的做法应该是直接给j
赋值0
,而不是使用大括号。
修改:
uint8_t j = 0; // 正确的初始化
处理
S[j]
的范围: 在 RC4 算法中,对数组的访问必须确保在合法范围内。尤其是在这里,ctx->j += ctx->S[ctx->i];
需要确保ctx->j
不会超过255,因为数组S
的大小是256。对输入消息进行更好的控制: 你在
RC4Test()
中传入的是整个数组,但只需要加密有效部分(例如,字符串 “hello world!“)的长度。你可以通过传递实际的长度来解决这个问题。
以下是修改后的代码片段:
#include <ctype.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
// 交换
void Swap(uint8_t *S1, uint8_t *S2) {
uint8_t tmp = *S1;
*S1 = *S2;
*S2 = tmp;
}
struct rc4_ctx_t {
uint8_t i;
uint8_t j;
uint8_t S[256];
};
// 初始化 S 盒
void rc4_init(struct rc4_ctx_t *ctx, const uint8_t *key, int key_len) {
ctx->i = 0;
ctx->j = 0;
for (int i = 0; i < 256; i++) {
ctx->S[i] = i;
}
uint8_t j = 0; // 修正:直接赋值,不用大括号
for (int i = 0; i < 256; i++) {
j += ctx->S[i] + key[i % key_len];
Swap(&ctx->S[i], &ctx->S[j]);
}
}
// RC4 随机数生成与加解密
void rc4_cipher(struct rc4_ctx_t *ctx, uint8_t *Str, int len) {
for (int k = 0; k < len; k++) {
ctx->i++;
ctx->j += ctx->S[ctx->i];
Swap(&ctx->S[ctx->i], &ctx->S[ctx->j]);
// key 就是本轮生成的字节。
uint8_t key = ctx->S[(uint32_t)(ctx->i + ctx->j) % 256]; // 确保索引在有效范围内
// 异或处理
Str[k] ^= key;
}
}
// 摘抄自 https://stackoverflow.com/a/29865
void hexdump(void *ptr, int buflen) {
unsigned char *buf = (unsigned char *) ptr;
for (int i = 0; i < buflen; i += 16) {
printf("%06x: ", i);
for (int j = 0; j < 16; j++)
if (i + j < buflen)
printf("%02x ", buf[i + j]);
else
printf(" ");
printf(" ");
for (int j = 0; j < 16; j++)
if (i + j < buflen)
printf("%c", isprint(buf[i + j]) ? buf[i + j] : '.');
printf("\n");
}
}
int RC4Test() {
struct rc4_ctx_t rc4;
const char* key = "hello world";
unsigned char message[] = "hello world!"; // 使用动态长度
size_t msg_len = strlen((const char*)message); // 获取实际消息长度
printf("*************start*************\n");
printf("message: %s\n", message);
printf("Key: %s \n\n", key);
printf("*************enc*************\n");
// 加密阶段
rc4_init(&rc4, (const uint8_t*)key, strlen(key));
rc4_cipher(&rc4, message, msg_len);
hexdump(message, msg_len);
printf("*************dec*************\n");
// 解密阶段
rc4_init(&rc4, (const uint8_t*)key, strlen(key));
rc4_cipher(&rc4, message, msg_len);
hexdump(message,msg_len);
printf("*************end*************\n");
}
int main() {
RC4Test();
return 0;
}
请根据上面的建议修改你的代码,这样可以避免潜在的问题,并确保它按预期工作。如果还有其他问题,请告诉我!
内容由零声教学AI助手提供,问题来源于学员提问