Encryption 在C中更改和包装关键字整数而不使用循环
我正在编写一个程序,在命令提示符下接受一个字符串,然后将字符串中的每个字符转换为字母表中相应的0-25位数字。然后,在程序提示后,每个数字用于对用户输入的另一个字符串的每个字符进行加密。第二个字符串的每个字母字符应与整数字符串的顺序匹配,如果第二个字符串较长,则整数字符串将换行。该程序的目标是使用第一个字符串作为键来移动消息的每个字符(第二个字符串) 示例(所需输出): 用户运行程序并输入关键字:Encryption 在C中更改和包装关键字整数而不使用循环,encryption,cs50,vigenere,Encryption,Cs50,Vigenere,我正在编写一个程序,在命令提示符下接受一个字符串,然后将字符串中的每个字符转换为字母表中相应的0-25位数字。然后,在程序提示后,每个数字用于对用户输入的另一个字符串的每个字符进行加密。第二个字符串的每个字母字符应与整数字符串的顺序匹配,如果第二个字符串较长,则整数字符串将换行。该程序的目标是使用第一个字符串作为键来移动消息的每个字符(第二个字符串) 示例(所需输出): 用户运行程序并输入关键字:bad 提示用户仅输入字母字符和标点符号:Dr.Oz 程序将关键字“bad”转换为1,0,3 程序将
bad
提示用户仅输入字母字符和标点符号:Dr.Oz
程序将关键字“bad”转换为1,0,3
程序将消息加密到Er中。Ra
我实际上得到的是:
… T.B.S. …
我尝试了很多方法,但不幸的是,我似乎不知道如何在不循环第二条消息的情况下循环和包装密钥。如果你运行这个程序,你就会看到我的问题
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int shift(char key1);
int main(int argc, string argv[]) // user enter number at cmd prompt
{
if (argv[1] == '\0')
{
printf("Usage: ./vigenere keyword\n");
return 1;
}
string key = argv[1]; // declare second arg as string
for (int i = 0, n = strlen(key); i < n; i++)
if (isdigit(key[i]) != 0 || argc != 2)
{
printf("Usage: ./vigenere keyword\n");
return 1;
}
string text = get_string("plaintext: ");
printf("ciphertext: ");
int k;
char t;
for (int j = 0, o = strlen(text); j < o; j++)
{
t = text[j];
for (int i = 0, n = strlen(key); i < n; i++)
{
k = shift(key[i]);
if (isupper(t))
{
t += k;
if (t > 'Z')
{
t -= 26;
}
}
if (islower(t))
{
t += k;
if (t > 'z')
{
t -= 26;
}
}
printf("%c", t);
}
}
printf("\n");
}
int shift(char key1)
{
int k1 = key1;
if (islower(key1))
{
k1 %= 97;
}
if (isupper(key1))
{
k1 %= 65;
}
return k1;
}
#包括
#包括
#包括
#包括
int移位(char键1);
int main(int argc,字符串argv[])//用户在cmd提示符下输入数字
{
如果(argv[1]=='\0')
{
printf(“用法:./vigenere关键字\n”);
返回1;
}
string key=argv[1];//将第二个arg声明为字符串
for(int i=0,n=strlen(键);iZ')
{
t-=26;
}
}
if(岛下(t))
{
t+=k;
如果(t>z')
{
t-=26;
}
}
printf(“%c”,t);
}
}
printf(“\n”);
}
整数移位(字符键1)
{
int k1=键1;
如果(孤岛(键1))
{
k1%=97;
}
如果(isupper(键1))
{
k1%=65;
}
返回k1;
}
我感谢您的帮助和建议,但请记住,解决方案应该与我的程序建议的编码水平相匹配。编写此程序可能有许多高级方法,但不幸的是,我们仍处于本课程的开始阶段,因此展示新方法(我一定会尝试理解)可能会让我不知所措。这是您的代码的修改版本,根据我的评论进行了更改:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int shift(char key1);
int main(int argc, string argv[]) // user enter number at cmd prompt
{
if (argc != 2 || argv[1][0] == '\0')
{
fprintf(stderr, "Usage: ./vigenere keyword\n");
return 1;
}
string key = argv[1]; // declare second arg as string
for (int i = 0, n = strlen(key); i < n; i++)
{
if (!isalpha(key[i]))
{
fprintf(stderr, "Usage: ./vigenere keyword\n");
return 1;
}
}
string text = get_string("plain text: ");
printf("ciphertext: ");
int keylen = strlen(key);
int keyidx = 0;
for (int j = 0, o = strlen(text); j < o; j++)
{
int t = text[j];
if (isupper(t))
{
int k = shift(key[keyidx++ % keylen]);
t += k;
if (t > 'Z')
t -= 26;
}
else if (islower(t))
{
int k = shift(key[keyidx++ % keylen]);
t += k;
if (t > 'z')
t -= 26;
}
printf("%c", t);
}
printf("\n");
}
int shift(char key1)
{
if (islower(key1))
key1 -= 'a';
if (isupper(key1))
key1 -= 'A';
return key1;
}
解密密钥是通过将数据第1行中的“加密”字母与第2行中的解密字母匹配而得到的:
abcdefghijklmnopqrstuvwxyz
azyxwvutsrqponmlkjihgfedcb
对于加密和解密,对代码最基本的acid测试是,给定正确的解密密钥和密码文本,程序可以解密其自己的加密输出。如果单击,您将发现许多与您的类似的程序。您可能可以在其中找到解决方案。如果(argv[1]='\0')不是完全错误的,但最好使用
0
或NULL
-'\0'
编写该行,因为它是一个非常规但有效的空指针常量。但你不是在比较一个角色;您正在比较字符指针和空指针。同样地,argc!=2
下一个循环中的测试并不是完全错误的,但是重复测试是不必要的,因为它在循环中,并且在初始测试中可能会更好:如果(argc!=2 | | | argv[1]==NULL | | argv[1][0]='\0')
(对非空的第一个参数进行额外测试)。您需要删除内部循环的循环控件,但保留相当数量的内部循环体。您可以使用j
计算正确的键索引;您还可以知道键的长度(称之为keylen
)。您将找到与j%keylen
一起使用的键的正确元素(因此,对于3字符键,您将依次使用值0、1、2)。shift中的代码可以使用减法,而不是模运算符-我以前没有见过这种方法,但我认为它确实有效,但可能不如k1-=“a”干净代码>或k1-=“A”代码>。您的验证可能应该使用isalpha()
进行检查。编码非常有趣。正是这一部分使这个计划得以实施。int k=shift(键[keyidx++%keylen])谢谢Jonathan!你教了我一些新东西。
abcdefghijklmnopqrstuvwxyz
azyxwvutsrqponmlkjihgfedcb