[英]Vigenere Square Decryption in C
I'm trying to encrypt and decrypt a message using a passphrase and a vigenere square stored in an array. 我正在尝试使用存储在数组中的密码短语和vigenere正方形来加密和解密消息。 I am able to encrypt the message successfully however I can't work out how to decrypt it again afterwards.
我能够成功加密消息,但是以后无法解决如何解密的问题。 Any ideas?
有任何想法吗?
#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;
}
}
}
(Please ignore the I/O stuff I'll be implementing that later.) Thanks for the help :) (请忽略稍后将要实现的I / O内容。)感谢您的帮助:)
When you encode a letter, you look up letter at the the row of the password letter m[j]
and the columns of the plaintext letter p[i]
in the Vigenère table. 对字母进行编码时,可以在Vigenère表中的密码字母
m[j]
和明文字母p[i]
的列中查找字母。 When you decode, you must find the column where encrypted letter c[i]
is in the row of the password letter. 解码时,必须在密码字母的行中找到加密字母
c[i]
的列。 In code, encrypting is a simple table lookup, but decrypting is not. 在代码中,加密是简单的表查找,但解密不是。
You don't really need the table, though. 不过,您实际上不需要表。 You can describe the Vigenère cipher algorithmically.
您可以通过算法描述Vigenère密码。 The cipher really is just a Ceasar cipher – a simple letter shift &ndash, where the shift amount is determined by the current letter in the password.
密码实际上只是Ceasar密码-简单的字母移位&ndash,其中移位量由密码中的当前字母确定。 Encrypting means shifting forwards, decrypting means shifting backwards:
加密意味着向前移动,解密意味着向后移动:
c[i] = (p[i] + m[j]) % 26
p[i] = (c[i] - m[j]) & 26
In this formula, the letters are represented by the numbers 0 (A) to 25 (Z). 在该公式中,字母由数字0(A)至25(Z)表示。 Remember that indices start at zero in C. That also means that you have to subtract
'A'
(65) from your letters, not 64. 请记住,索引在C中从零开始。这也意味着您必须从字母中减去
'A'
(65),而不是64。
Because decryption and encryption are so similar, you can implement them in a single function with a flag for the mode of operation: 因为解密和加密是如此相似,所以您可以在一个带有操作模式标志的函数中实现它们:
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;
}
}
Things to note: 注意事项:
'\\0'
. '\\0'
来测试是否已到达C字符串的末尾。 Call this code like so: 像这样调用此代码:
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.