【问题标题】:Why I am getting an empty value in this implementation of Caesar's cipher?为什么我在凯撒密码的这个实现中得到一个空值?
【发布时间】:2020-10-16 23:05:21
【问题描述】:

我已经在 C 中实现了Caesar's cipher,尽管该算法有效,但我不明白为什么(有时)如果在添加之前不减去字母表的第一个字母,我会得到一个空值钥匙。以下是完整代码(见第 59 行或搜索return (letter + k) % 26):

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

string caesar_cipher(string text, int k);
char replace_letter(char letter, int k);
bool is_numeric(string input);

int main(int argc, string argv[])
{
    if (argc != 2 || (argc == 2 && !is_numeric(argv[1])))
    {
        fprintf(stderr, "You must specify a key to the cipher! Exiting...\n");
        exit(EXIT_FAILURE);
    }

    // Convert command line argument to integer.
    int k = atoi(argv[1]);

    // Prompts user for the text to encrypt
    string text = get_string("plaintext: ");

    // Returns encrypted text
    printf("ciphertext: %s\n", caesar_cipher(text, k));

    exit(EXIT_SUCCESS);
}

string caesar_cipher(string text, int k)
{
    int text_length = strlen(text);
    string ciphered_text = text;

    for (int i = 0; text[i] != '\0'; i++)
    {
        ciphered_text[i] = replace_letter(text[i], k);
    }

    return ciphered_text;
}

char replace_letter(char letter, int k)
{
    // Early return when 'letter' is a non-alphabetical character
    if (!isalpha(letter))
    {
        return letter;
    }

    char operation_letter = 'a';

    if (isupper(letter))
    {
        operation_letter = 'A';
    }

    // return (letter + k) % 26; // Sometimes, returns an empty value
    return ((letter - operation_letter + k) % 26) + operation_letter;
}

// Loop over characters to check if each one of them is numeric
bool is_numeric(string input)
{
    for (int i = 0; input[i] != '\0'; i++)
    {
        // If character is not numeric
        // returns false.
        if (isdigit(input[i]) == 0)
        {
            return false;
        }
    }

    return true;
}

谁能解释为什么会这样?

【问题讨论】:

  • (letter + k) % 26 可能会变为 0,而 0 表示字符串结束。当第一个字符变为 0 时(例如,明文 = abc 和密钥 = 7),结果将为空。
  • 当它不为空时,你得到的是你所期望的吗?
  • 你知道C是如何存储字符串的吗?因为(letter + k) % 26 将返回一个从 0 到 25 的数字,其中没有一个是字母,其中一个(零)用于标记 C 样式字符串的结尾。

标签: c cs50 ansi caesar-cipher


【解决方案1】:

您需要在函数中考虑字母表的第一个字母(aA),因为 chars 在内部表示为整数(通常只有一个字节,但这取决于编码)。例如,在ASCII 中,执行% 26 将导致ASCII 表的前26 个值中的任何一个,它们都不是实际的字母。希望我说清楚了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-01
    • 2017-06-20
    • 2014-02-28
    • 1970-01-01
    • 2013-10-07
    • 1970-01-01
    • 2014-03-07
    • 2020-05-31
    相关资源
    最近更新 更多