文章目录

  • 前言
  • 一、什么是莫尔斯电码(也有翻译为摩尔斯)
    • 1. 电报的工作原理:
    • 2. 莫尔斯电码编码表:
      • 国际莫尔斯电码(字母)
      • 国际莫尔斯电码(数字)
      • 国际莫尔斯电码(标点)
  • 二、使用Python将英文消息转莫尔斯电码并模拟发报与解码
    • 1. 生成代码字典
    • 2. 模拟发报与译码(完整源代码)
  • 三、使用Python将中文消息转莫尔斯电码并模拟发报
    • 1. 发送中文怎么办?
    • 2. 编码与译码
    • 3. 模拟中文发报与译码(完整源代码)
  • 总结

前言

先展示下程序效果:

python模拟CW通联发报与译码

CW是等幅电报通信(Continuous Wave)的英文字头简称,CW电报通信是业余电台众多通信方式中主要的常用联络方式之一,在业余电台通信联络中通称为CW方式。

由于很多人对CW中使用的电报码还不是很熟悉,更多只是电视剧谍报人员收发报过程中听过到的滴滴答答的声音。

那么电报码到底是什么样的?它的消息发送有什么规律和要求呢?本文将为您一一揭晓。甚至您可以自己编一段消息来体验下发报的过程和声音。当然收报解译需要一个熟练过程。

CW的学习步骤简单的讲只有3个字:“背”“抄”“发”, 那就是背码表,练抄收,练发报的一个过程。

本文将向您展示什么是莫尔斯电码,以及如何使用其发送和接收英文、中文消息。通过Python程序模拟CW电报发报与译码,包括英文和中文,方便练习发报节奏和听音解码。感兴趣的朋友可以试试。代码均已测试OK。

一、什么是莫尔斯电码(也有翻译为摩尔斯)

电报出现于19世纪,是人类最早用电信号传送信息的方式,在19世纪和20世纪也是主要的通信方式之一。进入21世纪后,电报这种通信方式基本不再使用。但在业务无线电里,它依然活跃,而且由于设备的升级,普通人只要考取的业余无线电B类操作证也可以架台和原方的HAM进行CW的通联。这里就有必要解释下电报的工作原理。

1. 电报的工作原理:

发报方将文字转换成特定的编码,然后以电信号把这些编码发送出去;收报方抄收这些编码,然后翻译成文字。双方都有一个相同的代码本,上面记载了文字和编码的对应关系。显然,使用私有的代码本,可避免无关收报方破译电报文本。

电报通常使用国际摩尔斯电码进行收发报。摩尔斯电码使用点(·)和划(-)两种符号的特定组合表示不同的字符,在用声音表示时,其中点(·)为短信号,一个时间单位,读作滴,划(-)为长信号,三个时间单位,读作嗒;两个信号间隔一个时间单位,字符间隔三个时间单位,单词间隔七个时间单位。

2. 莫尔斯电码编码表:

国际莫尔斯电码(字母)

字符 代码 字符 代码 字符 代码 字符 代码 字符 代码 字符 代码 字符 代码
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 -----

国际莫尔斯电码(标点)

字符 代码 字符 代码 字符 代码 字符 代码 字符 代码 字符 代码
. ·-·-·- : —··· , –··– ; -·-·-· ? ··–·· = -···-
·----· / -··-· ! -·-·– - -····- _ ··–·- " ·-··-·
( -·–· ) -·–·- $ ···-··- & ·-··· @ ·–·-· + ·-·-·

二、使用Python将英文消息转莫尔斯电码并模拟发报与解码

1. 生成代码字典

# 莫尔斯代码字典
MORSE_CODE_DICT = { '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':'-----', '.':'·-·-·-', ':':'---···', ',':'--··--', ';':'-·-·-·', '?':'··--··', '=':'-···-',"'":'·----·', '/':'-··-·', '!':'-·-·--', '-':'-····-', '_':'··--·-', '"':'·-··-·','(':'-·--·', ')':'-·--·-', '$':'···-··-', '&':'·-···', '@':'·--·-·', '+':'·-·-·'}

由于字典默认使用单引号定义键名,而英文字符单引号也是字符之一,故这里使用双引号,解决的键名定义问题"‘":’·----·’
如果使用双引号定义字符串,那么字符串里如果需要用到双引号,需要使用转移符,修改为:\" 即可。

2. 模拟发报与译码(完整源代码)

# -*- coding: utf-8 -*-# 莫尔斯代码字典
MORSE_CODE_DICT = { '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 en2morse(message): # 将字符转为莫尔斯代码字符串message = ' '.join(message.split()) # 将多个空格替换为一个,避免程序报错。cipher = '' for letter in message: if letter != ' ': cipher += MORSE_CODE_DICT[letter] + ' 'else: cipher += ' 'return cipher def morse2en(code): # 将莫尔斯代码字符串转为字符code = code.strip() # 剔除前后空格,避免程序报错。code += ' 'decipher = '' citext = '' for letter in code: if (letter != ' '): i = 0citext += letterelse: i += 1if i == 2 : decipher += ' 'else: decipher += list(MORSE_CODE_DICT.keys())[list(MORSE_CODE_DICT.values()).index(citext)] citext = '' return decipherdef morse2beep(code):# 对莫尔斯字符串转为声音import winsound,time,sys# 间隔时间:滴=1t,嗒=3t,滴嗒间=1t,字符间=3t,单词间=7tdi = 80da = di*3sp = di/1000chr_sp = di*3/1000word_sp = di*7/1000vol = 600for i in range(len(code)):if code[i] == '.':winsound.Beep(vol,di)# 其中vol表示声音大小,di表示发生时长,1000为1秒elif code[i] == '-':winsound.Beep(vol,da)            elif code[i] == ' ':if  i < len(code)-1 and code[i+1] == ' ' :time.sleep(word_sp)else:time.sleep(chr_sp)else:time.sleep(sp)print(code[i],end='')sys.stdout.flush()print()def msg2beep2msg(msg):# 将消息转换为莫尔斯代码并显示,再通过声音模拟发报,最后进行译码。print(message)ret = en2morse(message.upper()) # 消息转为莫尔斯代码print(ret)morse2beep(ret)  # 通过声音展示莫尔斯代码,模拟发报ret = morse2en(ret)  # 莫尔斯代码转为消息,模拟解码print(ret)if __name__ == '__main__': message = "CQ CQ CQ DE BI9ABG BI9ABG BI9ABG PSE K " # 字符串里使用:”"“,需要修改为:”\"“。msg2beep2msg(message)

三、使用Python将中文消息转莫尔斯电码并模拟发报

1. 发送中文怎么办?

在电话普及前,已开始使用电报。但要将几千个汉字发成电报貌似比26个英文字母要复杂,于是人们想出对汉字使用4位数字进行编码的方案,也就是汉字电报码。

汉字电报码使用四位数字标识一个汉字,如:我的代码是 2053,西安分别是6007 1344。

既然知道了逻辑,我们把汉字电报码下载下来,使用程序做成字典,调用的时候去查询即可。由于字典太大,我们将汉字电报码保存在hzdbm.txt,和程序放在同一个目录。

当然发报人和收报人需要使用同一个字典,才可以正常译码。这也就是密码本的来由。这也就是电视中破译电报桥段的来由。无线电波信号是公开传递的,但没有密码本,自然收到也无法译码。你也可以自己定义字典,可以定义属于你的专属密码本。不过,作为一般大家都适用通用电码本。下面为大家准备了一个电码字典。

中文电报码-其它文档类资源-CSDN文库 https://download.csdn.net/download/popboy29/87522106

2. 编码与译码

发报时先查字典找到对应汉字的编码,然后对数字使用莫尔斯电码发报;解译的过程和编码的过程相反,先将收到的莫尔斯电码继续下来,4位数字对应一个汉字,然后再按数字查字典找到对应的汉字,就可以看到中文消息内容。

3. 模拟中文发报与译码(完整源代码)

首先将第二部分代码完整保存为morsecode.py,再将以下内容和hzdbm.txt一同保存在同一目录。

from morsecode import *def hz_morsecode():# 将汉字电报码转为dict,方便调用。由于数字唯一,故使用4位数字字符串作为键名。import osHZ_CODE_DICT = {}with open(os.path.dirname(os.path.abspath(__file__))+'\\hzdbm.txt',encoding='utf-8-sig') as file:line = file.read()line = line.replace('\n', '') # 删除末尾的换行符line_list = line.strip().split(" ")for i in range(len(line_list)):HZ_CODE_DICT[line_list[i][1:5]] = line_list[i][0:1]return HZ_CODE_DICTHZ_CODE_DICT = hz_morsecode()
# print(HZ_CODE_DICT)def get_keys(d, value):# 根据值来查找键return [k for k, v in d.items() if v == value]def get_hz_morsecode(hz_msg):# 将字符转为莫尔斯代码字符串hz_msg = ''.join(hz_msg.split()) # 将多个空格替换为一个,避免程序报错。cipher = '' hz_msg = hz_msg.upper() # 英文需要先全部改为大写for hz in hz_msg: if hz in MORSE_CODE_DICT.keys():# 如果是英文字符后数字,直接输出cipher += en2morse(hz) + ' ' elif hz == ' ':cipher += ' 'else:# 如果是汉字字符,转换为4位数字再转莫尔斯码输出# print(get_keys(HZ_CODE_DICT, hz))for i in get_keys(HZ_CODE_DICT, hz)[0]:cipher += en2morse(i) + ' 'return cipher def hz2beep2hz(msg):# 将汉字消息逐字转换为4位代码,再将数字转换为莫尔斯代码并显示,再通过声音模拟发报,最后进行译码。print(hz_msg)ret = get_hz_morsecode(hz_msg)print(ret)morse2beep(ret)  # 通过声音展示莫尔斯代码,模拟发报ret = morse2en(ret)  # 莫尔斯代码转为消息,模拟解码print(ret)#import rehz_code_str = ret.replace(' ', '')print(hz_code_str)hz_code_str = re.findall(r'[0-9]{4}', hz_code_str)print(hz_code_str)for i in hz_code_str:print(HZ_CODE_DICT[i],end='')print()if __name__ == '__main__': hz_msg = "声音传递汉字"hz2beep2hz(hz_msg)

运行结果如下:

声音传递汉字
… .---- .---- -… --… …— ----. ----. ----- …— --… —… -… -… --… --… …-- …-- … …— .---- …-- .---- -…
… .---- .---- -… --… …— ----. ----. ----- …— --… —… -… -… --… --… …-- …-- … …— .---- …-- .---- -…
5 1 1 6 7 2 9 9 0 2 7 8 6 6 7 7 3 3 5 2 1 3 1 6
511672990278667733521316
[‘5116’, ‘7299’, ‘0278’, ‘6677’, ‘3352’, ‘1316’]
声音传递汉字

相比于英文(26个字母+数字+标点符号)莫尔斯码,汉字只需要记住以下0-9数字的莫尔斯码即可(规律很明显,其实很简单),然后就是收到的消息四位数字一分隔,然后去查字典就好。小学生也可以很快掌握。

字符 代码 字符 代码 字符 代码 字符 代码 字符 代码
1 ·---- 2 ··— 3 ···– 4 ····- 5 ·····
6 -···· 7 –··· 8 —·· 9 ----· 0 -----

总结

CW,等幅电波,在无线电通信中,特指等幅电报。由于是形如“1、0”的二进制信号,故一般利用摩尔斯电码发送信息。它通过电键控制发信机产生短信号".“(点)和长信号”–"(划),并利用其不同组合表示不同的字符,从而组成单词和句子。与其他无线电通信方式相比,CW优点是所需设备简单、占用频带窄、发射效率高、在同等条件下通信距离更远。但是需要值机员熟练掌握收发报技术。

随着通讯科技的发展,电报已不再是主要的通讯方法。自从电话网络数字化以后,电报通讯变成为数位通讯网络内其中一种以文字通讯的应用,在传真机普及后更被传真所取代。当互联网及行动通讯日渐广泛使用以后,电报更进一步被电子邮件及短信所取代。一般人已不会使用电报通讯。

电报业务虽然已经过时,但是CW通联在业务无线电里依然收到广大HAM的热爱,除了短波CW传输距离远以外,电报这种最早出现的电子信息传递方式依然有其拥趸。也是一种情怀,也许是自由通信的热爱,也许是对古老通信方式的好奇,让我们一起CW通联吧。

注意:使用短波设备CW通联需要首先获得业余无线单B类操作证,并报备后方可设台通联。
(使用Python程序模拟发报、译码先在本地体验一下,这个就不用了。^-^)

【业余无线电】Python程序模拟CW电报发报与译码(包含英文和中文,方便练习发报节奏和听音解码)相关推荐

  1. Python程序模拟手工推算考虑兔子寿命的斐波那契数列

    开学第一课:拜托,一定不要这样问Python问题 中国大学MOOC"Python程序设计基础"免费学习地址 推荐图书: <Python程序设计(第3版)>,(ISBN: ...

  2. 用python画地球_如何用PYTHON程序模拟一个太阳系?

    描述一个星系和描述一所学校有的思维方式是一样的,其实和python关系不大.都可用面向对象思维来抽象.描述某个物体通常都要先思考几个问题:该物体是什么? 该物体有什么特征? 该物体有什么能力? 该物体 ...

  3. python模拟行星运动_如何用PYTHON程序模拟一个太阳系?

    描述一个星系和描述一所学校有的思维方式是一样的,其实和python关系不大.都可用面向对象思维来抽象.描述某个物体通常都要先思考几个问题:该物体是什么? 该物体有什么特征? 该物体有什么能力? 该物体 ...

  4. python生成6位验证码随机数,需包含英文字母大写、小写和数字(含代码和注释)

    具体见代码和注释: def get_code():code_list = []# for i in range(10): # 0~9for i in range(48,57): #ASCII表示的数字 ...

  5. 如何退出python程序_python怎么退出程序

    python程序退出方式[sys.exit() os._exit() os.kill() os.popen(...)]. 1. sys.exit() 执行该语句会直接退出程序,这也是经常使用的方法,也 ...

  6. Python程序访问北京预约挂号平台

    2019独角兽企业重金招聘Python工程师标准>>> 通过Python程序模拟访问北京预约挂号统一平台,包括验证码识别.登陆.按医院.时间.科室查询可约号等. 本程序仅为学习使用, ...

  7. python老是报参数未定义_浅谈Python程序的错误:变量未定义

    Python程序的错误种类 Python程序的错误分两种.一种是语法错误(syntax error).这种错误是语句的书写不符合Python语言的语法规定.第二种是逻辑错误(logic error). ...

  8. 退出python命令行-在cmd命令行里进入和退出Python程序的方法

    在cmd命令行里进入和退出Python程序的方法 进入: 直接输入python即可,如图所示 退出: 1:输入exit(),回车 2:输入quit(),回车 3:输入ctrl+z,回车 以上这篇在cm ...

  9. python未定义_浅谈Python程序的错误:变量未定义

    Python程序的错误种类 Python程序的错误分两种.一种是语法错误(syntax error).这种错误是语句的书写不符合Python语言的语法规定.第二种是逻辑错误(logic error). ...

最新文章

  1. Python IDLE theme
  2. 直接排序python实现
  3. 肖像:作家艺术家之一
  4. SentinelResource注解配置上_分布式系统集群限流_线程数隔离_削峰填谷_流量控制_速率控制_服务熔断_服务降级---微服务升级_SpringCloud Alibaba工作笔记0045
  5. iPhone13系列预计5499起;蔚来回应31岁企业家“自动驾驶”车祸去世;小米取消MIX4防丢失模式无卡联网服务|极客头条...
  6. Spring设置定时器配置
  7. mysql中regexp用法_mysql 中查询语句表达式REGEXP用法
  8. 程序员代码面试指南:IT名企算法与数据结构题目最优解(第2版) 左程云
  9. 老版本xcode下载_iOS秘籍】-下载历史版本App超详细教程
  10. Java docx4j 操作word 1.0
  11. canvas画圆形进度条
  12. 离职,第 10 天,有点心酸。。。
  13. Hadoop1.0,2.0,3.0区别
  14. GitHub · 如何创建文件夹
  15. Opencv源码之平面点集的最小包围圆
  16. Google hacking(谷歌语法)
  17. 如何查看三菱PLC生产日期与版本信息?
  18. leetcode 1074. Number of Submatrices That Sum to Target(和为target的子矩阵个数)
  19. Docker多主机管理Docker Machine
  20. 好玩的话剧 节选之 相亲的密谋

热门文章

  1. flink实时消费kafka中oracle的DML数据写入mysql
  2. 每日新的总结-20180118
  3. 又多了一座电站,总投资超百亿,云南曲靖这回真的来了大项目
  4. cmd执行命令行程序时有时会卡住
  5. 什么是核心交换机?选择核心交换机的重要考虑因素
  6. C语言——实验一:查验身份证(身份证号码的校验码)
  7. 基于STM32单片机甲醛二氧化碳温度湿度采集系统
  8. matlab最炫名族风,Matlab演奏《最炫民族风》的代码
  9. uni-app中引入uViewUI框架
  10. sql 2008的错误代码解释(转载)