C语言randstring生成加密密钥乱码无法解密及终端清屏咨询
修复方案
密钥乱码、校验无效问题
你的代码存在几个明确的逻辑错误,直接导致了乱码和密钥校验失败:
strcpy参数顺序写反+缓冲区长度不足:strcpy的语法是strcpy(目标地址, 源字符串地址),你写的strcpy(newchar, private_key)完全颠倒了方向。且private_key是定义在栈上长度20的未初始化数组,内存里全是随机垃圾值,这行代码不仅没把randstring生成的合法随机串存入private_key,还把垃圾值写入了堆内存。后续打印从未被正确赋值的private_key时,读到无效字节就会显示带问号的三角形替换字符。另外randstring生成长度为20的字符串时会额外分配1字节存字符串结束符\0,总长度21字节,你定义的private_key只有20字节,哪怕复制方向写对也会触发栈溢出。- 随机数未初始化:你没有调用
srand()设置随机数种子,每次程序运行rand()生成的序列完全固定,生成的密钥不具备随机性。 - 密钥比对逻辑错误:你用
strncmp仅比对密钥前3位,且fgets()读取用户输入时会将行尾的换行符\n一并存入缓冲区,和不带换行符的原始密钥比对必然不匹配,会一直提示密钥无效。另外解密成功后没有退出循环的逻辑,程序会无限要求输入密钥。
对应核心修正代码如下,记得额外引入<time.h>头文件用于生成随机种子:
// main函数中对应片段修改 srand((unsigned int)time(NULL)); // 初始化随机数种子 int tempint = 20; char *newchar = randstring(tempint); char private_key[21]; // 多分配1字节存字符串结束符 strcpy(private_key, newchar); // 修正复制方向:把生成的随机串复制到private_key free(newchar); // 释放堆内存,避免泄漏 char check_for_privatekey[21]; char text_to_encrypt[20]; printf("Enter text to encrypt: "); if (fgets(text_to_encrypt, 20, stdin) == NULL) { printf("Input error.\n"); exit(1); } // 可选:去掉输入明文末尾的换行符 char *text_newline = strchr(text_to_encrypt, '\n'); if (text_newline) *text_newline = '\0'; printf("Encrypting string->%s\n", text_to_encrypt); puts("This is where private_key is assigned"); printf("Your private key is:%s\n", private_key); // 这里后续可以加清屏逻辑 while(1) { printf("Enter private key: \n"); if (fgets(check_for_privatekey, 21, stdin) == NULL) { printf("Input error.\n"); exit(1); } // 去掉用户输入密钥末尾的换行符 char *key_newline = strchr(check_for_privatekey, '\n'); if (key_newline) *key_newline = '\0'; if (strcmp(check_for_privatekey, private_key) == 0) // 比对完整密钥 { printf("String decrypted\n ##%s", text_to_encrypt); break; // 解密成功后退出循环 } else { printf("Invalid key\n"); } }
终端清屏实现
可以通过系统宏判断当前运行环境,调用对应系统的原生清屏命令,在提示用户确认记录密钥后执行清屏即可,不要在密钥刚生成就清屏导致用户看不到密钥:
// 自定义跨平台清屏函数 void clear_screen() { #ifdef _WIN32 system("cls"); // Windows系统执行cls清屏 #else system("clear"); // Linux/macOS类Unix系统执行clear清屏 #endif }
使用示例,放在打印密钥的代码之后:
printf("Your private key is:%s\n", private_key); printf("确认已保存密钥后按回车键继续..."); getchar(); // 等待用户确认 clear_screen(); // 执行清屏
内容的提问来源于stack exchange,提问作者Anton Tonchev
相关产品推荐
相关产品推荐

