【问题标题】:Vigenere code in C crashes with a multi-character keyC 中的 Vigenere 代码因多字符键而崩溃
【发布时间】: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 ;

标签: c encryption vigenere


【解决方案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) ;
    }
    

    谢谢大家。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-25
      • 1970-01-01
      • 1970-01-01
      • 2014-05-30
      • 2014-05-04
      • 2023-04-02
      • 2017-10-02
      相关资源
      最近更新 更多