Vigenere在C中的密码

时间:2015-09-05 19:37:54

标签: c encryption vigenere

我在C中编写了一个程序,它使用纯文本和密码,并使用vigenere的密码生成密文。虽然代码在大多数情况下产生了正确的输出,但我找到了一个产生意外输出的例子,我自己找不到问题。输出如下:

alex@alex-laptop:~/Desktop/programming/C/current/vigenere$ ./vigenere lemon attackatdawn
LXF OPV EFR NHR [0002]

最后的那个框没有显示它应该出现,它表示当bash尝试显示ascii字符2时,但复制和粘贴不能正确显示它。这是来自维基百科的密码的示例文本,它是我发现的唯一一个破坏我的程序的文本(我不知道原因是什么,所以我无法复制它)但我确信还有更多的字符串这将产生类似的结果。我怀疑我做了一些产生未定义行为的东西,但我不确定。我在这做错了什么? 我的代码:

// vigenere.c - Takes a plaintext and a cipher key from argv[1] and argv[2] and produces the cipher text according to Vigenere's cipher

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

void string_clean(char *source) //Courtesy (mostly) of user 'Aaron' of StackOverflow
{
    char *i = source;
    char *j = source;

    while(*j != 0) {
        *i = *j++;
        if( *i != ' ' && (isupper(*i) || islower(*i)) )
            i++;
    }

    *i = 0;
}

char *vigenere_enc(char plain[], char cipher[])
{
    char *cipher_text;

    string_clean(plain);
    string_clean(cipher);

    int plain_len = strlen(plain);
    int cipher_len = strlen(cipher);

    if( !(cipher_text = calloc(plain_len, sizeof(char))) )
        return 0;

    for(int i = 0; i < cipher_len; i++) {
        if(isupper(cipher[i]))
            cipher[i] -= 'A';
        else if(islower(cipher[i]))
            cipher[i] -= 'a';
    }

    int j = 0;

    for(int i = 0; i < plain_len; i++, j++) {
        if(j == cipher_len)
            j = 0;

        if(isupper(plain[i]))
            plain[i] -= 'A';
        else if(islower(plain[i]))
            plain[i] -= 'a';

        cipher_text[i] = ((plain[i] + cipher[j]) % 26) + 'A';
    }
    return cipher_text;
}

int main(int argc, char *argv[])
{
    if(argc != 3)
        return 1;
    char *cipher = vigenere_enc(argv[2], argv[1]);

    for(int i = 0; i < strlen(cipher); i++) {
        if(i % 3 == 0 && i != 0)
            putchar(' ');
        putchar(cipher[i]);
    }

    putchar('\n');

    return 0;
}

非常感谢所有和任何帮助/建议!

1 个答案:

答案 0 :(得分:3)

您需要NUL-terminate输出字符串。 :-(这也意味着您拨打calloc(您真的应该只使用malloc)应该指定plain_len + 1,而不只是plain_len