0

我正在研究一个 Shit Cipher 并解密一段特定的文本。好的,那么,程序是如何工作的:

  1. 从文本文件中获取字符
  2. 将每个字符在字母表中向下移动 9 位。

现在,我已经这样做了,但是,我知道字符不能总是移动 9 个位置,所以程序会查看字符在字母 char 数组中的位置,然后如果可以完成,它只需添加 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]; 
}
}

任何人都知道我要去哪里错了,或者,可以提供一个类似的解决方案?

4

2 回答 2

3

你需要做模:

algorthm = (j + 9) % 26;

如果你带走 9 来处理溢出,那么你将引入与其他字符的冲突,并且前 9 个位置将不会被使用。

[编辑]只是指出...

您的 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;

请注意,这也保留了任何非字母字符,而您的代码忘记了它们并将该位置留在未初始化的“解密”数组中。

于 2012-08-24T00:08:55.680 回答
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'));
}
于 2012-08-24T00:17:14.213 回答