#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void Decryption(char *P, char *Temp, char * Key, int Count);
void Encryption(char *P, char *Temp, char * key, int Count);
void Change_key(char * p);
void Vig_Cipher(); // 비제네르 암호 표 출력.
int main()
{
int select, count;
printf("=====================Vigenere Cipher ==========================\\n");
Vig_Cipher();
printf("===============================================================\\n");
while (1)
{
char * p = (char *)malloc(sizeof(char)* 20);
char * key = (char *)malloc(sizeof(char)* 20);
printf("========== Enter Plain Text or Cryptogram : ");
scanf("%s", p);
printf("========== Enter Key Value : ");
scanf("%s", key);
Change_key(key); // key값이 대문자일 경우, 소문자로 변환시켜준다...
count = strlen(p); // 평문 or 암호문의 문자길이 입력 (문자길이 만큼 동적메모리 할당하기 위해서)
char *Tmp = (char *)malloc(sizeof(char)* (count + 1)); // count+1 하는이유는 문자열 출력 할 때 NULL바이트까지 넣기위해서..
Tmp[count] = \'\\0\'; // 임시저장할 문자에 NULL바이트 삽입
printf("========== Enter Encryption[1] Decryption[2] End[3] : \\b");
scanf("%d", &select);
if (select == 1)
Encryption(p, Tmp, key, count);
else if (select == 2)
Decryption(p, Tmp, key, count);
else if (select == 3)
break;
else
{
printf("\\n Error!!\\n");
exit(-1);
}
free(p);
free(Tmp);
free(key);
}
return 0;
}
void Decryption(char * P, char * Temp, char * Key, int Count)
{
int i, j = 0;
int key_len = strlen(Key); // key값의 문자열 길이
printf("\\n=== Decryption ===\\n");
for (i = 0; i < Count; i++)
{
if (P[i] >= 65 && P[i] <= 90)
{
Temp[i] = 90 - (90 - P[i] + (Key[j++] - 97)) % 26;
printf("%c -> %c\\n", P[i], Temp[i]);
}
else if (P[i] >= 97 && P[i] <= 122)
{
Temp[i] = 122 - (122 - P[i] + (Key[j++] - 97)) % 26;
printf("%c -> %c\\n", P[i], Temp[i]);
}
else
{
printf("Decryption Error!!\\n");
exit(-1);
}
if (j == key_len)
j = 0;
}
printf("<< Cryptogram : %s >>\\n", P);
printf("<< Plain Text : %s >>\\n\\n", Temp);
}
void Encryption(char * P, char *Temp, char * Key, int Count)
{
int j = 0;
int key_len = strlen(Key); // key값의 문자열 길이
printf("\\n=== Encryption ===\\n");
int i; // 반복문, 문자갯수count변수 선언
for (i = 0; i < Count; i++)
{
if (P[i] >= 65 && P[i] <= 90)
{// 평문이 값이 대문자일경우!
Temp[i] = (P[i] + (Key[j++]-97) - 65) % 26 + 65; // 암호화 공식 알파벳 갯수 26 ...
printf("%c -> %c\\n", P[i], Temp[i]);
}
else if (P[i] >= 97 && P[i] <= 122) //평문값이 소문자일 경우!
{
Temp[i] = (P[i] + (Key[j++]-97) - 97) % 26 + 97;
printf("%c -> %c\\n", P[i], Temp[i]);
}
else
{
printf("Plain Text Error!\\n");
exit(-1);
}
if (j == key_len)
j = 0;
}
printf("<< Plain Text : %s >>\\n", P);
printf("<< Cryptogram : %s >>\\n\\n", Temp);
}
void Change_key(char * p) // 키값이 대문자인경우 -> 소문자로 바꿔줌
{
int i;
int count = strlen(p); // count =>7 이묜 0~ 6
for (i = 0; i < count; i++)
{
if (p[i] >= 65 && p[i] <= 90) // 키값이 소문자일때,
p[i] = p[i] - 65 + 97;
else if (!(p[i] >= 97 && p[i] <= 122)) // 키값이 대문자일때,
{
printf("키값 오류!!!\\n");
exit(-1);
}
}
}
void Vig_Cipher(){
int i, j;
printf(" ");
for (i = 0; i < 26; i++)
{
printf("%2c", 65 + i);
}
printf("\\n ____________________________________________________\\n");
for (i = 0; i < 26; i++)
{
printf("%c | ", 65 + i);
for (j = 0; j < 26; j++)
{
printf("%2c", (i + j) % 26 + 65); // 비제네르 암호 표 소문자로 표시
}
printf("\\n");
}
}