Toolmingo
Guides9 min read

What is Morse Code? History, Alphabet, and How to Encode/Decode

Learn how Morse code works, see the complete alphabet and number table, and encode or decode messages in JavaScript, Python, Go, and PHP.

Morse code is one of the oldest digital communication systems ever invented — and it still works perfectly today. Whether you're studying for a ham radio license, building a fun project, or just curious how dots and dashes carry meaning, here's everything you need to know.

What is Morse code?

Morse code is a method of encoding text as a series of dots (short signals) and dashes (long signals). It was invented in the 1830s by Samuel Morse and Alfred Vail for use with the electric telegraph.

Each letter, digit, and punctuation mark has a unique sequence of dots and dashes:

  • A dot (.) = a short signal
  • A dash (-) = a signal three times longer than a dot
  • A short pause separates symbols within one letter
  • A longer pause separates letters
  • An even longer pause separates words

Originally sent as electrical pulses over wire, Morse code can also be conveyed by sound, light, radio waves — or even tapping on a surface.

Why Morse code matters today

Morse code is no longer required for maritime or aviation communication, but it's still used by:

  • Amateur (ham) radio operators — many still use it for long-distance contacts
  • Military signaling — light-based SOS signals
  • Accessibility — people with severe motor disabilities can communicate via single-switch input
  • Competitive "CW" (continuous wave) radio — an active global hobby
  • Encoding puzzles — CTF competitions, escape rooms, geocaching

SOS (... --- ...) is internationally recognized regardless of language.

The complete Morse code alphabet

Letters

Letter Morse Letter Morse
A .- N -.
B -... O ---
C -.-. P .--.
D -.. Q --.-
E . R .-.
F ..-. S ...
G --. T -
H .... U ..-
I .. V ...-
J .--- W .--
K -.- X -..-
L .-.. Y -.--
M -- Z --..

Digits

Digit Morse
0 -----
1 .----
2 ..---
3 ...--
4 ....-
5 .....
6 -....
7 --...
8 ---..
9 ----.

Common punctuation

Symbol Morse
. .-.-.-
, --..--
? ..--..
! -.-.--
/ -..-.
@ .--.-.
= -...-

How encoding works

Converting text to Morse is a lookup-table operation:

  1. Convert the input to uppercase.
  2. For each character, find its Morse symbol.
  3. Separate Morse symbols for each letter with a space.
  4. Separate words with three spaces (or a /).

Example: encode SOS

S = ...
O = ---
S = ...

Result: ... --- ...

Example: encode HELLO WORLD

H = ....
E = .
L = .-..
L = .-..
O = ---

W = .--
O = ---
R = .-.
L = .-..
D = -..

Result: .... . .-.. .-.. ---   .-- --- .-. .-.. -..

(Three spaces or / mark the word boundary.)

Encoding and decoding in code

JavaScript

const MORSE_CODE = {
  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: "--..",
  "0": "-----", "1": ".----", "2": "..---", "3": "...--",
  "4": "....-", "5": ".....", "6": "-....", "7": "--...",
  "8": "---..", "9": "----.",
  ".": ".-.-.-", ",": "--..--", "?": "..--..", "!": "-.-.--",
  "/": "-..-.", "@": ".--.-.", "=": "-...-",
};

const DECODE_MAP = Object.fromEntries(
  Object.entries(MORSE_CODE).map(([k, v]) => [v, k])
);

function encode(text) {
  return text
    .toUpperCase()
    .split("")
    .map((ch) => (ch === " " ? "   " : (MORSE_CODE[ch] ?? "")))
    .join(" ")
    .trim();
}

function decode(morse) {
  return morse
    .split("   ")
    .map((word) =>
      word.split(" ").map((sym) => DECODE_MAP[sym] ?? "?").join("")
    )
    .join(" ");
}

console.log(encode("SOS"));            // "... --- ..."
console.log(encode("HELLO WORLD"));    // ".... . .-.. .-.. ---   .-- --- .-. .-.. -.."
console.log(decode("... --- ..."));    // "SOS"

Python

MORSE_CODE: dict[str, str] = {
    "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": "--..",
    "0": "-----", "1": ".----", "2": "..---", "3": "...--",
    "4": "....-", "5": ".....", "6": "-....", "7": "--...",
    "8": "---..", "9": "----.",
    ".": ".-.-.-", ",": "--..--", "?": "..--..", "!": "-.-.--",
    "/": "-..-.",  "@": ".--.-.", "=": "-...-",
}

DECODE_MAP = {v: k for k, v in MORSE_CODE.items()}


def encode(text: str) -> str:
    parts = []
    for ch in text.upper():
        if ch == " ":
            parts.append("   ")
        elif ch in MORSE_CODE:
            parts.append(MORSE_CODE[ch])
    return " ".join(parts).replace("    ", "   ").strip()


def decode(morse: str) -> str:
    words = morse.split("   ")
    return " ".join(
        "".join(DECODE_MAP.get(sym, "?") for sym in word.split())
        for word in words
    )


print(encode("SOS"))          # "... --- ..."
print(encode("Hello World"))  # ".... . .-.. .-.. ---   .-- --- .-. .-.. -.."
print(decode("... --- ..."))  # "SOS"

Go

package main

import (
    "fmt"
    "strings"
)

var morseCode = map[string]string{
    "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": "--..",
    "0": "-----", "1": ".----", "2": "..---", "3": "...--",
    "4": "....-", "5": ".....", "6": "-....", "7": "--...",
    "8": "---..", "9": "----.",
}

func buildDecodeMap() map[string]string {
    m := make(map[string]string, len(morseCode))
    for k, v := range morseCode {
        m[v] = k
    }
    return m
}

func encode(text string) string {
    var parts []string
    for _, ch := range strings.ToUpper(text) {
        s := string(ch)
        if s == " " {
            parts = append(parts, "  ") // extra space between words
        } else if code, ok := morseCode[s]; ok {
            parts = append(parts, code)
        }
    }
    return strings.Join(parts, " ")
}

func decode(morse string) string {
    decodeMap := buildDecodeMap()
    words := strings.Split(morse, "   ")
    result := make([]string, 0, len(words))
    for _, word := range words {
        var letters []string
        for _, sym := range strings.Split(word, " ") {
            if ch, ok := decodeMap[sym]; ok {
                letters = append(letters, ch)
            }
        }
        result = append(result, strings.Join(letters, ""))
    }
    return strings.Join(result, " ")
}

func main() {
    fmt.Println(encode("SOS"))         // ... --- ...
    fmt.Println(decode("... --- ...")) // SOS
}

PHP

<?php

const MORSE_CODE = [
    "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" => "--..",
    "0" => "-----", "1" => ".----", "2" => "..---", "3" => "...--",
    "4" => "....-", "5" => ".....", "6" => "-....", "7" => "--...",
    "8" => "---..", "9" => "----.",
    "." => ".-.-.-", "," => "--..--", "?" => "..--..", "!" => "-.-.--",
    "/" => "-..-.",  "@" => ".--.-.", "=" => "-...-",
];

function morseEncode(string $text): string {
    $parts = [];
    foreach (str_split(strtoupper($text)) as $ch) {
        if ($ch === " ") {
            $parts[] = "  "; // word separator
        } elseif (isset(MORSE_CODE[$ch])) {
            $parts[] = MORSE_CODE[$ch];
        }
    }
    return implode(" ", $parts);
}

function morseDecode(string $morse): string {
    $decodeMap = array_flip(MORSE_CODE);
    $words = explode("   ", $morse);
    $result = [];
    foreach ($words as $word) {
        $letters = [];
        foreach (explode(" ", $word) as $sym) {
            $letters[] = $decodeMap[$sym] ?? "?";
        }
        $result[] = implode("", $letters);
    }
    return implode(" ", $result);
}

echo morseEncode("SOS") . "\n";          // ... --- ...
echo morseEncode("HELLO WORLD") . "\n";  // .... . .-.. .-.. ---   .-- --- .-. .-.. -..
echo morseDecode("... --- ...") . "\n";  // SOS

Timing rules for audio/radio transmission

When Morse code is transmitted as sound or radio, the timing ratios matter:

Element Duration
Dot 1 unit
Dash 3 units
Gap between symbols (same letter) 1 unit
Gap between letters 3 units
Gap between words 7 units

Amateur radio speed is measured in WPM (words per minute), where "PARIS " (5 characters + space) is the standard test word. Beginners typically start at 5–10 WPM; experienced operators often exceed 30 WPM.

Common Morse phrases to memorize

Message Morse Meaning
SOS ... --- ... International distress signal
CQ -.-. --.- Calling any station (ham radio)
73 --... ...-- Best regards (ham radio)
88 -.... ----. Love and kisses (ham radio)
OK --- -.- Confirmed
R .-. Received / Roger
AR .-.-. End of message
SK ... -.- End of contact (signing off)

Encoding Morse in other media

Morse code isn't limited to audio:

  • Light: flashlight SOS is universally understood — three short, three long, three short
  • Vibration: many accessibility devices use Morse via vibration patterns
  • Visual: signal flags, blinking indicators on aircraft and ships
  • Steganography: hidden in images, music, or text patterns in security puzzles

Encode Morse code online

Need to quickly convert text to Morse — or play it back as audio? Use the Morse Code Converter to encode, decode, and hear the dots and dashes in your browser.

FAQ

Q: Is Morse code still used today? Yes, by amateur (ham) radio operators worldwide. It's also used in accessibility technology, military signaling, and hobbyist projects. The ITU no longer requires it for maritime licenses, but it remains popular.

Q: What does SOS stand for? Nothing — SOS was chosen because ... --- ... is easy to send and recognize, not because it's an acronym. "Save Our Souls" and "Save Our Ship" are retroactive folk explanations.

Q: How long does it take to learn Morse code? Most people can learn the alphabet in a few hours. Reaching a conversational speed of 5 WPM takes a few weeks of daily practice. The Koch method (learning characters at full speed, one at a time) is the most effective approach.

Q: Can I use Morse code in Python with a library? Yes. Libraries like pyaudio can generate audio tones, and you can map your encoded Morse string to beeps. The encoding/decoding logic is simple enough to write yourself (as shown above) or use a package like morse-talk.

Q: What's the difference between International and American Morse code? International Morse code (ITU) is the current standard. American Morse (used on early US telegraphs) had additional characters and different timing rules. Today, "Morse code" almost always means the ITU version.

Related tools

Keep reading

All Toolmingotools are free & run in your browser

No sign-up, no upload, no watermark. Your files never leave your device.

Browse all tools