gpt4 book ai didi

c - Vigenere Cipher - 公式解释

转载 作者:太空宇宙 更新时间:2023-11-04 03:25:08 26 4
gpt4 key购买 nike

首先我没有人可以问这种问题所以请原谅我

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

int main(int argc, string argv[]) {
string key = argv[1];
int l = strlen(argv[1]);
if (argc != 2) {
return 0;
}
for (int i = 0, n = strlen(key); i < n; i++) {
if (!isalpha(key[i])) {
return 0;
}
key[i] = tolower(key[i]);
key[i] = key[i] - 97;
}
string txt = GetString();
for (int k = 0, p = strlen(txt); k < p; k++) {
if (isalpha(txt[k])) {
if (isupper(txt[k])) {
printf("%c", (((txt[k] - 65) + (key[k % l])) % 26 + 65));
}
if (islower(txt[k])) {
printf("%c", (((txt[k] - 97) + (key[k % l])) % 26 + 97));
}
} else
if (!isalpha(txt[k])) {
printf("%c", txt[k]);
}
}
printf("\n");
return 0;
}

我不太明白这两行代码

key[i] = key[i] - 97;
printf("%c", (((txt[k] - 97) + (key[k % l])) % 26 + 97));

对于我们为什么使用第一个以及第二个如何工作,是否有一个简单的解释?

最佳答案

用于 Vigenere 密码的 key 应该全是字母。第一个表达式将字符串转换为偏移量数组,0 表示 a1 表示 b,等等。 97 是 'a' 的 ASCII 码。这样写会更具可读性:

for (int i = 0, n = strlen(key); i < n; i++) {
if (!isalpha((unsigned char)key[i])) {
printf("key '%s' must contain only letters\n", key);
return 1;
}
key[i] = tolower((unsigned char)key[i]);
key[i] = key[i] - 'a';
}

对于第二个表达式,如果字符txt[k]是小写字母,printf("%c", (((txt[k] - 97) + ( key[k % l])) % 26 + 97)); 通过加上移位值计算并打印转置后的字母(key 中的每个字符用作移位值后一个另一个,为 a 移动 0,为 b 移动 1 等)。以下是步骤:

  • 程序计算字母索引txt[k] - 9797'a'的ASCII码,
  • 然后添加移位值 key[k % l],以循环方式循环 key 中的值,
  • 对 26 求模得到 0 到 25 之间的字母索引。
  • 它最后添加 97,即 'a' 的 ASCII 值,以将索引转换回小写字母。

这样写会减少冗余并提高可读性:

for (int i = 0, j = 0; txt[i] != '\0'; i++) {
int c = (unsigned char)txt[i];
if (isupper(c)) {
c = (c - 'A' + key[j++ % l]) % 26 + 'A';
} else
if (islower(c)) {
c = (c - 'a' + key[j++ % l]) % 26 + 'a';
}
putchar(c);
}

另请注意,在检查是否已在命令行上传递了足够的参数之前,不应将 argv[1] 传递给 strlen()

这是程序的修改版本:

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

int main(int argc, string argv[]) {
if (argc != 2) {
printf("missing key argument\n");
return 1;
}
string key = argv[1];
int klen = strlen(key);
if (klen == 0) {
printf("key cannot be empty\n");
return 1;
}
for (int i = 0; i < klen; i++) {
if (!isalpha((unsigned char)key[i])) {
printf("key '%s' must contain only letters\n", key);
return 1;
}
key[i] = tolower((unsigned char)key[i]) - 'a';
}

string txt = GetString();
for (int i = 0, j = 0; txt[i] != '\0'; i++) {
int c = (unsigned char)txt[i];
if (isupper(c)) {
c = (c - 'A' + key[j++ % klen]) % 26 + 'A';
} else
if (islower(c)) {
c = (c - 'a' + key[j++ % klen]) % 26 + 'a';
}
putchar(c);
}
putchar('\n');
return 0;
}

关于c - Vigenere Cipher - 公式解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41784915/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com