繁体   English   中英

vigenere 密码的 C++ 函数仅有时有效(适用于某些输入,跳过其他输入)

[英]C++ function for vigenere cipher only sometimes working (works for some inputs, skips shifts for others)

对于课堂作业,我必须编写一个函数,在辅助函数的可选帮助下,将用户输入字符串通过 vigenere 密码。 我能够使用辅助函数获得部分解决方案,该函数根据字符在字母表中的位置获取字符的正确移位,以及另一个函数,如果字符串中的字符是字母,则将字符串中的字符移位到这个位置。

该程序仅偶尔使用一个示例,即“Hello, world!” 将关键字“cake”正确加密为“Jevpq, Wyvnd!”,但是自动分级器输入的“hDcT+T EtL5V71”和关键字“vpkbncc”返回“cSmU+V OuY5Q71”而不是“cSmU+ G GvG5K71"。 我知道为什么会这样; 每次迭代都会跳过第一个字符,所以“蛋糕”最终变成了“ake”,但是我不知道如何解决这个问题。 这是我的代码:

/*Author: Xavier f.*/

#include <iostream> 
#include <string>  
#include <cctype>  

using namespace std;

int getShift(char c); // helper function that converts chars into their place in the alphabet as an int 
char shiftChar(char c, int rshift); // this function handles the character value shifting part of the problem
string encryptVigenere(string plaintext, string keyword); //implemntation of Vigenere cypher  , needs to loop around keyword


int main(){ 

    string text, key, debug; 
    cout << "Enter a sentence: ";
    getline(cin, text); 
    cout << "Enter the keyword  : "; 
    getline(cin, key); 

    debug = encryptVigenere(text, key);
    cout << "Ciphertext     : " << debug;  

    return 0; 

}

int getShift(char c) { 

    if (isupper(c)) { 

        return (int)c-(int)'A';
    }
    else { 

        return (int)c-(int)'a';

    }


}  

char shiftChar(char c, int rshift) { 

    char shifted;


    if (isalpha(c)) { //if it is a letter

        if (isupper(c)){

            shifted = ((int)c + rshift - 'A')%26 + 'A';        //65-90 for uppercase , 97-122 for lowercase
        } 
        else { //dont have to put condition since if its not uppercase its obviously lowercase  

            shifted = ((int)c + rshift - 'a')%26 + 'a'; 

        } 

        return shifted;
    } 
    else { 

        return c; 

    } 

} 

string encryptVigenere(string plaintext, string keyword){ 

    char encrypted;
    string vigenere; 
    int ciphercount = 0;

        for(int i = 0; i < plaintext.length(); ++i) {

            if(isalpha(plaintext[i])) {

                encrypted = shiftChar(plaintext[i], getShift(keyword[ciphercount])); 
                vigenere += encrypted; 
                ciphercount ++;

            } 
            else { 
                ciphercount -= keyword.length();
                vigenere += plaintext[i]; 
            }
            ciphercount = ciphercount % keyword.length();
        }  

    return vigenere;    

}

就像我之前提到的“你好,世界!” 即使由于某种原因在 for 循环中跳过了 cake 中的第一个字符,示例仍然有效:

Enter a sentence: Hello, world!
Enter the keyword  : cake
Ciphertext     : Jevpq, wyvnd! 

debug: og ciphercount: c/ debug: plaintext[i]: H / debug: keyword[ciphercount]: a / debug: cyphercount isalpha: 1 / debug: encrypted: J / debug: vigenere: J
debug: cyphercount loop through: 1

然而,随着自动分级机的输入,这个问题变得更加灾难性:

Enter a sentence: hDcT+T EtL5V71
Enter the keyword  : vpkbncc
Ciphertext     : cSmU+V OuY5Q71 

debug: og ciphercount: v / debug: plaintext[i]: h / debug: keyword[ciphercount]: p / debug: cyphercount isalpha: 1 / debug: encrypted: c / debug: vigenere: c
debug: cyphercount loop through: 1

输出应该是“cSmU+G GvG5K71”,但由于第一个移位字符被跳过,因此移位的文本是 pkbn_bn_c_p__ 这是错误的。

有谁知道我该如何解决这个问题?

您的问题不在于关键字的第一个字母被忽略(尝试fake而不是cake并确认它确实改变了输出)。

看来您真正的问题在于encryptVigenere函数的编写方式。

我不是密码学专家,我不能告诉你这是否是实现 vigenere 密码的正确方法,但我无法理解这一行:

            ciphercount -= keyword.length();

事实证明,如果您删除它,您将得到您想要的结果。

所以,这是你的新encryptVigenere函数:

string encryptVigenere(string plaintext, string keyword){ 

    char encrypted;
    string vigenere; 
    int ciphercount = 0;

        for(int i = 0; i < plaintext.length(); ++i) {

            if(isalpha(plaintext[i])) {
                encrypted = shiftChar(plaintext[i], getShift(keyword[ciphercount])); 
                vigenere += encrypted; 
                ciphercount ++;
            } 
            else { 
                //ciphercount -= keyword.length();
                vigenere += plaintext[i]; 
            }
            ciphercount = ciphercount % keyword.length();
        }  

    return vigenere;    

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM