728x90
import random as r #key를 만들기 위한 랜덤 모듈
import copy as c #LFSR함수에서 key데이터를 복사하기 위한 모듈
def capital(alpha): #대문자 검사를 위한 함수
if alpha >= ord('A') and alpha <= ord('Z'): #대문자라면
return 1 #1반환
else: #대문자가 아니라라면
return 0 #0반환
def shift_encrypt(key, msg): #쉬프트 암호화 함수
length = len(msg) #평문의 길이
ctx = '' #암호문
for i in range(0, length): #평문의 문자 개수만큼 반복
if capital(ord(msg[i])) == 1: #대문자라면
ctx += chr(ord('A') + ((ord(msg[i]) - ord('A')) + key) % 26) #대문자 기준 key만큼 문자를 shift
else: #소문자라면
ctx += chr(ord('a') + ((ord(msg[i]) - ord('a')) + key) % 26) #소문자 기준 key만큼 문자를 shift
return ctx #암호문 반환
def shift_decrypt(key, ctx): #쉬프트 복호화 함수
length = len(ctx) #암호문의 길이
msg = '' #평문
for i in range(0, length): #암호문의 문자 개수만큼 반복
if capital(ord(ctx[i])) == 1: #대문자라면
msg += chr(ord('A') + ((ord(ctx[i]) - ord('A')) - key) % 26) #대문자 기준 -key만큼 문자를 shift
else: #소문자라면
msg += chr(ord('a') + ((ord(ctx[i]) - ord('a')) - key) % 26) #소문자 기준 -key만큼 문자를 shift
return msg #평문 반환
def vigenere_genkey(n): #vigenere 암호의 키 생성 함수
key = [] #키
for i in range(0, n): #n개의 키를 생성
newkey = r.randint(0, 10000) #키를 랜덤으로 생성
while newkey in key: #혹시라도 키가 겹칠 가능성을 고려하여 동일한 키가 이미 존재할 경우
newkey = r.randint(0, 10000) #다른 키 값을 생성
key.append(newkey) #키 등록
return key #키 반환
def vigenere_encrypt(key, msg): #vigenere 암호화 함수
length = len(msg) #평문의 길이
keylen = len(key) #키 길이
key_index = 0 #키의 인덱스 정보
ctx = '' #암호문
for i in range(0, length): #평문의 문자 개수만큼 반복
if key_index == keylen: #만약 키를 모두 사용했다면
key_index = 0 #다시 처음부터 사용
if capital(ord(msg[i])) == 1: #대문자라면
ctx += chr(ord('A') + ((ord(msg[i]) - ord('A')) + key[key_index]) % 26) #대문자 기준, 블럭안의 문자와 대응하는 key만큼 shift
key_index += 1 #다음 키 사용
else: #소문자라면
ctx += chr(ord('a') + ((ord(msg[i]) - ord('a')) + key[key_index]) % 26) #소문자 기준, 블럭안의 문자와 대응하는 key만큼 shift
key_index += 1 #다음 키 사용
return ctx #암호문 반환
def vigenere_decrypt(key, ctx): #vigenere 복호화 함수
length = len(ctx) #암호문의 길이
keylen = len(key) #키 길이
key_index = 0 #키의 인덱스 정보
msg = '' #평문
for i in range(0, length): #평문의 문자 개수만큼 반복
if key_index == keylen: #만약 키를 모두 사용했다면
key_index = 0 #다시 처음부터 사용
if capital(ord(ctx[i])) == 1: #대문자라면
msg += chr(ord('A') + ((ord(ctx[i]) - ord('A')) - key[key_index]) % 26) #대문자 기준, 블럭안의 문자와 대응하는 -key만큼 shift
key_index += 1 #다음 키 사용
else: #소문자라면
msg += chr(ord('a') + ((ord(ctx[i]) - ord('a')) - key[key_index]) % 26) #소문자 기준, 블럭안의 문자와 대응하는 -key만큼 shift
key_index += 1 #다음 키 사용
return msg #평문 반환
def lfsr_genkey(n): #lfsr 암호 키 생성 함수
cdata = [] #정수
xdata = [] #초기값
key = [] #c_i와 x_i가 들어갈 키
for i in range(0, n): #n만큼 반복
#c값과 x값을 받음
newcdata = r.randint(0, 25)
newxdata = r.randint(0, 25)
#받은 c값과 x값이 c_i와 x_i과 같은 확률을 감안, 동일한 값이 이미 등록되어 있을 경우 값을 다시 받음
while newcdata in cdata:
newcdata = r.randint(0, 25)
cdata.append(newcdata)
while newxdata in xdata:
newxdata = r.randint(0, 25)
xdata.append(newxdata)
key.append(cdata) #c등록
key.append(xdata) #x등록
return key #키 반환
def lfsr_encrypt(real_key, msg): #lfsr 암호화 함수
key = c.deepcopy(real_key) #키는 사용자끼리 공유하므로 이번 실습에선 깊은 복사를 통해 사용
length = len(msg) #평문의 길이
keylen = len(key[1]) #x_i의 길이
clen = len(key[0]) #c_i의 길이
c_index = 0 #c의 인덱스
newx = 0 #암호화에 사용되기 위해 만들어진 x값
ctx = '' #암호문
for i in range(0, length): #평문의 길이만큼 반복
keylen = len(key[1]) #x(key)의 길이를 다시 저장
for j in range(0, keylen): #x(key)의 길이만큼 반복
if c_index == clen: #만약 c값을 모두 이용했다면
c_index = 0 #처음부터 다시 사용
newx += key[0][c_index] * key[1][j] #암호화에 사용되기 위해 제작된 x값
c_index += 1 #다음 c값 사용
newx = newx % 26 #x값을 mod 26연산으로 다음 x값 계산을 준비
key[1].append(newx) #x값 등록
if capital(ord(msg[i])) == 1: #대문자라면
ctx += chr(ord('A') + ((ord(msg[i]) - ord('A')) + newx) % 26) #x를 더한 후 mod연산
else: #소문자라면
ctx += chr(ord('a') + ((ord(msg[i]) - ord('a')) + newx) % 26) #x를 더한 후 mod연산
return ctx #암호문 반환
def lfsr_decrypt(real_key, ctx): #lfsr 복호화 함수
key = c.deepcopy(real_key) #키는 사용자끼리 공유하므로 이번 실습에선 깊은 복사를 통해 사용
length = len(ctx) #암호문의 길이
keylen = len(key[1]) #x_i의 길이
clen = len(key[0]) #c_i의 길이
c_index = 0 #c의 인덱스
newx = 0 #복호화에 사용되기 위해 만들어진 x값
msg = '' #평문
for i in range(0, length): #암호문의 길이만큼 반복
keylen = len(key[1]) #x(key)의 길이를 다시 저장
for j in range(0, keylen): #x(key)의 길이만큼 반복
if c_index == clen: #만약 c값을 모두 이용했다면
c_index = 0 #c처음부터 다시 사용
newx += key[0][c_index] * key[1][j] #복호화에 사용되기 위해 제작된 x값
c_index += 1 #다음 c값 사용
newx = newx % 26 #x값을 mod 26연산으로 다음 x값 계산을 준비
key[1].append(newx) #x값 등록
if capital(ord(ctx[i])) == 1: #대문자라면
msg += chr(ord('A') + ((ord(ctx[i]) - ord('A')) - newx) % 26) #-x를 더한 후 mod연산
else: #소문자라
msg += chr(ord('a') + ((ord(ctx[i]) - ord('a')) - newx) % 26) #-x를 더한 후 mod연산
return msg #평문 반환
728x90
'Sejong University > Symmetric-key cryptography' 카테고리의 다른 글
CBC mode (0) | 2022.04.23 |
---|---|
Simple DES (0) | 2022.04.23 |
Histogram for Character Frequency (0) | 2022.04.23 |
댓글