ADFGVX암호


 ADFGVX 암호문을 파이썬으로 완성했었는데  
다시한번 짚어보며 써볼려고 합니다.
ADFGVX 암호는 제1차 세계대전때 독일군이 처음 사용한
암호방식이라고 합니다. 
ADFGVX 암호는 알파벳 26문자와 숫자 10개로
36문자로 이루어져 있습니다.
- ADFGVX 암호 표

위에표는 ADFGVX암호이고
저렇게 6X6 행렬로 이루어져 있습니다.
이표를 보고 암호화를 하면 되는데요 
표를 보는 방법을 설명하겠습니다.

평문을 gwangju
키를 secure로 정하겠습니다.
먼저 g 를 ADFGVX표로 암호문을 만들면
DA가 되는데요 
예를 들어  숫자 5를 암호문으로 만들고 싶은면
5가 교차돼있는 지점이 X와D가 교차돼있는걸 볼수 있습니다.

제가 그려논 1번 2번순서로 
왼쪽꺼부터 써주면 되요
즉,
P를 암호문으로 하면 FG
U를 암호문으로 하면 GF
H를 암호문으로 하면 DD
이런식으로 암호문을 만들어주면 됩니다.




ADFGVX암포 효를 보고 암홈누을 만들면 
위에 표처럼 되는데
gwangju을 암호문으로 하면
DA GV AA FD DA DG GF이렇게 나옵니다.
아직 여기서 끝이아니고
아까 암호키를 SECURE라고 했는데
여기서 주의할게 SECURE에서 E가 중복되면
그러면 중복된문자나 숫자를 지워줘야됩니다.
이럴때 앞에 E와 뒤에 E가 있다면
뒤에것을 삭제하게 코드를 짜시면 되요

그러면 암호키는 SECUR이 최종형태로 되요

그럼 5x5행렬 표를 만들어주고 위에 SECUR를 써주고
밑에 채우는방법은 
아까 나온 암호문을 처음부터 순서대로 DAGVAAFDDADGGF
로 채워줍니다 그런 한칸 모자라는데 패딩 값으로 P를 채워줍니다.
그리고 
알파벳 순서대로 문자들을 다시 뽑아줘야 됩니다.
여기서는 




                    
CERSU순서입니다
C밑에 GDG부터 순서대로 적어주면
GDG AFG AAP DAD VDF 가 되서
결국 ADFGVX 암호를 이용하여
암호화한 값이 나옵니다.
평문을 두번을 통하여 암호화 를 하였는데
복호화는
역시 똑같은 방법으로 돌리시면 됩니다.

밑에 사진은 실제 코드를 이용하여 실행한 사진입니다. 




일단 출력 결과값을로 보여주는건
1단계 환자암호를 통한 문자변환
2단계 키를 통해 문자열을 정렬한거

그러면 복호화는
2단계 표로 했던걸 키를 다시 불러와서
원료 문자열 순서대로 복구해주고
또 ADFGVX 표를 이용하여 평문으로 돌려주면
됩니다.
 복호화 코드는 뺄테니 한번 직접 짜보시면
좋을거 같아요


 

ENC = 0 # 암호화
DEC = 1
#평문입력
plaintext = (input("평문을입력해주세요:"))
text = plaintext.upper()
plainlen = len(plaintext)  #문자의 길이를 나타내준다
#암구어
xplain = input("암구어 입력해주세요:")
plain = xplain.upper()
xplainsize = len(xplain)

def ADFGVX(plain,mode,strlen):
    # 환자암호함수
    #ADFGVX 암호
    a = [['A','B','C','D','E','F'],
    ['G','H','I','J','K','L'],
    ['M','N','O','P','Q','R'],
    ['S','T','U','V','W','X',],
    [ 'Y','Z','0','1','2','3',],
    ['4','5','6','7','8','9',]]
#a 의 길이는 6
    ad = len(a)
    b = ['A','D','F','G','V','X',]
    ba = len(b)
    secure =""
    xsecure =""
    #환자암호화  값
    if mode ==ENC:
        for m in range(strlen):
            for i in range(ad):     #b의 값
                for u in range(ad): # b의값
                    if plain[m] == a[i][u]:   #L 은 [1][6] 니까 i 가 1 u 5 이면 동일
                        x = b[i]
                        y = b[u]
                        secure = secure+x+y
        return secure
    #환자암호문 복호화 값

#ADFGVX암호 로  암호화 한걸 저장
msg = ADFGVX(text,ENC,plainlen)
print("바뀐 암호문은:" ,msg)
#key값 중복 제거 하기
def  key(key):
    key_set = set() # 중복허용하지 않는데 인덱스 값 다 날라버림
    key = []
    for l in plain:      #ex APPLE 입력하면 for문은 5번 돌아간다.
        if l not in key_set:       #k값이 not in 으로 인해 key_set에 k 값이 있으면 FALSE 없으면 TRUE
            key.append(l)       #key=[] 에는 APPLE 하면 APLE 순서대로 입력돼서 출력된다
            key_set.add(l)      #key_set 은 set()중복 허용불가만 했기때문에 순서는 이상하게 저장된다.
    print("중복이면 제거 ",key)
    return key

#중복제거한 키값을 rkey 에 저장
rkey = key(key)
#문자와 키의 길의를 나타내준다
msgsize = len(msg) 
keysize = len(rkey)
#총글자수가 나누어 떨어지지 않으면 빈자리 채우기 위한 blocksize
if int(msgsize %keysize)>0:  #msgsize mod keysize 의 나머지가 0보다 클때 실행
    blocksize = int(msgsize/keysize +1)
else:
    blocksize  = int(msgsize/keysize)
 
def cipher_value(xplain):
    c = [['P']*blocksize for i in range(keysize)]
    m = 0
    #문자열 배치
    for x in range(blocksize):   
            for y in range(keysize):           
                if msgsize == m:
                        break
                c[y][x] = msg[m]
                m = m+1     #1 ,2,3,4,5,6,7,8,9
    for x in range(keysize):       #APPLE 가정 하면 중복제거하면 4번돌아간
        for y in range(blocksize):
             rkey[x] = rkey[x]+c[x][y]  #암구어 에 맞춰 키값 넣기
    rkey.sort()#암구어를 기준으로  알파벳 순으로 다시 재배치
    text = " "
    for x in range(keysize):
        text = text +(rkey[x][1:])  #rkey[0] [1:] key[0]번 값에서 0번째 순서 문자열 빼고 한마디로 키값제거
    return text
#환자암호 - 전치암호를 거친 결과물
cipher = cipher_value(msg)
print("최종암호문:",cipher)
#복호화를위한 원래 정렬안된 원래키값 key(key)호출
key = key(key)
text =['P']*keysize

for x in range(keysize):
    for y in range(keysize):
        if key[x] == rkey[y][0]:    #KEY[0] 값과 == reky[y][0] 같을때 일땐 rkey 앞에부분 이 A 면 저장
            text[x] = rkey[y]

for x in range(keysize):
        text[x] = text[x][1:]  #rkey[0] [1:] key[0]번 값에서 0번째 순서 문자열 빼고 한마디로 키값제거

#key값을 제거하고 배열 한걸 다시  문자로 재배치
xipher = [' ']*msgsize #암호문 크기만큼 [''] * msgsize 인덱스생성
m = 0


#마지막 다시환자암호넣어서 복호화
msg = ADFGVX(ptext,DEC,prin)

print("평문값:",msg)

 



 






 
 
                 
       






 
 
                 
       


댓글

댓글 쓰기

이 블로그의 인기 게시물

절차 지향 vs 객체지향 프로그래밍

선형(순차) 탐색 알고리즘