정보/python

ASCII코드를 이용해 python으로 쉬운 암호 만들어보기

FeatherCoder 2024. 5. 26. 12:51

 파이썬에서 tkinter 모듈을 이용해서 암호화 복호화 프로그램을 만들어보았다. 그러려면 tkinter 창의 간단한 디자인과 암호화 복호화 방법을 정해야한다.

디자인

 먼저 디자인은 크게 중요하지 않으므로 간단하게 하였다. 암호화 시킬 텍스트를 집어넣는 엔트리와 암호화된 결과를 보여줄 엔트리, 또 암호화 시킬 버튼이 필요하고, 복호화도 마찬가지로 복호화 시킬 암호를 넣는 엔트리와 복호화된 결과를 보여주는 엔트리, 또 복호화 버튼이 필요하다. 추가적으로 무슨 엔트리인지를 보여주는 텍스트와 모든 내용을 지우는 지우기 버튼도 추가하였다.

코드

from tkinter import *
win = Tk()

win.title('Encryption & Decryption')
win.geometry('400x400')

entry1 = Entry()
entry2 = Entry()
btn1 = Button(text='암호화',command=encrypt)
text1 = Text()
btn2 = Button(text='복호화',command=decrypt)
text2 = Text()
lb1 = Label(text='*암호화할 문자 입력*',fg='red')
lb2 = Label(text='*암호화 결과*',fg='red')
lb3 = Label(text='*복호화할 문자 입력*',fg='red')
lb4 = Label(text='*복호화 결과*',fg='red')
clear_button = Button(text='지우기',command=clear)

entry1.place(x=150,y=10)
entry2.place(x=150,y=230)
btn1.place(x=150,y=30)
text1.place(x=150,y=100,width=200,height=50)
lb1.place(x=10,y=10)
lb2.place(x=40,y=100)
lb3.place(x=10,y=230)
lb4.place(x=40,y=320)

btn2.place(x=150,y=250)
text2.place(x=150,y=320,width=200,height=50)
clear_button.place(x=340,y=10)

win.mainloop()

실행화면

tkinter 창

 

암호화 복호화 방법

 

 암호화와 복호화는 ASCII 코드를 사용해 문자를 숫자로 변환한 뒤 이 숫자를 인수분해 하여 그 소인수들을 이용하였다. 암호화는 소인수들에 64를 더한 후 ASCII 코드를 사용해 숫자를 문자로 변화시켰다. 각 단어의 마디를 표시하기 위해서 단어 사이 사이에 F를 넣어주었다. 복호화는 F라는 문자를 기준으로 문자들을 다시 숫자로 바꾸어주고 64를 뺀 뒤 원래대로 곱해주어 원래 문자로 바꾸어주었다. 소인수분해 알고리즘은 루트n까지 소인수를 확인하는 것으로 하였다. 시간복잡도는 O(루트n)이다.

 

소인수 분해

def factorize(n):
    factors = []
    k = 2
    while n % k == 0:
        factors.append(k)
        n //= k
    k = 3
    while k * k <= n:
        while n % k == 0:
            factors.append(k)
            n //= k
        k += 2
    if n > 2:
        factors.append(n)

    return factors

 

암호화

def encrypt():
    a = entry1.get()
    b = ""

    def factorize(n):
        factors = []
        k = 2
        while n % k == 0:
            factors.append(k)
            n //= k
        k = 3
        while k * k <= n:
            while n % k == 0:
                factors.append(k)
                n //= k
            k += 2
        if n > 2:
            factors.append(n)
            
        return factors
        
    for i in range(0,len(a)):
        c=ord(a[i])
        factor = factorize(c)
        for j in range(0,len(factor)):
            b = b + chr(factor[j]+64)
        if i !=len(a)-1:
            b = b + 'F'
    
    text1.delete(0.0,END)
    text1.insert(END,b)

복호화

def decrypt():
    a = str(entry2.get())
    b = ''
    list = a.split('F')
    for i in range(0,len(list)):
        p = 1
        s = str(list[i])
        for j in range(0,len(s)):
            p *= int(ord(s[j])-64)
        b += str(chr(p))
    text2.delete(0.0,END)
    text2.insert(0.0,b)

 

기타 기능

 편의를 위해 엔트리의 입력 값들을 모두 지워주는 간단한 기능도 추가해보았다.

def clear():
    text2.delete(0.0,END)
    text1.delete(0.0,END)  
    entry1.delete(0,END)  
    entry2.delete(0,END)

 

실행 결과

 

암호화
복호화

 

전체 코드

from tkinter import *
win = Tk()

win.title('Encryption & Decryption')
win.geometry('400x400')

def encrypt():
    a = entry1.get()
    b = ""

    def factorize(n):
        factors = []
        k = 2

        while n % k == 0:
            factors.append(k)
            n //= k

        k = 3
        while k * k <= n:
            while n % k == 0:
                factors.append(k)
                n //= k
            k += 2

        if n > 2:
            factors.append(n)

        return factors

    for i in range(0,len(a)):
        c=ord(a[i])
        factor = factorize(c)
        for j in range(0,len(factor)):
            b = b + chr(factor[j]+64)
        if i !=len(a)-1:
            b = b + 'F'
    
    text1.delete(0.0,END)
    text1.insert(END,b)

def decrypt():
    a = str(entry2.get())
    b = ''
    list = a.split('F')
    for i in range(0,len(list)):
        p = 1
        s = str(list[i])
        for j in range(0,len(s)):
            p *= int(ord(s[j])-64)
        b += str(chr(p))
    text2.delete(0.0,END)
    text2.insert(0.0,b)

def clear():
    text2.delete(0.0,END)
    text1.delete(0.0,END)  
    entry1.delete(0,END)  
    entry2.delete(0,END)

entry1 = Entry()
entry2 = Entry()
btn1 = Button(text='암호화',command=encrypt)
text1 = Text()
btn2 = Button(text='복호화',command=decrypt)
text2 = Text()
lb1 = Label(text='*암호화할 문자 입력*',fg='red')
lb2 = Label(text='*암호화 결과*',fg='red')
lb3 = Label(text='*복호화할 문자 입력*',fg='red')
lb4 = Label(text='*복호화 결과*',fg='red')
clear_button = Button(text='지우기',command=clear)

entry1.place(x=150,y=10)
entry2.place(x=150,y=230)
btn1.place(x=150,y=30)
text1.place(x=150,y=100,width=200,height=50)
lb1.place(x=10,y=10)
lb2.place(x=40,y=100)
lb3.place(x=10,y=230)
lb4.place(x=40,y=320)
btn2.place(x=150,y=250)
text2.place(x=150,y=320,width=200,height=50)
clear_button.place(x=340,y=10)

win.mainloop()

 

아쉬운 점

 

 F가 단어 사이사이에 계속 들어가서 단어를 나누는 문자라고 쉽게 추측할 수 있을 것 같다. 따라서 난수표를 이용해서 단어 중간중간에 들어가는 문자를 바꿔주면 조금 더 개선할 수 있을 것 같다.