Encryption 在C中更改和包装关键字整数而不使用循环

Encryption 在C中更改和包装关键字整数而不使用循环,encryption,cs50,vigenere,Encryption,Cs50,Vigenere,我正在编写一个程序,在命令提示符下接受一个字符串,然后将字符串中的每个字符转换为字母表中相应的0-25位数字。然后,在程序提示后,每个数字用于对用户输入的另一个字符串的每个字符进行加密。第二个字符串的每个字母字符应与整数字符串的顺序匹配,如果第二个字符串较长,则整数字符串将换行。该程序的目标是使用第一个字符串作为键来移动消息的每个字符(第二个字符串) 示例(所需输出): 用户运行程序并输入关键字:bad 提示用户仅输入字母字符和标点符号:Dr.Oz 程序将关键字“bad”转换为1,0,3 程序将

我正在编写一个程序,在命令提示符下接受一个字符串,然后将字符串中的每个字符转换为字母表中相应的0-25位数字。然后,在程序提示后,每个数字用于对用户输入的另一个字符串的每个字符进行加密。第二个字符串的每个字母字符应与整数字符串的顺序匹配,如果第二个字符串较长,则整数字符串将换行。该程序的目标是使用第一个字符串作为键来移动消息的每个字符(第二个字符串)

示例(所需输出): 用户运行程序并输入关键字:
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