[英]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.