C 中的 Vigenere 代码因多字符键而崩溃
Posted
技术标签:
【中文标题】C 中的 Vigenere 代码因多字符键而崩溃【英文标题】:Vigenere code in C crashes with a multi-character key 【发布时间】:2015-10-26 12:45:53 【问题描述】:如果我使用一个字符长键一切正常,但如果我使用更长的键程序崩溃。 对于此输入:'2A282E2A282E' 应该输出这个:'aaaaaa'
#include <stdio.h>
#define KL 3
main()
unsigned char ch;
FILE *fpIn, *fpOut;
int i;
unsigned char key[KL] = 0x4B, 0x49, 0x4F;
fpIn = fopen("ctext.txt", "r");
fpOut = fopen("dtext.txt", "w");
i=0;
while(fscanf(fpIn, "%02X", &ch) != EOF)
fprintf(fpOut, "%c", ch ^ key[i % KL]);
i++;
fclose(fpIn);
fclose(fpOut);
return(0) ;
【问题讨论】:
您应该在调试器中运行您的程序,这样您就可以准确地看到它崩溃的位置,然后还能够检查是否存在变量的内容。 你知道^
是做什么的吗?
另外,编译您的程序并启用警告。当我使用 GCC 编译您的程序时,我收到警告“格式 '%X' 需要 'unsigned int *' 类型的参数,但参数 3 的类型为 'unsigned char *'”。这是一个可能导致崩溃的错误。
测试fscanf(fpIn, "%02X", &ch)
与EOF
的返回值可能不是一个好主意。如果由于其他原因转换失败并返回零怎么办?我会写while(fscanf(fpIn, "%02X", &ch) == 1)
代替(或者%02hhX
可能是char
变量)。
试试unsigned char ch ;
--> unsigned ch ;
【参考方案1】:
当我使用 GCC 编译您的程序时,我收到警告“格式 '%X' 需要 'unsigned int *' 类型的参数,但参数 3 的类型为 'unsigned char *'”。这是一个可能导致崩溃的错误,因为 char 通常是一个字节宽,而 int 通常是四个字节。 fscanf 将尝试将四个字节的数据放入您的单字节空间中,并愉快地覆盖后面的任何数据。
正如 BLUEPIXY 在评论中建议的那样,您可以将您的 unsigned char ch
替换为 unsigned ch
。
除此之外,当我尝试它时它可以工作,我没有发现其他明显的问题,除了你应该检查 fopen 的返回值。
【讨论】:
【参考方案2】:我必须使用 '%c' 而不是 '%02X' 来读取并将字符转换为十六进制值。 最终代码解决:
#include <stdio.h>
#define KL 3
int ctox(char c) //this is the convertin part
if(c>='0'&&c<='9') return c-'0';
return 10+c-'A';
main()
unsigned char ch, c1, c2;
FILE *fpIn, *fpOut;
int i=0;
unsigned char key[KL] = 0x4B, 0x49, 0x4F ;
fpIn = fopen("ctext.txt", "r");
fpOut = fopen("dtext.txt", "w");
while(fscanf(fpIn, "%c%c", &c1, &c2) != EOF) //the read in part corrected
ch = 16*ctox(c1) + ctox(c2);
printf("HEX %c%c ", c1, c2);
printf("DEC %3d ", ch); // this three line just for examination
printf("i %d\n", i);
fprintf(fpOut, "%c", ch^key[i % KL ] ) ;
i++;
fclose(fpIn);
fclose(fpOut);
return(0) ;
谢谢大家。
【讨论】:
以上是关于C 中的 Vigenere 代码因多字符键而崩溃的主要内容,如果未能解决你的问题,请参考以下文章