现在已经有很长一段时间了,似乎没什么用。我需要创建一个Vigenere密码,它接收一个关键字作为argy [1],然后得到一个字符串并使用这两个,做一个Vigenere cypher做的事情,其中关键字中的字母A和a对应于0的移位并且z和Z对应于25的移位。必须保留案例(上部和下部),并且字符串中的任何非字母字符都不能被加密,因此关键字本身的字母不应该用到下一个字母性格在那里。那是基本的纲要......
我会发布我的代码。请不要专注于问题背后的实际数学(我可以自己解决这个问题),而是使用模数和我的循环。现在我只是在处理如果字符串中的字符是小写的情况。
程序编译并且似乎使用单字母组合,而使用'b'的argv [1]和字符串'a',输出为'b'。但是,两个字母的关键字会产生更多的加密字母,然后是字符串中的字母(我该如何解决这个问题)。此外,我很难让关键字在用完它的所有字母时包围第一个字母(在字符串中更多的字母字符然后是关键字的情况下)。
#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, string argv[])
{
int a = argc;
if (a != 2)
{
return 1;
}
string b = argv [1];
int c = strlen(b);
string m;
for (int d = 0; d < c; d++)
{
if ( isdigit(b[d]) || ispunct(b[d]) || isspace(b[d]) )
{
return 1;
}
}
m = GetString();
for (int i = 0, n = strlen(m); i < n; i++)
{
if (islower(m[i]))
{
for (int j = 0; j <= c; j++)
{
if (j > c)
{
j = 1;
printf("%c", ((m[i]+(b[j]))%26)+85);
}
else
{
printf("%c", ((m[i]+(b[j]))%26)+85);
}
}
}
}
}
答案 0 :(得分:2)
你的问题在于我认为关键的循环。 Vingenere密码使用输入键的每个字符来选择已按该键字符数量旋转的字母表(即:以该字符开头)。您正在遍历数据,但是对于每个数据字符,您还要遍历所有关键字符,您应该选择下一个字符并将键视为偏移索引的循环缓冲区。
您还需要修复缩进并选择合理的变量名称。我添加了一个工作版本。我没有看到const char *
到string
的类型定义。这不是C ++。
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
const char *key = argv[1];
const char *data = argv[2];
int keylen, datalen, keyindex = 0;
if (argc != 3) {
fprintf(stderr, "usage: vig keystring data\n");
return 1;
}
/* validate the key */
keylen = strlen(key);
for (int n = 0; n < keylen; n++)
{
if ( isdigit(key[n]) || ispunct(key[n]) || isspace(key[n]) )
{
fprintf(stderr, "invalid char in key at index %d\n", n);
return 1;
}
}
/* iterate over the data adding a key dependent offset*/
datalen = strlen(data);
for (int i = 0; i < datalen; i++)
{
if (islower(data[i]))
{
printf("%c", ((data[i] + key[keyindex]) % 26) + 85);
/* treat key as circular buffer */
++keyindex;
keyindex %= keylen;
}
}
return 0;
}
测试一下:
C:\Code>vig abc abcd
aced