[Softeer]

Question

Language: Python

해당 문제는 주어진 문제의 조건에 따라 구현하면되는 비교적 간단한 유형의 문제이다.

주어진 평문에 대해 암호화를 수행하는 것이 문제의 목표인데, 암호화는 크게 3가지 단계로 구성된다.

  1. 키맵의 구성

주어진 key를 5*5 형태의 행렬 형태로 변환하는 작업을 수행한다. alpha_location이라는 dictionary을 통해 각각의 문자의 row,col 위치를 저장하고, key_map이라는 이차원 배열을 통해 각각 row,col 별로 문자를 저장한다. 이렇게 2개의 저장구조를 활용하여 row,col -> 문자, 문자 -> row,col을 빠르게 할 수 있도록 한다.

def next_location(row,col):
    col+=1
    if col==5:
        row+=1
        col=0
    return row,col

#알파벳 채우기
alpha_locations={chr(index):(-1,-1) for index in range(ord("A"),ord("A")+26) if index != ord("J")}
key_matrix=[[""] *5 for _ in range(5)]
row,col=0,0

#key에 대한 맵핑 수행
for char in cipher_key:
    #이미 입력된 알파벳이면 넘어간다.
    if alpha_locations[char] !=(-1,-1):
        continue
    alpha_locations[char]=(row,col)
    key_matrix[row][col]=char
    row,col=next_location(row,col)
    

#key에 없는 나머지 알파벳에 대한 맵핑
for key in alpha_locations:
    #이미 입력된 알파벳이면 넘어간다.
    if alpha_locations[key] != (-1,-1):
        continue

    alpha_locations[key]=(row,col)
    key_matrix[row][col]=key
    row,col=next_location(row,col)
  1. 두 쌍씩 분리

평문을 두 문자씩 묶어서 쌍을 만드는 작업을 수행한다.

pairs=[]
length=len(plain)
index=0
while index < length:
    #마지막에 하나의 인덱스만 남는 경우
    if index==length-1:
        pairs.append(plain[index]+"X")
        break
    #연속된 문자가 서로 같은 경우 X,Q를 삽입한다.
    if plain[index]==plain[index+1]:
        if plain[index]=="X":
            pairs.append(plain[index]+"Q")
        else:
            pairs.append(plain[index]+"X")
        index+=1
    #그외의 경우 서로 붙여서 쌍을 만든다.
    else:
        pairs.append(plain[index]+plain[index+1])
        index+=2
  1. 암호화

분리된 문자쌍에 대해 key_map, alpha_locations을 이용하여 암호화를 수행한다.

#암호화 수행
for pair in pairs:
    pair1_row,pair1_col=alpha_locations[pair[0]]
    pair2_row,pair2_col=alpha_locations[pair[1]]
    cipher1,cipher2="",""
    #행이 같은 경우
    if pair1_row==pair2_row:
        cipher1=key_matrix[pair1_row][(pair1_col+1)%5]
        cipher2=key_matrix[pair1_row][(pair2_col+1)%5]
    #열이 같은 경우 
    elif pair1_col==pair2_col:
        cipher1=key_matrix[(pair1_row+1)%5][pair1_col]
        cipher2=key_matrix[(pair2_row+1)%5][pair1_col]
    #그 외
    else:
        cipher1=key_matrix[pair1_row][pair2_col]
        cipher2=key_matrix[pair2_row][pair1_col]
    cipher_text+=(cipher1+cipher2)

Solution

import sys
def next_location(row,col):
    col+=1
    if col==5:
        row+=1
        col=0
    return row,col

def solution():
    #알파벳 채우기
    alpha_locations={chr(index):(-1,-1) for index in range(ord("A"),ord("A")+26) if index != ord("J")}
    key_matrix=[[""] *5 for _ in range(5)]
    row,col=0,0

    #key에 대한 맵핑 수행
    for char in cipher_key:
        #이미 입력된 알파벳이면 넘어간다.
        if alpha_locations[char] !=(-1,-1):
            continue
        alpha_locations[char]=(row,col)
        key_matrix[row][col]=char
        row,col=next_location(row,col)
        
    
    #key에 없는 나머지 알파벳에 대한 맵핑
    for key in alpha_locations:
        #이미 입력된 알파벳이면 넘어간다.
        if alpha_locations[key] != (-1,-1):
            continue

        alpha_locations[key]=(row,col)
        key_matrix[row][col]=key
        row,col=next_location(row,col)
    
    #두쌍씩 분해
    pairs=[]
    length=len(plain)
    index=0
    while index < length:
        #마지막에 하나의 인덱스만 남는 경우
        if index==length-1:
            pairs.append(plain[index]+"X")
            break
        #연속된 문자가 서로 같은 경우 X,Q를 삽입한다.
        if plain[index]==plain[index+1]:
            if plain[index]=="X":
                pairs.append(plain[index]+"Q")
            else:
                pairs.append(plain[index]+"X")
            index+=1
        #그외의 경우 서로 붙여서 쌍을 만든다.
        else:
            pairs.append(plain[index]+plain[index+1])
            index+=2

    cipher_text=""
    #암호화 수행
    for pair in pairs:
        pair1_row,pair1_col=alpha_locations[pair[0]]
        pair2_row,pair2_col=alpha_locations[pair[1]]
        cipher1,cipher2="",""
        #행이 같은 경우
        if pair1_row==pair2_row:
            cipher1=key_matrix[pair1_row][(pair1_col+1)%5]
            cipher2=key_matrix[pair1_row][(pair2_col+1)%5]
        #열이 같은 경우 
        elif pair1_col==pair2_col:
            cipher1=key_matrix[(pair1_row+1)%5][pair1_col]
            cipher2=key_matrix[(pair2_row+1)%5][pair1_col]
        #그 외
        else:
            cipher1=key_matrix[pair1_row][pair2_col]
            cipher2=key_matrix[pair2_row][pair1_col]
        cipher_text+=(cipher1+cipher2)
        
    print(cipher_text)
if __name__ == "__main__":
    plain=str(sys.stdin.readline().strip())
    cipher_key=str(sys.stdin.readline().strip())

    solution()

댓글남기기