我已经用C实现了凯撒密码,尽管算法是有效的,但我不明白为什么(有时)如果我在添加密钥之前没有减去字母表的第一个字母,我会得到一个空值。下面是完整的代码(见第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;
}
有人能解释一下为什么会这样吗?
1条答案
按热度按时间mrphzbgm1#
你需要解释字母表的第一个字母(
a
或A
),因为char
在内部表示为整数(通常只有一个字节,但它取决于编码)。例如,在ASCII中,执行% 26
将导致ASCII表的26个前值中的任何一个,没有一封是真的信希望我说清楚了