본문 바로가기
C/암호학

Vigenere Cipher[C]

by 덤더리덤떰 2023. 9. 1.

1. Vigenere Cipher(비제네르 암호)

: 다중 대치 암호의 대표적인 암호

 

1-1. 단일문자대치암호 vs 다중대치암호

  • 단일문자대치암호(ex. 카이사르암호) : 하나의 평문 문자 -> 동일한 하나의 암호 문자
  • 다중대치암호(ex. 비제네르암호) : 하나의 평문 문자 -> 여러 개의 암호 문자

 

1-2. 다중대치암호 방식

 

: 대치표를 2회 이상 적용 

: 대치 표 개수가 d라면 주기 d를 갖는다 

=> d=8, 비밀키 수열= "security"

: 평문을 길이 8씩 분할하여 비밀키의 문자와 mod26 연산을 통해 암호문을 생성 

 

1-2-1. 비밀키의 차이

  • 카이사르 암호 : key = 1(숫자)  -> abcd의 암호화 결과 : bcde
  • 비제네르 암호 : key = ab(문자열) -> abcd의 암호화 결과 : acce

비제네르 암호의 키수열은 소문자 'a'(0) ~ 'z'(25)로만 구성이 가능하다 

ex) 평문의 문자 : t(19) -> 키 : s(18) => (19+18) % mod 26 = l(11)

 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

#define STRING_SIZE 50

void Encrypt(char* string, char* key, int klen) {
	for (int i = 0; i <= strlen(string); i++) {
		int j = i % klen; //happy인 경우에 5번째 요소일 경우에 key는 0번째 요소여야함
		if (string[i] >= 'a' && string[i] <= 'z') {
			string[i] -= 'a';
			key[j] -= 'a';
			if (string[i] + key[j] < 0) {
				string[i] += 26;
			}
			string[i] += key[j];
			string[i] %= 26;
			string[i] += 'a';
			key[j] += 'a';
		}
		else if (string[i] >= 'A' && string[i] <= 'Z') {
			string[i] -= 'A';
			key[j] -= 'a';
			if (string[i] + key[j] < 0) {
				string[i] += 26;
			}
			string[i] += key[j];
			string[i] %= 26;
			string[i] += 'A';
			key[j] += 'A';
		}
	}
}

void Decrypt(char* string, char* key, int klen) {
	for (int i = 0; i <= strlen(string); i++) {
		int j = i % klen; //happy인 경우에 5번째 요소일 경우에 key는 0번째 요소여야함
		if (string[i] >= 'a' && string[i] <= 'z') {
			string[i] -= 'a';
			key[j] -= 'a';
			if (string[i] - key[j] < 0) {
				string[i] += 26;
			}
			string[i] -= key[j];
			string[i] %= 26;
			string[i] += 'a';
			key[j] += 'a';
		}
		else if (string[i] >= 'A' && string[i] <= 'Z') {
			string[i] -= 'A';
			key[j] -= 'a';
			if (string[i] - key[j] < 0) {
				string[i] += 26;
			}
			string[i] -= key[j];
			string[i] %= 26;
			string[i] += 'A';
			key[j] += 'A';
		}
	}
}

int main() {
	char string[STRING_SIZE];
	int choice;
	char key[STRING_SIZE];
	printf("암호문 또는 평문을 입력:");
	fgets(string, sizeof(string), stdin);
	printf("암호화는 1번, 복호화는 2번 선택: ");
	scanf("%d", &choice);
	printf("키 값 입력(소문자만) :");
	scanf("%s", key);
	int klen = strlen(key);
	//key: happy인 경우 klen=5

	if (choice == 1) {
		//암호화
		printf("암호화된 결과 출력: ");
		Encrypt(string, key, klen);
		puts(string, stdout);
	}
	else if (choice == 2) {
		//복호화
		Decrypt(string, key, klen);
		printf("복호화된 결과 출력: ");
		puts(string, stdout);
	}




	getchar();
	return 0;
}

thiscryptosystemisnotsecure

llkmtzrnlsusjbxkawpikaxamvg

'C > 암호학' 카테고리의 다른 글

Transposition Cipher[C]  (0) 2023.09.04
Caesar Cipher[C]  (0) 2023.09.01
EED(Extend Euclid Algorithm)[c]  (0) 2023.09.01