매일 업데이트
2022-10-19 08:22 9 min

Python을 사용하여 모스 부호 변환기를 만드는 방법

모스 부호의 세계: 파이썬으로 인코딩 및 디코딩하기

모스 부호는 점(.)과 대시(-) 그리고 공백을 조합하여 메시지를 표현하는 독특한 통신 방식입니다. 주로 비밀 메시지나 군사 통신 등에서 사용되어 왔으며, 오늘날에도 여전히 그 가치를 인정받고 있습니다.

영화에서 해군이 모스 부호를 사용하는 장면을 종종 보셨을 텐데요, 여기서는 바로 그 모스 부호를 다루면서, 파이썬을 사용하여 영문을 모스 부호로 변환하거나 그 반대로 변환하는 프로그램을 만들어 볼 것입니다.

모스 부호란 무엇인가?

모스 부호는 영문 알파벳, 숫자, 특수 문자 등에 고유한 패턴을 할당하여 메시지를 암호화합니다. 각 문자 또는 기호에 해당하는 모스 부호 패턴을 이해하면 메시지를 손쉽게 인코딩하고 디코딩할 수 있습니다. 더 자세한 정보와 패턴은 위키백과의 모스 부호 페이지에서 찾아볼 수 있습니다.

본 튜토리얼에서는 일반적인 영문 텍스트를 모스 부호로 바꾸거나, 모스 부호를 다시 영문 텍스트로 되돌리는 과정을 학습합니다. 영문 알파벳, 숫자, 기본 구두점을 중심으로 인코딩과 디코딩을 다루지만, 원한다면 추가 문자를 포함하도록 코드를 확장할 수 있습니다. 핵심 원리를 이해하면 쉽게 응용할 수 있습니다.

모스 부호에서는 대문자와 소문자 알파벳이 동일한 패턴을 사용한다는 점을 기억해야 합니다. 이는 모스 부호가 대소문자를 구분하지 않는 통신 환경에서 주로 사용되기 때문입니다.

이제 인코딩과 디코딩을 위한 코딩 여정을 시작해 봅시다.

영문을 모스 부호로 변환하는 방법

일반 영문 텍스트를 모스 부호로 변환하는 과정은 비교적 간단합니다. 다음 단계를 살펴보겠습니다.

  1. 영문 알파벳, 숫자, 특수 문자와 해당하는 모스 부호 패턴을 매핑한 사전을 만듭니다.
  2. 텍스트를 순회하며 각 문자에 해당하는 모스 부호 패턴을 결과에 추가합니다.
    • 모스 부호는 각 문자 뒤에 하나의 공백을, 각 단어 뒤에 두 개의 공백을 추가하여 구분합니다.
    • 텍스트에서 공백을 만나면 단어의 경계를 표시하므로 결과에 두 개의 공백을 추가합니다.
  3. 생성된 문자열이 최종 모스 부호가 됩니다.
  4. 결과를 반환합니다.

파이썬 코드를 직접 작성해 봅시다. 처음에는 완벽하지 않더라도 걱정하지 마세요.

다음은 영문 텍스트를 모스 부호로 인코딩하는 파이썬 코드 예시입니다.

# 문자들을 모스 부호에 매핑하는 사전
CHARS_TO_MORSE_CODE_MAPPING = {
    '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': '--..',  '1': '.----', '2': '..---', '3': '...--', '4': '....-',
    '5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.',
    '0': '-----', '.': '.-.-.-', ',': '--..--', '?': '..--..', "'": '· − − − − ·',
    '!': '− · − · − −', '/': '− · · − ·',  '(': '− · − − ·',  ')': '− · − − · −',
    '&': '· − · · ·',  ':': '− − − · · ·', ';': '− · − · − ·',  '=': '− · · · −',
    '+': '· − · − ·',  '-': '− · · · · −', '_': '· · − − · −', '"': '· − · · − ·',
    '$': '· · · − · · −', '@': '· − − · − ·'
}
# 영문 텍스트를 모스 부호로 변환하는 함수
def to_morse_code(english_plain_text):
    morse_code = ""
    for char in english_plain_text:
        # 공백 문자를 확인하고 처리
        # 각 문자 뒤에 하나의 공백을, 단어 뒤에 두 개의 공백을 추가
        if char == ' ':
            morse_code += '  '
        else:
            # 사전을 사용하여 모스 부호로 변환하고 결과에 추가
            morse_code += CHARS_TO_MORSE_CODE_MAPPING[char.upper()] + ' '
    return morse_code
morse_code = to_morse_code(
    'koreantech.org produces high-quality technology & finance articles, makes tools, and APIs to help businesses and people grow.'
)
print(morse_code)

위 코드를 실행하면 아래와 같은 모스 부호 결과를 얻을 수 있습니다. 메시지를 변경하지 않았다면 터미널에도 비슷한 모스 부호가 출력될 것입니다.

--. . . -.- ..-. .-.. .- .-. .   .--. .-. --- -.. ..- -.-. . ...   .... .. --. .... − · · · · − --.- ..- .- .-.. .. - -.--   - . -.-. .... -. --- .-.. --- --. -.--   · − · · ·   ..-. .. -. .- -. -.-. .   .- .-. - .. -.-. .-.. . ... --..--   -- .- -.- . ...   - --- --- .-.. ... --..--   .- -. -..   .- .--. .. ...   - ---   .... . .-.. .--.   -... ..- ... .. -. . ... ... . ...   .- -. -..   .--. . --- .--. .-.. .   --. .-. --- .-- .-.-.-

성공적으로 모스 부호를 생성했습니다! 이제 다음 단계로 넘어갈 시간입니다.

디코딩 코드를 작성하기 전에 잠시 멈춰서, 어떻게 디코딩을 해야 할지 생각해 봅시다.

...

가장 먼저 떠올려야 할 것은 `CHARS_TO_MORSE_CODE_MAPPING` 사전을 뒤집는 것입니다. 직접 수동으로 하는 것은 번거롭고, 원래 매핑이 변경될 때마다 업데이트해야 합니다. 따라서 사전을 뒤집는 코드를 작성해 보겠습니다.

def reverse_mapping(mapping):
    reversed = {}
    for key, value in mapping.items():
        reversed[value] = key
    return reversed

위의 코드는 주어진 사전의 키-값 쌍을 뒤집어, 값은 새로운 키가 되고, 키는 새로운 값이 됩니다.

이제 모스 부호를 일반 영문 텍스트로 디코딩하는 데 필요한 모든 준비가 완료되었습니다. 바로 디코딩 여정을 시작해 보겠습니다.

모스 부호를 영어로 변환하는 방법

디코딩 알고리즘은 모스 부호 인코딩 과정의 반대 순서로 진행됩니다. 다음은 모스 부호를 일반 영문 텍스트로 디코딩하는 알고리즘입니다.

  1. 이전에 만든 유틸리티 함수를 사용하여 `CHARS_TO_MORSE_CODE_MAPPING` 사전을 뒤집습니다.
  2. 모스 부호를 순회하며 현재 모스 부호 문자를 추적합니다.
    • 공백을 만나면 디코딩할 모스 부호 문자가 완성되었다는 의미입니다.
      • 만약 현재 모스 부호 문자가 비어있고, 연속된 두 개의 공백이 있다면, 이는 영문 텍스트에서 단어 구분 공백이므로, 결과에 공백을 추가합니다.
      • 위 조건이 거짓이면, 사전을 사용하여 현재 모스 부호 문자를 디코딩하고 결과에 추가한 뒤, 현재 모스 부호 문자를 초기화합니다.
    • 공백이 아니면 현재 모스 부호 문자에 추가합니다.
  3. 마지막 문자가 남아 있다면, 사전을 이용하여 디코딩하고 결과에 추가합니다.
  4. 최종 결과를 반환합니다.

이제 위 알고리즘에 따른 코드를 확인해 보겠습니다.

def reverse_mapping(mapping):
    reversed = {}
    for key, value in mapping.items():
        reversed[value] = key
    return reversed
# 문자들을 모스 부호에 매핑하는 사전 (이전 코드에서 가져옴)
CHARS_TO_MORSE_CODE_MAPPING = {
    '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': '--..',  '1': '.----', '2': '..---', '3': '...--', '4': '....-',
    '5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.',
    '0': '-----', '.': '.-.-.-', ',': '--..--', '?': '..--..', "'": '· − − − − ·',
    '!': '− · − · − −', '/': '− · · − ·',  '(': '− · − − ·',  ')': '− · − − · −',
    '&': '· − · · ·',  ':': '− − − · · ·', ';': '− · − · − ·',  '=': '− · · · −',
    '+': '· − · − ·',  '-': '− · · · · −', '_': '· · − − · −', '"': '· − · · − ·',
    '$': '· · · − · · −', '@': '· − − · − ·'
}
MORSE_CODE_TO_CHARS_MAPPING = reverse_mapping(CHARS_TO_MORSE_CODE_MAPPING)

def to_english_plain_text(morse_code):
    english_plain_text = ""
    current_char_morse_code = ""
    i = 0
    while i < len(morse_code) - 1:
        # 각 문자 처리
        if morse_code[i] == ' ':
            # 단어 구분 공백 확인
            if len(current_char_morse_code) == 0 and morse_code[i + 1] == ' ':
                english_plain_text += ' '
                i += 1
            else:
                # 디코딩된 문자를 결과에 추가
                english_plain_text += MORSE_CODE_TO_CHARS_MAPPING[
                    current_char_morse_code]
                current_char_morse_code = ""
        else:
            # 현재 모스 부호 문자에 모스 부호 문자 추가
            current_char_morse_code += morse_code[i]
        i += 1
    # 마지막 문자 처리
    if len(current_char_morse_code) > 0:
        english_plain_text += MORSE_CODE_TO_CHARS_MAPPING[
            current_char_morse_code]
    return english_plain_text
english_plain_text = to_english_plain_text(
    '--. . . -.- ..-. .-.. .- .-. .   .--. .-. --- -.. ..- -.-. . ...   .... .. --. .... − · · · · − --.- ..- .- .-.. .. - -.--   - . -.-. .... -. --- .-.. --- --. -.--   · − · · ·   ..-. .. -. .- -. -.-. .   .- .-. - .. -.-. .-.. . ... --..--   -- .- -.- . ...   - --- --- .-.. ... --..--   .- -. -..   .- .--. .. ...   - ---   .... . .-.. .--.   -... ..- ... .. -. . ... ... . ...   .- -. -..   .--. . --- .--. .-.. .   --. .-. --- .-- .-.-.- '
)
print(english_plain_text)

인코딩 함수에서 생성된 모스 부호를 입력으로 사용했습니다. 위 프로그램을 실행하면 다음과 같은 결과가 출력됩니다.

koreantech.org PRODUCES HIGH-QUALITY TECHNOLOGY & FINANCE ARTICLES, MAKES TOOLS, AND APIS TO HELP BUSINESSES AND PEOPLE GROW.

참고: 사전에서 매핑에 대문자 알파벳을 사용했기 때문에 출력된 결과는 영어 대문자로만 표시됩니다.

마무리하며

디코딩 함수의 결과가 모두 대문자로 출력되는 것을 확인했습니다. 만약 원한다면 영어 알파벳의 대소문자를 추적하여 입력된 그대로 출력하도록 프로그램을 개선할 수 있습니다. 모스 부호 자체는 대소문자를 구분하지 않지만, 코딩 연습으로 시도해 볼 만한 좋은 과제입니다.

이것으로 모스 부호 튜토리얼을 마칩니다. 이제 모스 부호를 만날 때마다 우리가 만든 프로그램을 활용해 보세요.

즐거운 코딩하세요! 👨‍💻

추가로 파이썬을 사용하여 임의의 암호를 생성하는 방법도 살펴보는 것을 추천합니다.

저자
Korea

기술 트렌드와 실용적인 팁을 전하는 लेखक입니다.