Vigenere-cipher 错误输出

Posted

技术标签:

【中文标题】Vigenere-cipher 错误输出【英文标题】:Vigenere-cipher wrong output 【发布时间】:2016-03-27 17:50:45 【问题描述】:

我必须编写 Vigenere 密码,但我的输出看起来有点不同。

输入: Po treti raz sa ohlasi 钥匙: euhwa

输出: TI ANEXC YWZ WU VDLEMP 我得到了什么: TI ANEDM LHV SK SBSWSS

你能帮我看看,为什么它不能正常工作?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

char* vigenere_encrypt(const char* key, const char* text) 

    if(key==NULL || text==NULL)
        return NULL;

    int i,k,t,j=0;
    t = strlen(text);
    k = strlen(key);

    char* copy=(char*)malloc(strlen(text)+1);
    char* enc=(char*)malloc(strlen(text)+1);
    char* copykey=(char*)malloc(strlen(key)+1);

    for (i=0;i<k;i++)
    
        copykey[i]=toupper(key[i]);
    

    for (i=0;i<k;i++)
    
        if(!(isalpha(copykey[i])))
        
            free(copy);
            free(copykey);
            free(enc);
            return NULL;
        
    

    for (i=0;i<=t;i++)
    
        copy[i]=toupper(text[i]);
    

    for (i=0;i<=t;i++)
    
        if (isupper(copy[i]))
        
            enc[i]=(copy[i]+copykey[j])%26+'A';
            j++;
            if (j>k)
                j=0;
        
        else enc[i]=copy[i];
    

    free(copy);
    free(copykey);
    return enc;


int main()

    char* encrypted;
    encrypted = vigenere_encrypt("euhwa","Po treti raz sa ohlasi!");
    printf("%s\n",encrypted);
    free(encrypted);

【问题讨论】:

到目前为止,这段代码看起来很可怕。就像一般提示一样,添加间距,尽量不要像这样:for (i = 0; i &lt; 10; i++) 看起来像这样:for(i=1;&lt;10;i++)。另外,你为什么做一些事情两次或更多次?您正在从i = 0 循环到t 三个不同的时间。前两个正在做完全相同的事情。清理逻辑越多,调试问题就越容易。 另外,既然你肯定是在为 CS50 (cs50.tv) 做这个,你不应该指望别人会给你答案。您应该让我们知道您已经尝试过什么,并且您应该非常清楚这是一项家庭作业。另外:int i,k,t,j=0; 可能不会像你想的那样做。然后你从 i = 0 迭代到 t,这是未定义的! 提示:尝试在密码循环中添加一个printf,这样您就可以看到您使用的charplaintextkey,因为您如何管理关键..(我拿了你的代码并添加了这一行printf("char: %c + %c mod26 + A: %c \n", copy[i], copykey[j], enc[i]); 真的很抱歉。我复制了这部分:"for (i=0;i&lt;=t;i++) copy[i]=toupper(text[i]);" 2 次。下次我会照顾的。抱歉,添麻烦了。我不是为 CS50 这样做的。 【参考方案1】:

问题在于你如何处理:

“嘿,我已经完成了密钥,让j归零”

现在,代码相当混乱,不是因为双重复制/粘贴(可能会发生),而是因为它可以(并且应该)稍微优化..

无论如何,您的问题的解决方案很简单:

j&gt;=k 时,您应该将j 设置为零。 equal 部分很重要,因为您希望在达到密钥长度时它为 0。您这样做的方式(仅测试greater than)意味着当您到达密钥的末尾时,您会执行一个额外的循环,该循环使用无效的copykey 值。如果密钥的长度等于5,您应该停止在copykey[4],但额外的循环执行copykey[5],这是无效的......而且(不)幸运的是它没有segfault你下地狱。

for (i=0;i<=t;i++)

    if (isupper(copy[i]))
    
        enc[i]=(copy[i]+copykey[j])%26+'A';
        j++;
        if (j >= k)
            j=0;
    
    else enc[i]=copy[i];

【讨论】:

非常感谢!我真的很感谢你的帮助!我很感激!

以上是关于Vigenere-cipher 错误输出的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript 中的 Vigenère 密码显示或 � 字符

如何让我的 Vigenère 密码处理消息中的空格?

Python Vigenère密码不起作用

Vigenère密码

PHP 中带有数字的 Vigenére 密码

codevs1197 Vigenère密码