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:
- Stwórz słownik, w którym przyporządkujesz wzory kodu Morse’a do liter, cyfr i znaków interpunkcyjnych języka angielskiego.
- 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.
- Otrzymany ciąg znaków to nasz zakodowany tekst w kodzie Morse’a.
- 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:
- Odwróć słownik `CHARS_TO_MORSE_CODE_MAPPING` za pomocą napisanej wcześniej funkcji.
- 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.
- Gdy napotkamy spację, oznacza to, że mamy cały znak do odkodowania.
- Jeśli pozostał jakiś ostatni znak, dodaj go do wyniku po odkodowaniu ze słownika.
- 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
Maciej – redaktor, pasjonat technologii i samozwańczy pogromca błędów w systemie Windows. Zna Linuxa lepiej niż własną lodówkę, a kawa to jego główne źródło zasilania. Pisze, testuje, naprawia – i czasem nawet wyłącza i włącza ponownie. W wolnych chwilach udaje, że odpoczywa, ale i tak kończy z laptopem na kolanach.