在凯撒密码中的最后一个字母之后循环回到字母表开头的逻辑
Logic for looping back to start of alphabet after last letter in Caesar's Cipher
我一直在编写下面的程序作为凯撒密码的实现,除非提供的密钥大于 26,否则它可以工作。问题是一旦值超过 'z' 或 'Z'。
到目前为止我尝试的是嵌套 if
语句和 while
循环,这导致了内存泄漏(LOL),所以我只想说,我被困住了.
程序使用方法:
gcc -o caesar caesar.c -lcs50 -lm && ./caesar key(number)
其中 caesar.c
是文件名。
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
bool input_valid(int count, string arg);
int main(int argc, string argv[])
{
int key;
char final_val;
string string;
char cipher_string[80];
if (!input_valid(argc, argv[1]))
{
printf("Invalid input!\nUSAGE: ./caesar key\n");
return 1;
}
string = get_string("plaintext: ");
key = strtol(argv[1], NULL, 10);
for (int i = 0; i < strlen(string); i++)
{
int ascii_val = (int)string[i];
bool valid_lower_case = (ascii_val + key) >= 'a' && (ascii_val + key) < 'z';
bool valid_upper_case = (ascii_val + key) >= 'A' && (ascii_val + key) < 'Z';
if (isalpha(string[i]))
{
if (valid_lower_case || valid_upper_case)
{
final_val = ascii_val + key;
}
else
{
// loop back to 'a' if ascii_val reaches 'z'
final_val = 'a' + (key - ('z' - (ascii_val - 1)));
}
}
else
{
final_val = ascii_val;
}
cipher_string[i] = final_val;
}
printf("ciphertext: %s\n", cipher_string);
}
bool input_valid(int count, string arg)
{
// input has more args than just the file name
// input is an integer
return count > 1 && isdigit(arg[0]);
}
您是否熟悉 MOD 运算符 %
?
它对实现 "ring-oriented" 数据很有用,例如
array = [0, 1, 2] // "ring"
array[0 % 3] == 0
array[1 % 3] == 1
array[2 % 3] == 2
array[3 % 3] == 0 // "ring" loops back to 0
array[4 % 3] == 1
array[5 % 3] == 2
数学上,就是除法的余数。
10 / 4 # (4 * 2) + 2
10 % 4 == 2
17 / 2 # (2 * 8) + 1
17 % 2 == 1
我一直在编写下面的程序作为凯撒密码的实现,除非提供的密钥大于 26,否则它可以工作。问题是一旦值超过 'z' 或 'Z'。
到目前为止我尝试的是嵌套 if
语句和 while
循环,这导致了内存泄漏(LOL),所以我只想说,我被困住了.
程序使用方法:
gcc -o caesar caesar.c -lcs50 -lm && ./caesar key(number)
其中 caesar.c
是文件名。
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
bool input_valid(int count, string arg);
int main(int argc, string argv[])
{
int key;
char final_val;
string string;
char cipher_string[80];
if (!input_valid(argc, argv[1]))
{
printf("Invalid input!\nUSAGE: ./caesar key\n");
return 1;
}
string = get_string("plaintext: ");
key = strtol(argv[1], NULL, 10);
for (int i = 0; i < strlen(string); i++)
{
int ascii_val = (int)string[i];
bool valid_lower_case = (ascii_val + key) >= 'a' && (ascii_val + key) < 'z';
bool valid_upper_case = (ascii_val + key) >= 'A' && (ascii_val + key) < 'Z';
if (isalpha(string[i]))
{
if (valid_lower_case || valid_upper_case)
{
final_val = ascii_val + key;
}
else
{
// loop back to 'a' if ascii_val reaches 'z'
final_val = 'a' + (key - ('z' - (ascii_val - 1)));
}
}
else
{
final_val = ascii_val;
}
cipher_string[i] = final_val;
}
printf("ciphertext: %s\n", cipher_string);
}
bool input_valid(int count, string arg)
{
// input has more args than just the file name
// input is an integer
return count > 1 && isdigit(arg[0]);
}
您是否熟悉 MOD 运算符 %
?
它对实现 "ring-oriented" 数据很有用,例如
array = [0, 1, 2] // "ring"
array[0 % 3] == 0
array[1 % 3] == 1
array[2 % 3] == 2
array[3 % 3] == 0 // "ring" loops back to 0
array[4 % 3] == 1
array[5 % 3] == 2
数学上,就是除法的余数。
10 / 4 # (4 * 2) + 2
10 % 4 == 2
17 / 2 # (2 * 8) + 1
17 % 2 == 1