C语言中Caesar Cipher程序的高级思考

时间:2014-04-28 19:40:38

标签: c encryption

#include <stdio.h>

void caesar (char cipher[], int shift);

int main ()
{

char cipher[200];
int shift;

printf("Enter text to be encrypted (in small letter): ");
gets(cipher);

printf("Number of shift to right? : ");
scanf("%d", &shift);

caesar (cipher, shift);

return 0;
}

void caesar (char cipher[], int shift)
{
int i = 0;

while (cipher[i] != '\0')
{
    if ((cipher[i] + shift) >= 97 && (cipher[i] + shift) <= 122)
    {
        cipher[i] += (shift);
    }
    else
    {
        cipher[i] += (shift - 25);
    }
    i++;
}
printf("%s", cipher);
}

如何忽略空格的操作?我的意思是,我想在转换/解密的字符串中添加空格。当我运行这个程序时,它会从加密字符串中消失空格。我怎样才能做到这一点?假设,&#34;这是一支笔&#34;将成为:&#34; uijt jt b qfo&#34;如果右移1。

1 个答案:

答案 0 :(得分:3)

你应该在转移之前检查一个角色是否是一个字母。您的代码会移动所有内容,并仅检查字符后面是否为有效字母以检测包装。 (它也不会使标点符号和空格消失,它会将它们转换为ASCII值低于32的不可打印字符。)

您还可以使用模运算符强制执行正确的换行:

void caesar(char cipher[], int shift)
{
    char *p = cipher;

    while (*p)
    {
        if ('a' <= *p && *p <= 'z') {
            *p = 'a' + (*p - 'a' + shift) % 26;
        }
        p++;
    }
}

如果您想自动检测换档,只需对所有26个可能的换档使用蛮力并检查常见的预期子串:

int autocaesar(char cipher[])
{
    int shift = 0;

    while (shift < 26) {
        if (strstr(cipher, "the")) return shift;
        if (strstr(cipher, "this")) return shift;
        if (strstr(cipher, "that")) return shift;

        caesar(cipher, 1);
        shift++;
    }

    return -1;
}

函数strstr<string.h>中,并在字符串中查找子字符串。这里做得非常粗暴:"the"不是一个单独的词。此外,该检查区分大小写。

请注意,密码每次移动一个字符,因为原始字符串将连续移动。如果找不到任何操作系统,它将被包裹以包含原始字符串。