【发布时间】:2022-07-14 23:27:55
【问题描述】:
程序必须通过命令行中的密钥加密明文。
如果 p 是一些明文,k 是关键字(即字母字符串,其中 A(或 a)表示 0,B(或 b)表示 1,C(或 c)表示 2,……,Z(或 z) 表示 25),则密文 c 中的每个字母 ci 计算如下:
ci = (pi + kj) % 26
注意这个密码使用 kj 而不是 k。如果 k 比 p 短,那么 k 中的字母必须循环重复使用尽可能多的次数来加密 p。
换句话说,如果 Vigenère 自己想秘密地向某人打招呼,使用 ABC 等关键字,他会用 0 的密钥(即 A)加密 H,用 1 的密钥加密 E (即 B)和第一个 L 的密钥为 2(即 C),此时他将在关键字中没有字母,因此他将重用(部分)它来加密第二个L 再次带有 0 键(即 A),O 再次带有 1 键(即 B)。因此,他将 HELLO 写为 HFNLP,如下所示: 这样:
plaintext H E L L O
+key A B C A B
(shift value) 0 1 2 0 1
= ciphertext H F N L P
例如:
$ ./vigenere bacon
plaintext: Meet me at the park at eleven am
ciphertext: Negh zf av huf pcfx bt gzrwep oz
我的情况:
键: baz
明文: barfoo
预期: caqgon
我的结果: caqfgv
我的代码:
#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
// Functions:
bool check_arguments(int argc);
bool is_key_alpha(string key);
int shift(char c);
int main(int argc, string argv[])
{
if (check_arguments(argc) == false)
{
return 1;
}
// Declaring key string variable:
string key = argv[1];
// Check containing any character that is not an alphabetic character
if (is_key_alpha(key) == false)
{
return 1;
}
// Prompting user for plaintext:
string plaintext = get_string("plaintext: ");
// Ecipher:
printf("ciphertext: ");
for (int i = 0; i < strlen(plaintext); i++)
{
if (islower(plaintext[i]))
{
printf("%c", ((plaintext[i]) - 97 + shift(key[i])) % 26 + 97);
}
else if (isupper(plaintext[i]))
{
printf("%c", ((plaintext[i]) - 65 + shift(key[i])) % 26 + 65);
}
else
{
printf("%c", plaintext[i]);
}
}
printf("\n");
return 0;
}
// FUNCTIONS :
// Checking if there's more than one command-line argument
// Checking if the command-line argument exists:
bool check_arguments(int argc)
{
// Checking if there's more than one command-line argument
if (argc > 2)
{
printf("Usage: ./vigenere keyword\n\n");
return false;
}
// Checking if the command-line argument exists:
else if (argc < 2)
{
printf("Usage: ./vigenere keyword\n");
return false;
}
// If okey:
else
{
return true;
}
}
// containing any character that is not an alphabetic character
bool is_key_alpha(string key)
{
for (int i = 0; i < strlen(key); i++)
{
if (isalpha(key[i]) == false)
{
printf("Key contains non-alphabetical chars");
return false;
}
}
return true;
}
// convert character into the correct shift value
int shift(char c)
{ // for ex. char = a == 97 ascii
if (isalpha(c))
{
if (isupper(c))
// The ASCII value of A is 65
{
c = c - 65;
}
else if (islower(c))
// The ASCII value of a is 97
{
c = c - 97;
}
}
else
{
return c;
}
return c;
}
【问题讨论】:
-
请注意,
key[i]在您的示例中i >= 4时未定义。你的意思可能是i%strlen(plaintext)或什么的 -
巴里走在正确的轨道上。它是 UB。在我的系统上,我得到了:
caqflr将:shift(key[i])更改为shift(key[i % strlen(key)]) -
旁注:
for (int i = 0; i < strlen(plaintext); i++)需要二次时间 (O(n^2)) 来执行。将其替换为:for (int i = 0; plaintext[i] != 0; i++),这只是 O(n)
标签: c for-loop encryption cs50