我正在使用一个Shit Cipher并解密一段特定的文本。好的,那么,程序是如何工作的:
现在,我已经完成了这个,但是,我知道角色不能总是移位9个位置,所以程序会查看字符在字母字符数组中的位置然后如果可以完成,它只是添加9,如果无法完成,只需要9个(找出差异)。但是,它不起作用,我无法弄清楚我哪里出错了。
以下是代码:
#include <iostream>
#include <fstream>
using namespace std;
string inputFile = "";
#define MAX_FILE_SIZE 10000
const char alphabet[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
const char alphabetUpper[26] =
{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
const int sizeAlpha = sizeof(alphabet)/sizeof(alphabet[0]);
void Data(char* theData)
{
ifstream txtFile(inputFile.c_str());
if(!txtFile.is_open())
{
cerr << "Cannot open text file";
}
txtFile.read(theData, 520);
}
int main(int argc, char *argv[]) {
char getData[MAX_FILE_SIZE];
Data(getData);
char decrypted[520];
int algorthm;
for(unsigned i=0; (i < 520); i++)
{
for(unsigned j=0; (j < 26); j++)
{
if(getData[i] == alphabet[j] || alphabetUpper[j])
{
algorthm = j + 9; // we move 9 places.
if(sizeAlpha < algorthm)
{
decrypted[i] = alphabet[algorthm];
}else if(algorthm > sizeAlpha || algorthm == sizeAlpha)
{
algorthm = sizeAlpha - j;
decrypted[i] = alphabet[algorthm];
}
}
}
}
for(unsigned i=0; (i < 520); i++)
{
cout << decrypted[i];
}
}
任何人都知道我哪里出错了,或者,可以提供类似的解决方案吗?
答案 0 :(得分:3)
你需要做模数:
algorthm = (j + 9) % 26;
如果你带走9来处理溢出,那么你将引入与其他角色的冲突,并且不会使用前9个位置。
[edit] 只是指出......
你的if语句也有问题:
if(getData[i] == alphabet[j] || alphabetUpper[j])
这不会像你想象的那样起作用,如果它确实你的算法无论如何都不会起作用,因为你以后不会区分大小写。您必须复制代码或设置指向正确数组的指针。但这还有很长的路要走。
您无需搜索字母字符数组即可进行测试。任何合理的字符编码(我会说ASCII是目前最常见的)将保持字母字符顺序。所以:
const int shiftAmt = 9;
char c = getData[i];
if( c >= 'A' && c <= 'Z' )
c = 'A' + ((c - 'A' + shiftAmt) % 26);
else if( c >= 'a' && c <= 'z' )
c = 'a' + ((c - 'a' + shiftAmt) % 26);
decrypted[i] = c;
请注意,这也保留了任何非字母字符,而您的代码忘记了它们,并将“解密”数组中的位置保留为未初始化。
答案 1 :(得分:2)
如果可以,它只会增加9,如果无法完成,只需要9个
这不可能是可逆的,因为你将两个不同的值映射到同一个值。
相反,你必须环顾四周:
unsigned char shiftChar(unsigned char const plain, signed char const by) {
unsigned char const caseBit = plain & ('a' ^ 'A');
unsigned char offset = (plain ^ caseBit) - ('a' & 'A');
offset += ('z' - 'a' + 1) + by; // there's your "shift"
offset %= ('z' - 'a' + 1);
return caseBit | (offset + ('a' & 'A'));
}