首页 > 解决方案 > c中的Ceasar密码错误输出

问题描述

我需要根据基本字符串(即字母表)和整数来移动给定字符串的字母。
该函数的目标是保持在基本字符串内。
示例:

string to shift: a b c
key: -6
output: u v w

但相反,我得到:

output: [ \ ]

这意味着移位是基于 ascii 表而不是基本字符串完成的。
我很难弄清楚为什么?:(

这是代码

#include <stdio.h>
#include <string.h>

void    cesar(char *str, int shift);

int     main(void)
{
    char    str[1001] = "ikio kyz rg ykiutjk vgmk ja robxk";
    char    temp[1001];

    strcpy(temp, str);

    printf("%s\n", str);
    cesar(temp, -6);
    return (0);
}

void    cesar(char *str, int shift)
{
    char    alphabet[27] = "abcdefghijklmnopqrstuvwxyz";
    char    c;
    int     i;

    i = 0;
    while (str[i] != '\0')
    {
        if (str[i] >= 'a' && str[i] <= 'z')
        {
            c = alphabet[i] + (str[i] - alphabet[i] + shift);
            str[i] = c;
        }
        i++;
    }
    printf("%s\n", str);
}

输出:

ceci est la seconde page d[ li\re

代替:

ceci est la seconde page du livre

谢谢^^

标签: ccaesar-cipher

解决方案


这是在没有任何不正确值的情况下实现移位的方法

    if (str[i] >= 'a' && str[i] <= 'z')
    {
        c = str[i] - 'a'; // 0 <= c < 26
        c += shift;       // any value possible (no limits on `shift`)
        while( c < 0 ) c += 26; // no longer negative
        while( c > 25 ) c -= 26; // no longer 26+
        str[i] = c + 'a';
    }

减去a从 ASCII 常量转换为可以由密码操作的字母索引 (0...25) 的值。在末尾添加a会转换回 ASCII。

在进行 %26 检查后,您的代码正在做的是盲目地将移位添加到字母中。这意味着在字母表开头之前出现的字母,并且需要在字母表结尾(测试用例中的“u”和“v”)之后换行。


推荐阅读