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