使用正确的ASCII值时,Cs50 Vigenere代码会产生意外输出

时间:2018-04-01 22:51:27

标签: c ascii cs50 vigenere

我已经为cs50中的Vigenere问题编写了这段代码。 但是,当我打印加密的字母时,它不能正常工作,我使用的是58和90而不是65和97.(A和a的ASCII值)

这样做给了我想要的结果但是我不明白它为什么会这样做。当用“a”或“A”减去时,它给了我错误的加密文本,这对我没有任何意义。

我查找了一些不同的解决方案,他们都用'a'或'A'减去字母索引,但这样做对我来说不起作用。

我真的不明白为什么我必须在我的代码中使用这些值,也许任何人都可以帮助我理解出错的地方或我的逻辑错误在哪里。

先谢谢。

编辑:我改变了

k [z] = tolower(k [z]); to k [z] = toupper(k [z] - 'A');

我也改变了

printf(“%c”,(((p [j] - 58)+ k [1%strlen(k)])%26)+'A'); to printf(“%c”,(((p [j] - 'A'-6)+ k [l%strlen(k)])%26)+'A');

-6是因为这给了我正确的输出意味着某些东西仍未关闭

关键:培根

明文:上午十一点在公园见我

预期产出:Negh zf av huf pcfx bt gzrwep oz

-6的实际输出:Negh zf av huf pcfx bt gzrwep oz

实际输出没有-6:Tkmn fl gb nal vild hz mfxckv uf

不知何故,所有值都被-6关闭,我不知道为什么

k.size()也给了我错误所以我保留了strlen()。

int main(int argc,string argv[])
{

//checks if only one argument was typed
if (argc != 2)
{
    printf("Error");
    return 1;
}

//assigns the keyword argv[1] to k
string k = argv[argc -1];
//check if key is alphabetical only
for (int i = 0 , n = strlen(k); i < n; i++)
{
    if(!isalpha(k[i]))
    {
        printf("Key is not alphabetical");
        return 1;
    }
}
printf("Key Valid\n");
//convert key to lowercase only
for(int z = 0; k[z]; z++)
{
    k[z] = tolower(k[z]);
}

string p = get_string("Plaintext: ");
//iterate over p
//l is incremented only when the char is alphabetical and is used as index for k
for (int j = 0,l = 0 , o = strlen(p);j < o ;j++)
{

    if(isalpha(p[j]))
    {
        if(isupper(p[j]))
        {
            //print enciphered letter
            printf("%c",(((p[j]- 58) + k[l % strlen(k)]) % 26) + 'A');
        }
        else if(islower(p[j]))
        {
            //print enciphered letter
            printf("%c",(((p[j]- 90) + k[l % strlen(k)]) % 26 ) + 'a');
        }
        //increment so that next char in k is used
        l++;
    }
    else
    {
        //print unchanged
        printf("%c",p[j]);
    }
}

return 0;
}

1 个答案:

答案 0 :(得分:0)

代码的问题是密钥没有正确规范化。而不是字母&#39; A&#39;在表示值97的键中表示值0.使用您的示例我们应该为&#39; b&#39;应用键值。致信&#39; M&#39;到达编码的字母&#39; N&#39;因为&#39; b&#39;不是1而是98我们必须通过减去97来抵消它。但是因为我们添加了A&#39;最后我们也要通过减去65来抵消它。复合减法是97 + 65 = 162,其模数是162 mod 26 = 6.所以你可以减去6而不是减去58.结果是一样的但是,由于58 mod 26也是6,因此使用58而不是6得到相同的结果。

下一个案例涉及小写字母,因此复合减法为97 + 97 = 194,而194 mod 26 = 12.但是90 mod 26 = 12也是如此,因此您可以使用90而不是12来获得所需的结果。 / p>

为了避免键(97)所需的偏移,您可以使用正确的值构建键(字母值为&#39; A&#39;)。但是你必须在构建密钥之前存储密钥长度,因为函数strlen将停止计数值0(前一个字母&#39; A&#39;)。之后,在编码字母时,案例(65和97)仍有偏移量,但它们的值至少不会令人困惑。

相关问题