Transposition Cipher(전위(轉位) 암호화)

‘Cracking Codes with Python’ 이란 책을 보고 있는 중이다. 처음부터 끝까지 다 보고 싶긴 한데, 과연 그럴 수 있을지는 순전히 내 의지에 달려있다.

아무튼.. 초반 70여쪽은 그냥 하루만에 훑어볼 수 있었다. 파이썬에 관한 내용도, 암호화에 관한 내용도 모두 기초였기 때문에 별로 막힐 부분이 없었다.

첫번째 고비는, 그리고 아직도 거기에 계속 머물러 있긴 한데, Transposition Cipher(Chapter 7) 였다. 암호화 자체는 굉장히 쉽지만, 그것을 파이썬으로 구현하기가 약간 헷갈렸다.

정확히 말하자면, ‘암호화’는 금방 구현했는데, 복호화에서 살짝 막혔고, 그러다보니 하기가 싫어져서(이런 끈기하고는..) 몇 날 며칠을 뭉그적거리다가, 겨우 겨우 방법을 찾아냈다.

그리고 나서, 책에 있는 코드를 확인해봤다.
과연, 나랑은 얼마나 달리 풀어냈을까..


나는 리스트를 만들고, 리스트 안에 리스트를 넣는 방식을(‘배열’로 얘길하자면 2차원 배열) 생각했다.
그런데, 이렇게 하면, 모자란 공간을 처리하는데 문제가 발생한다.

예를 들어, 평문이 ‘Common sense is not so common.’ 이고, Key 는 8 이라고 하면, 글자 수는 30 인데, 필요한 칸(Block?)수는 총 32(8*4 줄)이 되어, 2칸만큼 공백이 생긴다.
이 공백을 감안하지 않으면, List 의 IndexError 가 발생한다.
이를 위해 try / except 를 사용했다.

for loop 를 2회 사용하려다가 보니 try 를 사용할 수 밖에 없었다.

# 평문을 key 크기로 나눠서(예를 들어 key=8 이라면 8 글자씩) 리스트에 넣기.
for i in range(len(PLAIN_TEXT)):
        
    # print("i: ",i)

    temp_list.append(PLAIN_TEXT[i])

    # temp_list 의 크기가 키 크기만큼 되면, temp_list 자체를 enc_text 에 추가.
    if i % key == (key - 1) or i == len(PLAIN_TEXT) - 1:
        enc_text.append(temp_list)
        temp_list=[]

##### Encryption #######

final_enc=[]

# 마지막 리스트 크기는 key 보다 작은 6 개인데.. 여기서 오류가 발생한다.
# 오류를 회피하기 위해 IndexError 를 try 로 처리했다.

# j 는 열, k 는 행
for j in range(key):
    for k in range(len(enc_text)) :
        try:
            added = enc_text[k][j]

        # 위 예의 x x 처럼 빈 공간이 있을 수 있다. 그를 방지하기 위한 설계.
        except IndexError:
            added = ''
        final_enc.extend(added)

# 최종 출력        
ENCRYPTED=''.join(final_enc)

이렇게 했는데.. 일단 코드가 길다.
책에선 이렇게 간단하게 했다.

나는 for 중첩하여 사용했던 반면, 책에서는 for 1 회와 while 을 사용했다. 따라서 try 를 사용할 필요가 없다.

def encryptMessage(key, message):
    # list * int : list 안 인자를 int 만큼 반복
    ciphertext = [''] * key

    # 암호문 안의 컬럼 수(즉, key 길이) 만큼 반복.
    for column in range(key):
        currentIndex = column

        # currentIndex 가 평문(message) 의 길이를 넘어서기 전까지 반복
        while currentIndex < len(message):
            ciphertext[column] += message[currentIndex]

            # currentIndex 를 키만큼 이동
            currentIndex += key

    return ''.join(ciphertext)

내가 풀어낸 복호화는 더 복잡해질 수 밖에 없다.
이 내용은 또 다른 글에서.

안녕하세요. 글 남겨주셔서 고맙습니다.