使用 ASCII 的 caesar 密码返回 C-cedilla

caesar cipher using ASCII returns C-cedilla

本文关键字:返回 C-cedilla 密码 caesar ASCII 使用      更新时间:2023-10-16

所以我目前正在使用字母表的 ASCII 代码进行凯撒密码程序,其中原始文本将向右移动 6 个字符,但问题是当我输入字母 z 时,它返回 Ç 而不是返回字母 f。这是我到目前为止的代码:

void strEncrypt(string userin)
{
    char wordArray[userin.length()];
    strcpy(wordArray, userin.c_str());
    for (int i=0; i<userin.size(); i++)
    {
        if(wordArray[i]>=65 && wordArray[i]<91)
        {
            wordArray[i] = wordArray[i] + 6;
            if (wordArray[i]>90)
            {
                wordArray[i] = wordArray[i]-26;
            }
        }
        else if(wordArray[i]>=97 && wordArray[i]<123)
        {
            wordArray[i] = wordArray[i] + 6;
            while(wordArray[i]>=123)
            {
                wordArray[i] = wordArray[i]-26;
            }
        }
    cout << wordArray[i];
    }
}

尝试编译并运行它,以便您更清楚地了解我的问题是什么

您正在遭受有符号整数溢出的困扰!

其中很多是依赖于实现/未定义的行为,但撇开这一点,我将解释发生了什么。

您的char类型是有符号的,并保存从 -128127 的值。 'z'的值为 122 。当您添加6,它会变得128...如果它能够代表这个数字。但是,最大值为 127 ,并且溢出。它环绕并变得-128

您可以在添加之前进行检查,以确保字符的值足够低,以便您可以安全地增加它以避免此问题。


具体来说,char是有符号还是无符号取决于实现,signed char只需要保存从-127127的值,而有符号溢出是未定义的行为。

你有一个溢出,使用无符号算术修复你的代码:

unsigned char wordArray[userin.length()];
strcpy((char *) wordArray, userin.c_str());