簡體   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