Jak stworzyć tłumacz alfabetu Morse’a za pomocą Pythona

Szyfr Morse’a to system reprezentowania wiadomości za pomocą kombinacji kropek, kresek i przerw. Jest powszechnie wykorzystywany do przesyłania tajnych informacji.

Zapewne spotkałeś się z użyciem kodu Morse’a w filmach, zwłaszcza w scenach z marynarką wojenną, gdzie służy on do komunikacji. Mówimy o tym samym szyfrze, lecz w naszym przypadku stworzymy program w języku Python, który będzie dokonywał translacji z języka angielskiego na kod Morse’a i odwrotnie.

Czym jest kod Morse’a?

Alfabet Morse’a posiada przypisany unikalny wzór składający się z kropek i kresek dla każdej litery alfabetu angielskiego, cyfry, znaku interpunkcyjnego i innych symboli. Znając te wzorce, łatwo jest zakodować i odkodować wiadomość. Szczegółowe informacje oraz tablice kodów można znaleźć na stronie Wikipedii poświęconej kodowi Morse’a.

W tym przewodniku pokażemy, jak przekształcić zwykły tekst angielski w kod Morse’a i w drugą stronę. Podczas procesu kodowania będziemy posługiwać się literami alfabetu angielskiego, cyframi oraz znakami interpunkcyjnymi. Po opanowaniu podstawowych zasad kodowania i dekodowania, rozszerzenie systemu o kolejne symbole będzie bardzo proste.

Istotne jest, że zarówno małe, jak i duże litery w języku angielskim są reprezentowane przez ten sam wzór kodu Morse’a. Wynika to z faktu, że alfabet Morse’a jest używany przede wszystkim do komunikacji, gdzie rozróżnianie wielkości liter nie ma znaczenia, jak w codziennych rozmowach.

Przejdźmy teraz do części praktycznej, czyli do kodowania i dekodowania.

Konwersja z angielskiego na kod Morse’a

Algorytm przekształcania tekstu angielskiego na kod Morse’a jest nieskomplikowany. Oto jego opis:

  1. Stwórz słownik, w którym przyporządkujesz wzory kodu Morse’a do liter, cyfr i znaków interpunkcyjnych języka angielskiego.
  2. Przejdź przez każdy znak tekstu i dodaj do wyniku odpowiadający mu wzór kodu Morse’a.
    • W kodzie Morse’a po każdym znaku występuje pojedyncza spacja, a po każdym słowie podwójna.
    • Jeśli w tekście napotkamy spację (separator słów), musimy dodać do wyniku dwie spacje.
  3. Otrzymany ciąg znaków to nasz zakodowany tekst w kodzie Morse’a.
  4. Zwróć wynik.

Spróbuj napisać kod w Pythonie. Nie martw się, jeśli nie uda ci się go od razu napisać w całości.

Prześledźmy kod odpowiedzialny za konwersję tekstu angielskiego na kod Morse’a:

# Słownik przypisujący znaki do kodu Morse'a
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': '-----',
    '.': '.-.-.-',
    ',': '--..--',
    '?': '..--..',
    '\'': '· − − − − ·',
    '!': '− · − · − −',
    '/': '− · · − ·',
    '(': '− · − − ·',
    ')': '− · − − · −',
    '&': '· − · · ·',
    ':': '− − − · · ·',
    ';': '− · − · − ·',
    '=': '− · · · −',
    '+': '· − · − ·',
    '-': '− · · · · −',
    '_': '· · − − · −',
    '"': '· − · · − ·',
    '$': '· · · − · · −',
    '@': '· − − · − ·',
}

# Funkcja konwertująca tekst na kod Morse'a
def to_morse_code(english_plain_text):
    morse_code=""
    for char in english_plain_text:
        # Dodawanie spacji: pojedyncza po znaku, podwójna po słowie
        if char == ' ':
            morse_code += '  '
        else:
            # Dodawanie zakodowanego znaku do wyniku
            morse_code += CHARS_TO_MORSE_CODE_MAPPING[char.upper()] + ' '
    return morse_code

morse_code = to_morse_code(
    'newsblog.pl produces high-quality technology & finance articles, makes tools, and APIs to help businesses and people grow.'
)
print(morse_code)

Poniżej znajduje się wynik działania powyższego kodu. Powinieneś zobaczyć podobny kod Morse’a w swoim terminalu, o ile nie zmieniłeś wiadomości.

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

Brawo! Otrzymaliśmy kod Morse’a. Zapewne domyślasz się, co będzie następne.

Zanim jednak przejdziemy do programu dekodującego, zastanówmy się przez chwilę, jak powinien wyglądać kod, który będzie tłumaczył kod Morse’a z powrotem na tekst.

Niewątpliwie jednym z kroków powinno być odwrócenie słownika `CHARS_TO_MORSE_CODE_MAPPING`. Robienie tego ręcznie jest żmudne i wymagałoby aktualizacji przy każdej zmianie w oryginalnym mapowaniu. Napiszmy więc kod, który automatycznie odwróci słownik.

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

Powyższy kod zamienia klucze i wartości w słowniku. Otrzymany słownik będzie zawierał wartości z oryginalnego słownika jako klucze, a klucze z oryginalnego słownika jako wartości.

Mamy teraz wszystkie elementy potrzebne do zdekodowania kodu Morse’a na tekst angielski. Przejdźmy zatem do procesu dekodowania.

Konwersja z kodu Morse’a na angielski

Aby uzyskać algorytm dekodowania, musimy odwrócić proces kodowania. Zobaczmy jak wygląda algorytm dekodowania z kodu Morse’a na tekst angielski:

  1. Odwróć słownik `CHARS_TO_MORSE_CODE_MAPPING` za pomocą napisanej wcześniej funkcji.
  2. Iteruj po kodzie Morse’a, śledząc aktualny wzór kodu Morse’a.
    • Gdy napotkamy spację, oznacza to, że mamy cały znak do odkodowania.
      • Jeśli aktualny znak kodu Morse’a jest pusty i mamy dwie kolejne spacje, dodaj separator słowa, czyli pojedynczą spację, do tekstu wynikowego.
      • Jeśli powyższy warunek jest fałszywy, pobierz zdekodowany znak ze słownika i dodaj go do wyniku. Zresetuj aktualny znak kodu Morse’a.
    • Jeśli nie napotkaliśmy spacji, dołącz obecny symbol do aktualnego znaku Morse’a.
  3. Jeśli pozostał jakiś ostatni znak, dodaj go do wyniku po odkodowaniu ze słownika.
  4. Zwróć końcowy rezultat.

Spójrzmy na kod implementujący powyższy algorytm:

def reverse_mapping(mapping):
    # Kod funkcji z poprzedniego fragmentu
  
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:
        # Przejście przez każdy znak
        if morse_code[i] == ' ':
            # Sprawdzanie końca słowa
            if len(current_char_morse_code) == 0 and morse_code[i + 1] == ' ':
                english_plain_text += ' '
                i += 1
            else:
                # Dodawanie zdekodowanego znaku do wyniku
                english_plain_text += MORSE_CODE_TO_CHARS_MAPPING[
                    current_char_morse_code]
                current_char_morse_code=""
        else:
            # Dodawanie znaku do obecnego kodu Morse'a
            current_char_morse_code += morse_code[i]
        i += 1

    # Dodawanie ostatniego znaku
    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)

Podałem ten sam kod Morse’a, który został wygenerowany wcześniej. Po uruchomieniu powyższego kodu, otrzymamy następujący tekst:

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

Pamiętaj: wynik jest przedstawiony w alfabecie angielskim, dużymi literami, ponieważ w słowniku do mapowania zostały użyte wielkie litery.

Podsumowanie

Jak widzimy, wynik działania funkcji dekodującej jest zapisany wielkimi literami. Możesz udoskonalić program, zmieniając go tak, aby odzwierciedlał wielkość liter z oryginalnego tekstu, śledząc małe i duże litery. Nie jest to związane z samym kodem Morse’a, ponieważ małe i duże litery mają identyczny wzór. Zachęcamy do spróbowania, ponieważ kodowanie to świetna zabawa.

To wszystko w tym tutorialu. Korzystaj z utworzonych programów, gdy następnym razem spotkasz się z kodem Morse’a.

Udanego kodowania 👨‍💻

Możesz również sprawdzić, jak można wygenerować losowe hasło w Pythonie.


newsblog.pl