凯撒密码不能正常工作C.

时间:2016-07-14 01:15:20

标签: c cs50 caesar-cipher

我一直在处理问题集的Caesar密码问题,但我遇到了一个小问题。 每当密码值越来越大于' z'的ascii时,我希望它能够反弹到' a'但我无法弄清楚如何做到这一点。 这是代码:

#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, string argv[])
{
    if(argc !=2 && !isdigit(argv[1]))
    {
        return 1;
    }

    //convert input to int and get the string
    int k = atoi(argv[1]);
    k=k%26;
    //printf("%d" ,k);
    //get he text

    char *s;
    s=GetString();
    int i, n=strlen(s);

    //checking each character
    for(i=0;i<n;i++)
    {
        if(s[i]==' ')
        {
            s[i]=' ';
        }
        else
        {
            s[i]=s[i]+k;
        }
        printf("%c" ,s[i]);
    }

}

这是一个非常基本的代码。任何帮助将不胜感激。

P.S。这是一个关键4的例子。

input-  Vinay Dawani
output- Zmre} He{erm

2 个答案:

答案 0 :(得分:0)

假设使用的代码集不是EBCDIC(字母字符之间有非字母字符),那么拉丁字母(unaccented az)的字母被编码为所有常见字母中的连续代码点代码集。当你知道如何时,字母表的旋转很简单。

从根本上说,您将每个字母转换为字母aA的偏移0..25(取决于大小写),添加编码密钥,取结果模26,然后添加首字母(aA)返回。请注意,算法发生在int,但结果会被分配回(可能已签名)char

#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, string argv[])
{
    if (argc != 2 || !isdigit((unsigned char)argv[1][0]))
    {
        fprintf(stderr, "Usage: %s shift\n", argv[0]);
        return 1;
    }

    // convert input to int and get the string
    int k = atoi(argv[1]) % 26;
    if (k < 0)
        k += 26;

    char *s = GetString();
    int n = strlen(s);

    printf("Original:  [%s]\n", s);

    // encoding each character
    for (int i = 0; i < n; i++)
    {
        if (isupper((unsigned char)s[i]))
        {
            s[i] = 'A' + (s[i] - 'A' + k) % 26;
        }
        else if (islower((unsigned char)s[i]))
        {
            s[i] = 'a' + (s[i] - 'a' + k) % 26;
        }
    }

    printf("Encrypted: [%s]\n", s);
    return 0;
}

示例运行:

$ ./caesar13 3
Caesar's cipher is hardly secure against the lazy dog jumping over the quick brown fox, is it?
Original:  [Caesar's cipher is hardly secure against the lazy dog jumping over the quick brown fox, is it?]
Encrypted: [Fdhvdu'v flskhu lv kdugob vhfxuh djdlqvw wkh odcb grj mxpslqj ryhu wkh txlfn eurzq ira, lv lw?]
$ ./caesar50 23
Fdhvdu'v flskhu lv kdugob vhfxuh djdlqvw wkh odcb grj mxpslqj ryhu wkh txlfn eurzq ira, lv lw?
Original:  [Fdhvdu'v flskhu lv kdugob vhfxuh djdlqvw wkh odcb grj mxpslqj ryhu wkh txlfn eurzq ira, lv lw?]
Encrypted: [Caesar's cipher is hardly secure against the lazy dog jumping over the quick brown fox, is it?]
$

CS50 library随时可在线获取。

答案 1 :(得分:-1)

在信中添加k后,请检查它是否高于z。如果是,只需减去字母表中的字母数量即可将其包裹起来。

s[i] = s[i]+k;
if (s[i] > 'z') {
    s[i] = s[i] - 26;
}

要处理大写和小写,你需要在主循环中进行单独的测试。

for(i=0;i<n;i++)
{
    if(islower(s[i]))
    {
        s[i] += k;
        if (s[i] > 'z') {
            s[i] -= 26;
        }
    }
    else if (isupper(s[i]))
    {
        s[i] += k;
        if (s[i] > 'Z') {
            s[i] -= 26;
        }
    }
    printf("%c" ,s[i]);
}

请注意,我删除了if (s[i] == ' ')的测试。这不是必要的 - 任何不是一封信的东西都是孤零零的。