简体   繁体   English

凯撒密码无法正常使用C

[英]Caesar cipher code not working properly C

I've been working on a Caesar cipher problem for a problem set but I ran into a minor problem. 我一直在为一个问题集解决凯撒密码问题,但遇到一个小问题。 Whenever the cipher value gets more the the ascii of 'z', I want it to bounce back to 'a' but I'm not able to figure out how to do so. 每当密码值变得比“ z”的ascii大时,我希望它反弹回“ a”,但我不知道该怎么做。 Here is the code: 这是代码:

#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]);
    }

}

This is quite a basic code. 这是相当基本的代码。 Any help will be appreciated. 任何帮助将不胜感激。

PS here is an example with key 4. 此处的PS是键4的示例。

input-  Vinay Dawani
output- Zmre} He{erm

Assuming that the code set in use is not EBCDIC (which has non-alphabetic characters in between alphabetic characters), then letters of the Latin alphabet (unaccented az) are coded as contiguous code points in all the common code sets. 假定使用的代码集不是EBCDIC (在字母字符之间具有非字母字符),则在所有通用代码集中将拉丁字母(无重音az)编码为连续的代码点。 The rotation of the alphabet is simple when you know how. 当您知道如何旋转字母时,它很简单。

Fundamentally, you convert each letter into an offset 0..25 from the letter a or A (depending on case), add the encoding key, take the result modulo 26, and add the starting letter ( a or A ) back. 从根本上讲,您可以将每个字母转换为相对于字母aA的偏移量0..25(取决于大小写),添加编码键,将结果取模26,然后再添加起始字母( aA )。 Note that the arithmetic takes place as int , but the result is assigned back to a (possibly signed) char . 请注意,算术以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;
}

Example run: 示例运行:

$ ./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?]
$

The CS50 library is readily available online. CS50库可随时在线获得。

After you add k to the letter, check if it's higher than z . k添加到字母后,检查它是否大于z If it is, just subtract the number of letters in the alphabet to wrap it around. 如果是这样,只需减去字母表中的字母数即可。

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

to deal with upper and lower case, you need separate tests in the main loop. 为了处理大小写,您需要在主循环中进行单独的测试。

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]);
}

Notice that I removed the test for if (s[i] == ' ') . 注意,我删除了if (s[i] == ' ') That's not necessary -- anything that isn't a letter is simply left alone. 没必要-凡是不是字母的东西都将被单独留下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM