首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

Python 實作摩斯密碼翻譯器:含聲音播放、PyGame 整合完整指南

     編輯:更多程式設計知識

摩斯密碼是經典的編碼通訊方式,將字元轉為「點」(.) 和「划」(-) 序列。本文實作完整的 Python 摩斯密碼翻譯器,包含字元編碼/解碼、時序控制、PyGame 聲音播放、錯誤處理,可作為教學專案或應急通訊工具。

核心規格

摩斯密碼對照表(標準國際電信聯盟 ITU-R M.1677)


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': '----.',
    '.': '.-.-.-', ',': '--..--', '?': '..--..', "'": '.----.', '!': '-.-.--',
    '/': '-..-.',  '(': '-.--.',  ')': '-.--.-', '&': '.-...',  ':': '---...',
    ';': '-.-.-.', '=': '-...-',  '+': '.-.-.',  '-': '-....-', '_': '..--.-',
    '"': '.-..-.', '$': '...-..-', '@': '.--.-.', ' ': '/'
}

完整實作程式碼


import pygame
import time
import sys
import os

# === 設定區 ===
ONE_UNIT = 0.15          # 基礎時間單位(秒),可調整速度
THREE_UNITS = 3 * ONE_UNIT
SEVEN_UNITS = 7 * ONE_UNIT
SOUND_DIR = "morse_sounds"  # 音效檔案目錄
FREQUENCY = 800          # 蜂鳴器頻率 (Hz)

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': '----.', '.': '.-.-.-', ',': '--..--', '?': '..--..',
    "'": '.----.', '!': '-.-.--', '/': '-..-.', '(': '-.--.', ')': '-.--.-',
    '&': '.-...', ':': '---...', ';': '-.-.-.', '=': '-...-', '+': '.-.-.',
    '-': '-....-', '_': '..--.-', '"': '.-..-.', '$': '...-..-', '@': '.--.-.',
    ' ': '/'
}

def verify_message(message):
    """驗證訊息只包含支援字元"""
    valid_chars = set(MORSE_CODE.keys())
    for char in message.upper():
        if char not in valid_chars:
            raise ValueError(f"不支援的字元: '{char}' (ASCII: {ord(char)})")

def play_sound(duration):
    """播放指定時長的蜂鳴聲(使用 pygame 生成正弦波)"""
    # 動態生成音效避免需外部檔案
    sample_rate = 44100
    n_samples = int(sample_rate * duration)
    buf = bytearray()
    for i in range(n_samples):
        t = i / sample_rate
        # 正弦波
        val = int(32767 * 0.5 * (1 + __import__('math').sin(2 * __import__('math').pi * FREQUENCY * t)))
        buf.extend(val.to_bytes(2, 'little', signed=True))
    
    sound = pygame.mixer.Sound(buffer=bytes(buf))
    sound.play()
    time.sleep(duration)

def play_morse_element(element):
    """播放單一點/划"""
    if element == '.':
        play_sound(ONE_UNIT)
    elif element == '-':
        play_sound(THREE_UNITS)
    # 元素間間隙
    time.sleep(ONE_UNIT)

def encode_to_morse(message):
    """編碼訊息為摩斯密碼字串"""
    morse_parts = []
    for char in message.upper():
        if char == ' ':
            morse_parts.append('/')
        else:
            morse_parts.append(MORSE_CODE.get(char, '?'))
    return ' '.join(morse_parts)

def play_morse_message(message):
    """播放完整摩斯密碼訊息"""
    verify_message(message)
    print(f"原文: {message}")
    morse = encode_to_morse(message)
    print(f"摩斯: {morse}")
    
    words = message.upper().split(' ')
    for wi, word in enumerate(words):
        for ci, char in enumerate(word):
            code = MORSE_CODE[char]
            print(f"  {char}: {code}")
            for element in code:
                play_morse_element(element)
            # 字元間間隙 (已在 play_morse_element 結尾包含 1 unit)
            time.sleep(TWO_UNITS := 2 * ONE_UNIT)  # 額外 2 unit = 總共 3 unit
        
        # 單詞間間隙 (最後一個字元不需額外)
        if wi < len(words) - 1:
            time.sleep(SEVEN_UNITS - THREE_UNITS)  # 已有 3 unit,補足 7 unit

def main():
    print("=== 摩斯密碼翻譯器 ===")
    print("支援字元: A-Z, 0-9, 空格, . , ? ' ! / ( ) & : ; = + - _ \" $ @")
    print("輸入 'quit' 結束\n")
    
    # 初始化 pygame mixer
    pygame.mixer.init(frequency=44100, size=-16, channels=1, buffer=512)
    
    try:
        while True:
            try:
                message = input("請輸入訊息: ").strip()
                if message.lower() in ('quit', 'exit', 'q'):
                    break
                if not message:
                    continue
                play_morse_message(message)
                print("播放完成\n")
            except ValueError as e:
                print(f"錯誤: {e}\n")
            except KeyboardInterrupt:
                print("\n中斷播放")
                break
    finally:
        pygame.mixer.quit()

if __name__ == "__main__":
    main()

關鍵技術細節解析

1. 動態生成正弦波音效(無需外部檔案)


import pygame
import math

def generate_tone(frequency=800, duration=0.1, volume=0.5):
    sample_rate = 44100
    n_samples = int(sample_rate * duration)
    buf = bytearray()
    for i in range(n_samples):
        t = i / sample_rate
        # 正弦波:y = A * sin(2πft)
        val = int(32767 * volume * math.sin(2 * math.pi * frequency * t))
        buf.extend(val.to_bytes(2, 'little', signed=True))
    return pygame.mixer.Sound(buffer=bytes(buf))

# 使用
tone = generate_tone(800, 0.3)
tone.play()

2. 精確時序控制


# 摩斯標準時序(以 1 unit 為基準)
DOT = 1
DASH = 3
INTRA_CHAR = 1      # 點/划之間
INTER_CHAR = 3      # 字元之間
INTER_WORD = 7      # 單詞之間

# 實作策略:每個元素播放後 sleep 1 unit
# 字元結束額外 sleep 2 unit (總共 3)
# 單詞結束額外 sleep 4 unit (總共 7)

3. 錯誤處理與驗證


def verify_message(message):
    valid = set(MORSE_CODE.keys())
    invalid = [c for c in message.upper() if c not in valid]
    if invalid:
        raise ValueError(f"不支援字元: {set(invalid)}")

進階擴展功能

1. 解碼功能(摩斯 → 文字)


# 反向查找表
MORSE_TO_CHAR = {v: k for k, v in MORSE_CODE.items()}

def decode_morse(morse_str):
    """解碼摩斯密碼字串(元素以空格分隔,字元以 / 分隔)"""
    words = morse_str.strip().split(' / ')
    result = []
    for word in words:
        chars = word.split()
        decoded = ''.join(MORSE_TO_CHAR.get(c, '?') for c in chars)
        result.append(decoded)
    return ' '.join(result)

print(decode_morse(".... . .-.. .-.. --- / .-- --- .-. .-.. -.."))
# HELLO WORLD

2. GUI 介面


import tkinter as tk
from tkinter import ttk, scrolledtext

class MorseGUI:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("摩斯密碼翻譯器")
        # 輸入區
        ttk.Label(self.root, text="輸入文字:").pack()
        self.input_text = scrolledtext.ScrolledText(self.root, height=5)
        self.input_text.pack(fill=tk.X, padx=5, pady=5)
        # 輸出區
        ttk.Label(self.root, text="摩斯密碼:").pack()
        self.output_text = scrolledtext.ScrolledText(self.root, height=5)
        self.output_text.pack(fill=tk.X, padx=5, pady=5)
        # 按鈕
        ttk.Button(self.root, text="編碼並播放", command=self.encode_play).pack(pady=5)
        ttk.Button(self.root, text="解碼", command=self.decode).pack(pady=5)
    
    def encode_play(self):
        text = self.input_text.get("1.0", tk.END).strip()
        if text:
            morse = encode_to_morse(text)
            self.output_text.delete("1.0", tk.END)
            self.output_text.insert("1.0", morse)
            play_morse_message(text)
    
    def decode(self):
        morse = self.output_text.get("1.0", tk.END).strip()
        if morse:
            text = decode_morse(morse)
            self.input_text.delete("1.0", tk.END)
            self.input_text.insert("1.0", text)
    
    def run(self):
        self.root.mainloop()

3. 檔案輸出(WAV 音檔)


import wave
import struct

def save_morse_wav(message, filename="morse.wav"):
    """將摩斯密碼存為 WAV 檔案"""
    sample_rate = 44100
    morse = encode_to_morse(message)
    
    with wave.open(filename, 'wb') as wav:
        wav.setnchannels(1)
        wav.setsampwidth(2)
        wav.setframerate(sample_rate)
        
        for char in message.upper():
            if char == ' ':
                # 單詞間隙
                write_silence(wav, SEVEN_UNITS)
                continue
            code = MORSE_CODE.get(char, '')
            for element in code:
                if element == '.':
                    write_tone(wav, ONE_UNIT)
                elif element == '-':
                    write_tone(wav, THREE_UNITS)
                write_silence(wav, ONE_UNIT)  # 元素間
            write_silence(wav, TWO_UNITS)  # 字元間補足

def write_tone(wav, duration):
    # ... 寫入正弦波資料
    pass

def write_silence(wav, duration):
    # ... 寫入靜音資料
    pass

安裝與執行


# 安裝依賴
pip install pygame

# 執行
python morse_translator.py

# 或直接編碼不播放
python -c "from morse_translator import encode_to_morse; print(encode_to_morse('SOS'))"
# ... --- ...

總結

Python 實作摩斯密碼翻譯器涵蓋:標準編碼表、精確時序控制、動態音效生成、錯誤驗證、解碼反向查找、GUI/WAV 擴展。關鍵技術點:pygame.mixer.Sound(buffer=...) 動態音效、time.sleep() 微秒級時序、dict 雙向映射。此專案適合學習聲音合成、時序控制、字串處理,也可作為無線電通訊教學輔助工具。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
元素符號時長單位說明
點.1 單位基本單位
划-3 單位3 個點時長
元素間間隙(點/划之間)1 單位同一字元內
字元間間隙(字母之間)3 單位3 個點時長
單詞間間隙(單詞之間)7 單位7 個點時長