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", &amp;ch)EOF 的返回值可能不是一个好主意。如果由于其他原因转换失败并返回零怎么办?我会写while(fscanf(fpIn, "%02X", &amp;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 代码因多字符键而崩溃的主要内容,如果未能解决你的问题,请参考以下文章

使用亚马逊管道的红移副本因缺少主键而失败

trap

CREATE UNIQUE INDEX 语句因发现重复键而终止 EF

c ++中的vigenere cypher

C++ 中的 Vigenere 密码错误

Vigenere Cipher - 如何忽略纯文本中的空格(在 C 中)?