Vigenere Cipher 只能在处理 C 中的空格(“”)之前有效 - 为啥?
Posted
技术标签:
【中文标题】Vigenere Cipher 只能在处理 C 中的空格(“”)之前有效 - 为啥?【英文标题】:Vigenere Cipher only works up until dealing with a space(" ") in C - why?Vigenere Cipher 只能在处理 C 中的空格(“”)之前有效 - 为什么? 【发布时间】:2016-01-20 21:00:23 【问题描述】: #include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int main(int argc, string argv[])
string k = argv[1];
string s = GetString();
int l = strlen(k);
for(int i = 0, n = strlen(s); i < n; i++)
if(s[i] >= 65 && s[i] <= 90)
int i2 = ((s[i]-65) + (k[i%l]-97)) % 26;
printf("%c", i2+65);
else if(s[i] >= 97 && s[i] <= 122)
int i2 = ((s[i]-97) + (k[i%l]-97)) % 26;
printf("%c", i2+97);
else
printf("%c", s[i]);
printf("\n");
return 0;
为了使代码与问题更相关,我已尽可能多地删除了部分。基本上为什么当“s”中没有任何空格(“”)并且当“s”由空格(“”)组成时,这段代码可以工作?
你们中的大多数人可能都知道,在 argv[1] 中输入的参数是密码的“关键字”。然后用户输入一个“纯文本”来加密。当我尝试使用各种单词或句子时,如果它不包含任何空格“”,它就会起作用。我只是不明白这背后的逻辑。如果s[i]
不是前两个条件之一,为什么循环会中断 - 我原以为“其他”条件会起作用。
如果有人能对此有所了解,我将不胜感激 - 非常感谢!
ps:我知道顶部有一些额外的库,argv[1]
的用户输入未通过isalpha()
进行验证。我现在只想更好地了解循环过程,我已经准备好将这些检查放在另一个文件中。
【问题讨论】:
建议使用'a'
和'z'
(以及'A'
和'Z'
)代替数字。
您的GetString
函数是如何工作的? '当“s”包含空格(“”)'是什么意思?
当您处理非字母字符时,您会跳过密钥中的一个字母,因为您使用i
来逐步检查密钥和要加密的数据。您需要使用单独的索引。
@nsilent22: GetString()
是包含<cs50.h>
标头时的半标准函数。你可以很容易地在网上找到源代码;它经常出现在 SO 上。
编程中的一般规则:不要使用幻数。
【参考方案1】:
这是实现我所做的“字符串和键的单独计数器”注释的代码。它还使用字母代码'a'
和'A'
(并避免使用'z'
或'Z'
)而不是使用数字。它确实假设您正在处理一个单字节代码集(不是 UTF-8,除非您在 ASCII 范围内工作),其中小写和大写字母都在一个连续的范围内(所以它不会t 与 EBCDIC 一起可靠地工作,但与大多数其他代码集一起工作),并且它也忽略重音字符。 (它必须通过setlocale("")
来获得特定于语言环境的对哪些字符是字母的解释。)
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int main(int argc, string argv[])
if (argc != 2)
fprintf(stderr, "Usage: %s key\n", argv[0]);
return 1;
string k = argv[1];
int l = strlen(k);
for (int i = 0; i < l; i++)
int c = k[i];
if (!isalpha(c))
fprintf(stderr, "%s: non-alpha character %c in key string\n", argv[0], c);
return 1;
k[i] = tolower(c);
printf("Enter a string to be encrypted:\n");
string s = GetString();
int n = strlen(s);
for (int i = 0, j = 0; i < n; i++)
int c = (unsigned char)s[i];
if (isupper(c))
c = ((c - 'A') + (k[j++ % l] - 'a')) % 26 + 'A';
else if (islower(c))
c = ((c - 'a') + (k[j++ % l] - 'a')) % 26 + 'a';
putchar(c);
putchar('\n');
return 0;
这是一个示例运行,它展示了使用“a”作为此 Vigenere 密码的密钥中的一个字母的弱点:
./vc caesArandAbrAcaDabRa
Enter a string to be encrypted:
It is reported that Caesar said "Veni, vidi, vici" when he conquered Britain.
Kt mk rvpbutfu tjaw Cbvscr wsiu "Vrqi, wzdk, vlcj" nhgn lw cfndxesvd Drltbzn.
【讨论】:
以上是关于Vigenere Cipher 只能在处理 C 中的空格(“”)之前有效 - 为啥?的主要内容,如果未能解决你的问题,请参考以下文章