繁体   English   中英

C中的Vigenere平方解密

[英]Vigenere Square Decryption in C

我正在尝试使用存储在数组中的密码短语和vigenere正方形来加密和解密消息。 我能够成功加密消息,但是以后无法解决如何解密的问题。 有任何想法吗?

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

void encrypt(char *text, char *pass, int n, int m, char *vs);
void decrypt(char *text, char *pass, int n, int m, char *vs);
void vigsq(char *vs);

main()
{
     char text[] = "HELLOWORLD";
     char pass[] = "MAGIC";
     int n, m;
     char vs[26*26];
     char *vsPointer, *textPointer, *passPointer;
     char command;
     char inputfile[10];
     char outputfile[10];
     //printf("Please enter e/d, pass phrase, input file, output file:");
     //scanf("%c, %s, %s, %s", &command, &pass, &inputfile, &outputfile);
     vsPointer = vs;
     textPointer = text;
     passPointer = pass;
     vigsq(vsPointer);
     //printf("%c, %s, %s, %s\n", command, pass, inputfile, outputfile);

    n = strlen(text);
    m = strlen(pass);
    //printf("%d, %d", n, m);
    encrypt(textPointer, passPointer, n, m, vsPointer);
    printf("%s\n", text);
    decrypt(textPointer, passPointer, n, m, vsPointer);
    printf("%s\n", text);   
}

void encrypt(char *text, char *pass, int n, int m, char *vs)
{
    int i;
    int ascii1;
    int ascii2;
    int passcount = 0;
    char encrypt;
    for (i = 0; i < n; i++)
    {
        ascii1 = (int)text[i];
        ascii2 = (int)pass[passcount];
        ascii1 = ascii1 - 64;
        ascii2 = ascii2 - 64;
        encrypt = vs[((ascii1 -1)*26) + (ascii2)];
        // printf("%d, %d, %c\n", ascii1, ascii2, encrypt);
        text[i] = encrypt;
        passcount++;
        if (passcount == m)
        {
            passcount = 0;
        }
    }   
}

void decrypt(char *text, char *pass, int n, int m, char *vs)
{
    int i;
    int ascii1;
    int ascii2;
    int passcount = 0;
    char decrypt;
    for (i = 0; i < n; i++)
    {
        ascii1 = (int)text[i];
        ascii2 = (int)pass[passcount];
        ascii1 = ascii1 - 64;
        ascii2 = ascii2 - 64;
        decrypt = vs[//Don't know what to put here];
        //printf("%d, %d, %c\n", ascii1, ascii2, decrypt);
        text[i] = decrypt;
        passcount++;
        if (passcount == m)
        {
            passcount = 0;
        }
    }       
}

void vigsq(char *vs)
{
    char alphabet[] = {'A','B','C','D','E','F','G','H','I','J','K',
        'L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};

    int a = 0, i, j, count = 0;
    for(i = 1; i <= 26*26; i++)
    {                           
        vs[i] = alphabet[a];
        a++;
        if (i % 26 == 0)
        {
            count++;
            a = count;
        }   
        if (a == 26)        
        {
            a = 0;
        }               
    }
}

(请忽略稍后将要实现的I / O内容。)感谢您的帮助:)

对字母进行编码时,可以在Vigenère表中的密码字母m[j]和明文字母p[i]的列中查找字母。 解码时,必须在密码字母的行中找到加密字母c[i]的列。 在代码中,加密是简单的表查找,但解密不是。

不过,您实际上不需要表。 您可以通过算法描述Vigenère密码。 密码实际上只是Ceasar密码-简单的字母移位&ndash,其中移位量由密码中的当前字母确定。 加密意味着向前移动,解密意味着向后移动:

c[i] = (p[i] + m[j]) % 26
p[i] = (c[i] - m[j]) & 26

在该公式中,字母由数字0(A)至25(Z)表示。 请记住,索引在C中从零开始。这也意味着您必须从字母中减去'A' (65),而不是64。

因为解密和加密是如此相似,所以您可以在一个带有操作模式标志的函数中实现它们:

enum {
    Encrypt, 
    Decrypt
};                    

void vigenere(char *text, const char *pass, int mode)
{
    int i;
    int passcount = 0;

    for (i = 0; text[i] != '\0'; i++)
    {
        int ascii1 = text[i] - 'A';
        int ascii2 = pass[passcount] - 'A';

        // Negate shift for decryption
        if (mode == Decrypt) ascii2 = -ascii2;

        text[i] = 'A' + (26 + ascii1 + ascii2) % 26;

        passcount++;
        if (pass[passcount] == '\0') passcount = 0;
    }
}

注意事项:

  • 公式中加26是为了防止取负数的余数,而余数将在C中产生负数。
  • 该代码仅在所有字符均为大写字母时才有效。
  • 显式的字符串长度已被省略; 您可以通过检查当前字符是否为终止null '\\0'来测试是否已到达C字符串的末尾。

像这样调用此代码:

int main()
{
    char text[] = "HELLOWORLD";
    const char *pass = "MAGIC";

    printf("plain %s\n", text);    

    vigenere(text, pass, Encrypt);
    printf("crypt %s\n", text);

    vigenere(text, pass, Decrypt);
    printf("decpt %s\n", text); 

    return 0;  
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM