Vigenere-cipher 错误输出
Vigenere-cipher wrong output
我必须编写 Vigenere 密码,但我的输出看起来有点不同。
输入: Po treti raz sa ohlasi 密钥: euhwa
输出: TI ANEXC YWZ WU VDLEMP 我得到的: TI ANEDM LHV SK SBSWSS
你能帮我看看为什么它不能正常工作吗?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char* vigenere_encrypt(const char* key, const char* text)
{
if(key==NULL || text==NULL)
return NULL;
int i,k,t,j=0;
t = strlen(text);
k = strlen(key);
char* copy=(char*)malloc(strlen(text)+1);
char* enc=(char*)malloc(strlen(text)+1);
char* copykey=(char*)malloc(strlen(key)+1);
for (i=0;i<k;i++)
{
copykey[i]=toupper(key[i]);
}
for (i=0;i<k;i++)
{
if(!(isalpha(copykey[i])))
{
free(copy);
free(copykey);
free(enc);
return NULL;
}
}
for (i=0;i<=t;i++)
{
copy[i]=toupper(text[i]);
}
for (i=0;i<=t;i++)
{
if (isupper(copy[i]))
{
enc[i]=(copy[i]+copykey[j])%26+'A';
j++;
if (j>k)
j=0;
}
else enc[i]=copy[i];
}
free(copy);
free(copykey);
return enc;
}
int main()
{
char* encrypted;
encrypted = vigenere_encrypt("euhwa","Po treti raz sa ohlasi!");
printf("%s\n",encrypted);
free(encrypted);
}
问题是你如何处理:
"Hey, i've finished the key, lets bring j
back to zero"
现在,代码非常混乱,不是为了双重 copy/paste(它可能会发生),而是因为它可以(并且应该)稍微优化一下..
无论如何,您的问题的解决方案很简单:
当 j
是 k
的 >=
时,您应该将 j
设置为零。 equal
部分很重要,因为您希望它在达到密钥长度时为 0。您这样做的方式(仅测试 greater than
)意味着当您到达键的末尾时,您会执行一个额外的循环,该循环使用无效的 copykey
值。如果键的长度等于5 你应该停在 copykey[4]
但额外的循环确实 copykey[5]
这是无效的..而且(不)幸运的是它不会 segfault
你见鬼去吧。
for (i=0;i<=t;i++)
{
if (isupper(copy[i]))
{
enc[i]=(copy[i]+copykey[j])%26+'A';
j++;
if (j >= k)
j=0;
}
else enc[i]=copy[i];
}
我必须编写 Vigenere 密码,但我的输出看起来有点不同。
输入: Po treti raz sa ohlasi 密钥: euhwa
输出: TI ANEXC YWZ WU VDLEMP 我得到的: TI ANEDM LHV SK SBSWSS
你能帮我看看为什么它不能正常工作吗?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char* vigenere_encrypt(const char* key, const char* text)
{
if(key==NULL || text==NULL)
return NULL;
int i,k,t,j=0;
t = strlen(text);
k = strlen(key);
char* copy=(char*)malloc(strlen(text)+1);
char* enc=(char*)malloc(strlen(text)+1);
char* copykey=(char*)malloc(strlen(key)+1);
for (i=0;i<k;i++)
{
copykey[i]=toupper(key[i]);
}
for (i=0;i<k;i++)
{
if(!(isalpha(copykey[i])))
{
free(copy);
free(copykey);
free(enc);
return NULL;
}
}
for (i=0;i<=t;i++)
{
copy[i]=toupper(text[i]);
}
for (i=0;i<=t;i++)
{
if (isupper(copy[i]))
{
enc[i]=(copy[i]+copykey[j])%26+'A';
j++;
if (j>k)
j=0;
}
else enc[i]=copy[i];
}
free(copy);
free(copykey);
return enc;
}
int main()
{
char* encrypted;
encrypted = vigenere_encrypt("euhwa","Po treti raz sa ohlasi!");
printf("%s\n",encrypted);
free(encrypted);
}
问题是你如何处理:
"Hey, i've finished the key, lets bring
j
back to zero"
现在,代码非常混乱,不是为了双重 copy/paste(它可能会发生),而是因为它可以(并且应该)稍微优化一下..
无论如何,您的问题的解决方案很简单:
当 j
是 k
的 >=
时,您应该将 j
设置为零。 equal
部分很重要,因为您希望它在达到密钥长度时为 0。您这样做的方式(仅测试 greater than
)意味着当您到达键的末尾时,您会执行一个额外的循环,该循环使用无效的 copykey
值。如果键的长度等于5 你应该停在 copykey[4]
但额外的循环确实 copykey[5]
这是无效的..而且(不)幸运的是它不会 segfault
你见鬼去吧。
for (i=0;i<=t;i++)
{
if (isupper(copy[i]))
{
enc[i]=(copy[i]+copykey[j])%26+'A';
j++;
if (j >= k)
j=0;
}
else enc[i]=copy[i];
}