【问题标题】:C Loop through a small array and add to a large array [closed]C循环遍历一个小数组并添加到一个大数组[关闭]
【发布时间】:2016-06-13 12:06:59
【问题描述】:

我第一次来这里,我是一个非常新手的编程学生,我遇到了一个我找不到任何解决方案的问题。 我正在编写一个代码来做 vigenere cipher,但我遇到了问题:

首先:要输入key,假设key是; “啊”

第二种:要加密的文本,假设文本是:“alligator”

密码应该是:

鳄鱼

+

aaa|aaa|aaa(重新运行文本中每个额外字母的键 vs 键)

一个 + 一种 加密的第一个字母; b

所有文字:

bmmjhbups

我的问题是如何用较短的 abc 遍历鳄鱼?在我所有的尝试中,当循环传递它时 abc 变为零,而不是当文本的循环传递 abc 的长度时从头开始。 我也尝试过使用 strcpy 和 concatenate,以便 abc 在 alligator 处变为相同的 strlength,但由于字符串乞求中的奇怪符号,我在 strcpy 和 cat 方法中遇到了问题。 关于循环如何通过更大的循环工作,有没有简单的解决方案?

【问题讨论】:

  • 能否提供一些代码,以便我们更好地帮助您?
  • 只需使用明文模密钥长度的索引作为密钥的索引,例如cypher = plain[i] + key[i % keylength]

标签: c arrays string loops


【解决方案1】:

虽然我可能不应该发布这个(因为没有提供代码示例),但这里有一段代码可以满足您的需求。但是,有几个想法:

  • 根据Vigenere wiki,每个字母都有一个与之关联的数字:

    • 一个 .. 0
    • b .. 1
    • ...
    • z .. 25

    当添加 2 个字母时,它们的值会被添加,然后将 % 26(模数)应用于结果。例如。 'a' + 'a' = (0 + 0) % 26 = 0 这也是 a (不同于 b 你所期待的),这就是为什么我必须添加 CUSTOM_OFFSET 将表中的每个结果(向前)移动 1。

  • 密码可以使用大写或小写字母,不能同时使用两者(或任何其他字符)。可能会添加一些textkey 验证例程。无论如何,在这种情况下,使用小写。

代码:

#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;
}

输出:

文本:鳄鱼,密钥:aaa,加密:bmmjhbups

【讨论】:

  • 嗨,感谢您的时间和投入,非常感谢。关于a + a = a,您是正确的。我认为这里有一些很好的信息可供我用来解决我的问题。
【解决方案2】:

请看看这个程序。我认为它可以满足您的需求。

#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 向上移动。

【讨论】:

  • 嗨,感谢您的时间和投入。您对 aaa = 0 的键是正确的。
猜你喜欢
  • 2018-04-07
  • 2021-06-18
  • 2013-11-06
  • 2020-12-22
  • 2015-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-09
相关资源
最近更新 更多