싲더
시저 암호가 뚫는 법은 암호화된 문장에 1부터 25까지 key값에 대입하여 더 암호화를 진행하는 방법이다.
이것이 먹히는 이유는, 우리는 쉬프팅 연산이 알파벳 순서를 기반으로 한다는것을 알기 때문이다.
따라서 이것을 해커가 모르도록 해야한다.
그래서, 난 파일입출력을 생각하였다.
파일 입출력을 이용하여 영어 대문자, 소문자, 숫자, 특수문자 등등 txt 파일을 만들어서 연산 순서를 그 파일에 저장하는 것이다.
파일 관리는 사용자가 직접 그 파일을 열어서 할 수도 있지만, 프로그램 자체적으로 순서를 섞어버려도 된다.
난 이러한 방법을 이용하였다.
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <ctype.h>
#include <wincon.h>
#include <memory.h>
#include <stdbool.h> //Use the bool
#include <time.h>
#pragma warning(disable:4996)
#define _PROGRAM_ERROR_ printf("Program_Error !!\nDon't run this program\n\n");
int upper_num_list[26];
char upper_char_list[26];
int lower_num_list[26];
char lower_char_list[26];
int num_int_list[10];
char num_char_list[10]; //This is inteager
int Special_num_list[31];
char Special_char_list[31];
int Special_end;
char Original_String[1000];
char Encode_String[1000];
int key;
int Encrypt_upper(int x) {
for (int j = 0; upper_char_list[j] != NULL; j++) {
if (upper_char_list[j] == Original_String[x]) {
int flag_int = j;// on the j.
if (flag_int + key > 25) { // I know the number of upper case
int more = key - (25 - flag_int);
Encode_String[x] = upper_char_list[more - 1];
}
else {
Encode_String[x] = upper_char_list[flag_int + key];
}
}
}
}
int Encrypt_lower(int x) {
for (int j = 0; lower_char_list[j] != NULL; j++) {
if (lower_char_list[j] == Original_String[x]) {
int flag_int = j;// on the j.
if (flag_int + key > 25) { // I know the number of upper case
int more = key - (25 - flag_int);
Encode_String[x] = lower_char_list[more - 1];
}
else {
Encode_String[x] = lower_char_list[flag_int + key];
}
}
}
}
int Encrypt_num(int x){
for (int j = 0; num_char_list[j] != NULL; j++) {
if (num_char_list[j] == Original_String[x]) {
int flag_int = j;// on the j.
if (flag_int + key > 9) { // I know the number of upper case
int more = key - (9 - flag_int);
Encode_String[x] = num_char_list[more - 1];
}
else {
Encode_String[x] = num_char_list[flag_int + key];
}
}
}
}
int Encrypt_special(int x) {
for (int j = 0; Special_char_list[j] != NULL; j++) {
if (Special_char_list[j] == Original_String[x]) {
int flag_int = j;// on the j.
if (flag_int + key > Special_end-1) { // I know the number of upper case
int more = key - (Special_end -1- flag_int);
Encode_String[x] = Special_char_list[more - 1];
}
else {
Encode_String[x] = Special_char_list[flag_int + key];
}
}
}
}
int Decrypt_upper(int x) {
for (int j = 0; upper_char_list[j] != NULL; j++) {
if (upper_char_list[j] == Encode_String[x]) {
int flag_int = j;// on the j.
if (flag_int - key < 0) { // I know the number of upper case
int less = 25 - (key - flag_int) + 2;
Original_String[x] = upper_char_list[less - 1];
}
else {
Original_String[x] = upper_char_list[flag_int - key];
}
}
}
}int Decrypt_lower(int x) {
for (int j = 0; lower_char_list[j] != NULL; j++) {
if (lower_char_list[j] == Encode_String[x]) {
int flag_int = j;// on the j.
if (flag_int - key < 0) { // I know the number of upper case
int less = 25 - (key - flag_int) + 2;
Original_String[x] = lower_char_list[less - 1];
}
else {
Original_String[x] = lower_char_list[flag_int - key];
}
}
}
}
int Decrypt_num(int x) {
for (int j = 0; num_char_list[j] != NULL; j++) {
if (num_char_list[j] == Encode_String[x]) {
int flag_int = j;// on the j.
if (flag_int - key < 0) { // I know the number of upper case
int less = 9 - (key - flag_int) + 2;
Original_String[x] = num_char_list[less - 1];
}
else {
Original_String[x] = num_char_list[flag_int - key];
}
}
}
}
int Decrypt_special(int x) {
for (int j = 0; Special_char_list[j] != NULL; j++) {
if (Special_char_list[j] == Encode_String[x]) {
int flag_int = j;// on the j.
if (flag_int - key < 0) { // I know the number of upper case
int less = Special_end - (key - flag_int) + 1;
Original_String[x] = Special_char_list[less - 1];
}
else {
Original_String[x] = Special_char_list[flag_int - key];
}
}
}
}
int upper() {
int i=0;
FILE *fp = fopen("upper.txt", "r");
if (fp == NULL) {
printf("upper.txt file doesn't exist.\nFirst, make that file\n");
return 0;
}
else {
while (fscanf(fp, "%d\t%c", &upper_num_list[i], &upper_char_list[i]) != EOF) {
i = i + 1;
}
}
fclose(fp);
}
int lower() {
int i = 0;
FILE *fp = fopen("lower.txt", "r");
if (fp == NULL) {
printf("lower.txt file doesn't exist.\nFirst, make that file\n");
return 0;
}
else {
while (fscanf(fp, "%d\t%c", &lower_num_list[i], &lower_char_list[i]) != EOF) {
i = i + 1;
}
}
fclose(fp);
}
int int_num() {
int i = 0;
FILE *fp = fopen("int_num.txt", "r");
if (fp == NULL) {
printf("int_num.txt file doesn't exist.\nFirst, make that file\n");
return 0;
}
else {
while (fscanf(fp, "%d\t%c", &num_int_list[i], &num_char_list[i]) != EOF) {
i = i + 1;
}
}
fclose(fp);
}
int Special_char() {
int i = 0;
FILE *fp = fopen("Special_char.txt", "r");
if (fp == NULL) {
printf("int_num.txt file doesn't exist.\nFirst, make that file\n");
return 0;
}
while (fscanf(fp, "%d\t%c", &Special_num_list[i], &Special_char_list[i]) != EOF) {
i = i + 1;
}
Special_end = i;
fclose(fp);
}
int Make_upper() {
int want;
printf("Make : 0\nStop : 1\n");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 12);
printf("Warning : if upper.txt already exists, it will removed ==>");
scanf("%d", &want);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
if (want == 0) {
char Alphabet[26] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char Encrypt_Alphabet[26];
int flag[1000];
int v;
int j=0;
memset(flag, NULL, 4000);
memset(Encrypt_Alphabet, NULL, sizeof(char) * sizeof(Encrypt_Alphabet));
srand(time(NULL));
for (int i = 0; i <= 4000; i++) {
v = rand() % 26;
if (Alphabet[v] == NULL) {
flag[v] = 1;
}
if (flag[v]==1) {
continue;
}
else {
if (j + 1 == 27) {
break;
}
Encrypt_Alphabet[j] = Alphabet[v];
flag[v] = 1;
j = j + 1;
}
}
FILE *fp = fopen("upper.txt", "w");
for (int i = 0; i <= 25; i++) {
if (i == 25) {
fprintf(fp, "%d\t%c", i, Encrypt_Alphabet[i]);
break;
}
fprintf(fp, "%d\t%c\n", i, Encrypt_Alphabet[i]);
}
fclose(fp);
}
else if(want==1){
printf("Stop!!\n");
return 1;
}
else {
printf("Only 0 or 1\n\n");
}
}
int Make_lower() {
int want;
printf("Make : 0\nStop : 1\n");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 12);
printf("Warning : if lower.txt already exists, it will removed ==>");
scanf("%d", &want);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
if (want == 0) {
char Alphabet[26] = "abcdefghijklmnopqrstuvwxyz";
char Encrypt_Alphabet[26];
int flag[1000];
int v;
int j = 0;
memset(flag, NULL, 4000);
memset(Encrypt_Alphabet, NULL, sizeof(char) * sizeof(Encrypt_Alphabet));
srand(time(NULL));
for (int i = 0; i <= 4000; i++) {
v = rand() % 26;
if (Alphabet[v] == NULL) {
flag[v] = 1;
}
if (flag[v] == 1) {
continue;
}
else {
if (j + 1 == 27) {
break;
}
Encrypt_Alphabet[j] = Alphabet[v];
flag[v] = 1;
j = j + 1;
}
}
FILE *fp = fopen("lower.txt", "w");
for (int i = 0; i <= 25; i++) {
if (i == 25) {
fprintf(fp, "%d\t%c", i, Encrypt_Alphabet[i]);
break;
}
fprintf(fp, "%d\t%c\n", i, Encrypt_Alphabet[i]);
}
fclose(fp);
}
else if (want == 1) {
printf("Stop!!\n");
return 1;
}
else {
printf("Only 0 or 1\n\n");
}
}
int Make_int_num() {
int want;
printf("Make : 0\nStop : 1\n");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 12);
printf("Warning : if int_num.txt already exists, it will removed ==>");
scanf("%d", &want);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
if (want == 0) {
char num[10] = "0123456789";
char Encrypt_num[10];
int flag[1000];
int v;
int j = 0;
memset(flag, NULL, 4000);
memset(Encrypt_num, NULL, sizeof(char) * sizeof(Encrypt_num));
srand(time(NULL));
for (int i = 0; i <= 4000; i++) {
v = rand() % 10;
if (num[v] == NULL) {
flag[v] = 1;
}
if (flag[v] == 1) {
continue;
}
else {
if (j + 1 == 11) {
break;
}
Encrypt_num[j] = num[v];
flag[v] = 1;
j = j + 1;
}
}
FILE *fp = fopen("int_num.txt", "w");
for (int i = 0; i <= 9; i++) {
if (i == 9) {
fprintf(fp, "%d\t%c", i, Encrypt_num[i]);
break;
}
fprintf(fp, "%d\t%c\n", i, Encrypt_num[i]);
}
fclose(fp);
}
else if (want == 1) {
printf("Stop!!\n");
return 1;
}
else {
printf("Only 0 or 1\n\n");
}
}
int Make_Special_char() {
int want;
printf("Make : 0\nStop : 1\n");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 12);
printf("Warning : if Special_char.txt already exists, it will removed ==>");
scanf("%d", &want);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
if (want == 0) {
int shake;
char Specials[1000];
int check=0;
while (1) {
rewind(stdin);
memset(Specials, NULL, sizeof(char) * sizeof(Specials));
printf("Input (max : 1000) => ");
gets_s(Specials, sizeof(Specials));
int Len = strlen(Specials);
char k[1000];
memset(k, NULL, sizeof(char) * sizeof(k));
int a[1000];
memset(a, NULL, sizeof(a));
for (int i = 0; Specials[i] != NULL; i++) {
k[i] = Specials[i];
}
for (int i = 0; k[i] != NULL; i++) {
for (int j = 0; Specials[j] != NULL; j++) {
if (k[i] == Specials[j]) {
a[i] += 1;
if (a[i] >= 2) {
check = 1;
printf("Error!\n");
continue;
}
}
}
}
if (check == 0) {
break;
}
}
rewind(stdin);
int Len = strlen(Specials);
printf("Do you want to shake?\nDon't shake : 0\nshake : 1\n=> ");
scanf("%d", &shake);
if (shake == 0) {
FILE *fp = fopen("Special_char.txt", "w");
for (int i = 0; i <= Len - 1; i++) {
if (i == Len - 1) {
fprintf(fp, "%d\t%c", i, Specials[i]);
break;
}
fprintf(fp, "%d\t%c\n", i, Specials[i]);
}
fclose(fp);
}
else if (shake == 1) {
char Encrypt_Specials[1000];
int flag[1000];
int v;
int j = 0;
memset(flag, NULL, 4000);
memset(Encrypt_Specials, NULL, sizeof(char) * sizeof(Encrypt_Specials));
srand(time(NULL));
for (int i = 0; i <= 10000; i++) {
v = rand() % Len;
if (Specials[v] == NULL) {
flag[v] = 1;
}
if (flag[v] == 1) {
continue;
}
else {
if (j + 1 == Len+1) {
break;
}
Encrypt_Specials[j] = Specials[v];
flag[v] = 1;
j = j + 1;
}
}
FILE *fp = fopen("Special_char.txt", "w");
for (int i = 0; i <= Len - 1; i++) {
if (i == Len - 1) {
fprintf(fp, "%d\t%c", i, Encrypt_Specials[i]);
break;
}
fprintf(fp, "%d\t%c\n", i, Encrypt_Specials[i]);
}
fclose(fp);
}
else {
printf("Only 0 or 1\n");
}
}
else if (want == 1) {
printf("Stop!!\n");
return 1;
}
else {
printf("Only 0 or 1\n\n");
}
}
int main(void) {
int Len = NULL;
int choice=NULL;
key = NULL;
int make = NULL;
memset(Original_String, NULL, sizeof(char) * sizeof(Original_String));
memset(Encode_String, NULL, sizeof(char) * sizeof(Encode_String));
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 10);
printf("===========================================================\n");
printf("Made by L0RQ2 - Cipher Encoder/Decoder - Upgrade\n");
printf("l0rq2.tistory.com\n");
printf("MMHS 10703 LORQ2\n");
printf("===========================================================\n");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
printf("En/Decode : 0 \nMake Agreement : 1 \n==>");
scanf("%d", &make);
rewind(stdin);
if (make == 0) {
upper();
lower();
int_num();
Special_char();
/*
printf("\n\n");
for (int i = 0; Special_num_list[i] != NULL; i++) {
printf("%d %c\n", Special_num_list[i], Special_char_list[i]);
}
*/
printf("Encode : 0\nDecode : 1\n==>");
scanf("%d", &choice);
rewind(stdin);
if (choice == 0) {
int i, flag_int;
char flag_char;
printf("Original_String To Encode => ");
gets_s(Original_String, 100); //Get Oiriginal_String
printf("Key => ");
scanf("%d", &key); //GetKey 0+앤터
Len = strlen(Original_String); //Get strlen of Original_String
for (i = 0; i < Len; i++) { //Orginal_string[i]!=NULL ++i i++
if (isalpha(Original_String[i])) { // Is it Alpha?
if (isupper(Original_String[i])) {
Encrypt_upper(i);
}
else if (islower(Original_String[i])) {
Encrypt_lower(i);
}
else {
_PROGRAM_ERROR_
break;
}
}
else if (isdigit(Original_String[i])) {
Encrypt_num(i);
}
else {
char *is = strchr(Special_char_list, Original_String[i]);
if (is == NULL) {
Encode_String[i] = Original_String[i];
}
else if (is != NULL) {
Encrypt_special(i);
}
else {
_PROGRAM_ERROR_
break;
}
}
}
printf("\n\nEncode_String : ");
puts(Encode_String);
}
else if (choice == 1) { //Decode
printf("Encode_Stirng to Decode => ");
gets_s(Encode_String, sizeof(char) * sizeof(Encode_String));
printf("Key => ");
scanf("%d", &key);
Len = strlen(Encode_String);
int i;
for (i = 0; i < Len; i++) { //Orginal_string[i]!=NULL ++i i++
if (isalpha(Encode_String[i])) { // Is it Alpha?
if (isupper(Encode_String[i])) {
Decrypt_upper(i);
}
else if (islower(Encode_String[i])) {
Decrypt_lower(i);
}
else {
_PROGRAM_ERROR_
break;
}
}
else if (isdigit(Encode_String[i])) {
Decrypt_num(i);
}
else {
char *is = strchr(Special_char_list, Encode_String[i]);
if (is == NULL) {
Original_String[i] = Encode_String[i];
}
else if (is != NULL) {
Decrypt_special(i);
}
else {
_PROGRAM_ERROR_
break;
}
}
}
printf("\n\nOriginal(Decrypt)_String : ");
puts(Original_String);
}
else {
printf("Just 0 Or 1\n");
}
system("pause");
return 0;
}
else if (make == 1) {
while (1) {
int which;
printf("\nIf you want to stop : 9\nmake upper.txt : 1 \nmake lower.txt : 2\nmake int_num.txt : 3\nmake Special_char.txt : 4\n ==>");
scanf("%d", &which);
if (which == 9) {
break;
}
else if (which == 1) {
Make_upper();
}
else if (which == 2) {
Make_lower();
}
else if (which == 3) {
Make_int_num();
}
else if (which == 4) {
Make_Special_char();
}
}
}
else {
printf("Just 0 Or 1\n");
}
return 0;
}
하지만, 이렇게 한다면 빈도수 공격에 의하여 뚫릴 수 있다.
이제, 빈도수 공격을 막을 방법을 생각해보자.!!!
'프로그래밍 > C언어' 카테고리의 다른 글
시저암호 프로그래밍 수정 (1) | 2018.01.23 |
---|---|
시저암호란? - 시저암호 프로그래밍 (0) | 2017.10.09 |