我第一次来这里,我是一个非常新手编程的学生,我有一个问题,我找不到任何解决方案。 我正在编写一个代码来做vigenere密码,但我遇到了问题:
首先:输入密钥,让我们说密钥是; “AAA”
第二:要加密的文本,假设文本是:“alligator”
密码应为:
鳄鱼
+
一 + 一个 加密的第一封信; B'/ P>
所有文字:
bmmjhbups
我的问题是如何用更短的abc循环鳄鱼?在我的所有尝试中,当循环传递时,abc变为零,而不是从文本的循环传递abc的长度时开始。 我也尝试过使用strcpy和concatenate,以便abc在alligator上变成相同的strlength,但是由于字符串的乞讨中的奇怪符号,我遇到了strcpy和cat metodes中的问题。 有没有关于循环如何通过更大的循环工作的简单解决方案?
答案 0 :(得分:0)
请看一下这个程序。我认为它做你想要的。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define NUMLETTERS 26
#define BUFSIZE 4096
char *get_input(void);
int main(int argc, char *argv[])
{
char sign = 1;
char const plainmsg[] = "Plain text: ";
// Convert argument into array of shifts
char const *const restrict key = "bbb";
size_t const keylen = strlen(key);
char shifts[keylen];
char const *restrict plaintext = NULL;
for (size_t i = 0; i < keylen; i++) {
if (!(isalpha(key[i]))) {
fprintf(stderr, "Invalid key\n");
return 2;
}
char const charcase = (char) (isupper(key[i])) ? 'A' : 'a';
// If decrypting, shifts will be negative.
// This line would turn "bacon" into {1, 0, 2, 14, 13}
shifts[i] = (key[i] - charcase) * sign;
}
do {
fflush(stdout);
// Print "Plain text: " if encrypting and "Cipher text: " if
// decrypting
printf("%s", plainmsg);
plaintext = get_input();
if (plaintext == NULL) {
fprintf(stderr, "Error getting input\n");
return 4;
}
} while (strcmp(plaintext, "") == 0); // Reprompt if entry is empty
size_t const plainlen = strlen(plaintext);
char* const restrict ciphertext = calloc(plainlen + 1, sizeof *ciphertext);
if (ciphertext == NULL) {
fprintf(stderr, "Memory error\n");
return 5;
}
for (size_t i = 0, j = 0; i < plainlen; i++) {
// Skip non-alphabetical characters
if (!(isalpha(plaintext[i]))) {
ciphertext[i] = plaintext[i];
continue;
}
// Check case
char const charcase = (isupper(plaintext[i])) ? 'A' : 'a';
// Wrapping conversion algorithm
ciphertext[i] = ((plaintext[i] + shifts[j] - charcase + NUMLETTERS) % NUMLETTERS) + charcase;
j = (j+1) % keylen;
}
ciphertext[plainlen] = '\0';
printf("%s\n", ciphertext);
free(ciphertext);
// Silence warnings about const not being maintained in cast to void*
free((char*) plaintext);
return 0;
}
char *get_input(void) {
char *const restrict buf = malloc(BUFSIZE * sizeof (char));
if (buf == NULL) {
return NULL;
}
fgets(buf, BUFSIZE, stdin);
// Get rid of newline
size_t const len = strlen(buf);
if (buf[len - 1] == '\n') buf[len - 1] = '\0';
return buf;
}
测试
Plain text: alligator
bmmjhbups
但是,我认为您可能误解了密钥,如果我理解正确,密钥aaa
将保持纯文本不变,但密钥bbb
会将位置向下移一步字母表。观察角落情况,例如将Z向下移动或向上移动A.
答案 1 :(得分:0)
虽然我可能不应发布此内容(因为没有提供代码示例),但这里有一段代码可以满足您的需求。但是,有几个想法:
根据Vigenere wiki,每个字母都有一个与之关联的数字:
- a .. 0
- b .. 1
- ...
- z .. 25
当添加2个字母时,会添加其值,然后将% 26
(模数)应用于结果。例如。 &#39; 一&#39; +&#39; a &#39; =(0 + 0)%26 = 0这也是 a (与您期望的 b 不同),这就是我必须添加的原因CUSTOM_OFFSET
将表中的每个结果(前进)移动1。
密码可以使用大写或小写字母,也可以不使用(或任何其他字符)。可能会添加一些text
和key
验证例程。无论如何,在这种情况下,使用小写。
代码:
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#define BASE_CHR 'a' //Change it to 'A' if working with uppercases (can't have both)
#define ALPHABET_LEN ('z' - 'a' + 1)
#define CUSTOM_OFFSET 1 //According to specs should be 0, but it wouldn't match the current requirements
int main() {
char *text = "alligator", *key = "aaa", *new_text = NULL;
size_t text_len = strlen(text), key_len = strlen(key), i = 0;
if ((new_text = (char*)calloc(text_len + 1, sizeof(char))) == NULL) {
printf("Malloc error\n");
return 1;
}
for (i = 0; i < text_len; i++)
new_text[i] = ((text[i] - BASE_CHR + key[i % key_len] - BASE_CHR + CUSTOM_OFFSET) % ALPHABET_LEN) + BASE_CHR;
printf("Text: %s, Key: %s, Crypted: %s\n", text, key, new_text);
free(new_text);
new_text = NULL;
return 0;
}
输出:
Text:alligator,Key:aaa,Crypted:bmmjhbups