没错,我是高端吃瓜玩家(搞懂摩斯密码)

article/2025/8/20 4:52:24

前言

大家好,我是bigsai大赛哥,好久不见,甚是想念。

行了,咱们步入正轨,已经进入2022,在2021这一年,很多人的快乐消遣是在吃瓜快乐中度过的,有的作为主动吃瓜群众第一手掌握消息,有的作为第二手或者被动吃瓜者(比如我就是)。

然而,现在吃瓜可有难度了,因为有的瓜可能是假的,某博上搜不到,在一些网站上、聊天出现一个神秘串串!!

6f3ff88886220b211ae5d842729c2202.png

这一串是啥玩意,惊天大瓜表达的啥意思,该怎么解读?

这年头,没点知识连吃瓜群众都当不成(手动狗头)!作为程序员,不光要知道吃瓜的内容,还要知道吃瓜背后的技术!

好了,也不藏着掖着了,这一串就是大名鼎鼎的摩尔斯电码,也称摩斯密码,当然这是以文本的形式直接展现了,你在谍战剧中、战争剧中那些电报的滴滴哒哒的其实多半就是摩斯密码,趁着这个机会,好好了解一下摩尔斯密码吧!

摩尔斯电码源来

摩尔斯电码是怎么被发明的呢?是某个叫摩尔斯的天才发明的吗?

其实在摩尔斯之前,就有非常笨重的电报机,不过这种电报机用了26根线表示26种字母(肯定没学过计算机,妥妥的暴力美学),在实用方面很差。

在电气时代刚流行的时代,并没有电话手机,人们探索的第一步是如何用电去传讯消息,在这期间摩尔斯发明了电报并且获得了专利,并且他的团队(有说是他的助手艾尔菲德·维尔发明的摩尔斯电码)配套发明了一套传输的规则被称为摩尔斯电码

在当时利用电去传输消息信号是非常了不起的发明,而电报机接收方会根据电报电流通过控制一直笔打印发送方按下电报机的内容,电流通过长划线就长,电流通过时间段划线就短,没有电流通过纸上空白就增长。

74623a105abe3c89add7039729756933.png

然后接收方根据摩尔斯电码规则转译成对应的字符单词即可。主要用( · )和(—)的不同排列组合表示不同的数字或字符,然后点划之间、字符之间、字母之间停顿时间都是不同的。

摩尔斯电码为什么用点划两种表示一些单词字母呢?

大家可以考虑一下,如果一种符号确实理论上行得通,但是一个符号能够表示的内容太少,一个连续点表示1、两个连续点表示2、三个连续点表示3…… n种数字字符就需要n个数量符号数才能表示,这样下去符号使用效率是非常低效了。

如果是三种符号表示,确实能够表示的内容非常多,长度为5的符号就可以表示243个字符。能够表达的内容其实已经远远超过日常使用(0-9数字,26个字母,几个常用符号)。看起来好像很紧凑但是三种符号讯号根本不好传递,很容易出现混淆问题(比如在电报等其他传输那么会分成长、中、短三种不容易甄别,远不如长短两种容易区分)。

所以2就是一个非常神奇的数字,无论在计算机还是大自然都是非常巧妙的,01、长短、快慢、高低……都可以用两种符号表示,并且这些内容在现实生活中也是非常容易展示实现的,并且使用两种符号能够表示内容数量也是可以接收的,长度为5的符号就可以可以表示2^5=32种数字字符,所以这种长度还是能够被接收的。

2c2577b841d31ed41ff5c95cc9fe1a80.png

摩尔斯电码艺术

我们关注摩尔斯电码的一些含义。上面提到摩尔斯团队早期发明的摩尔斯电码是一些表示数字的点和划用一个电键可以敲击出点、划以及中间的停顿(长按,短按表示点(.)、划(—),松开不按表示停顿),点划、字符、单词等时长和停顿为:

  1. ( · ):1 (读  dit ,时间占据1t )

  2. (—):111 (读  dah ,时间占据3t )

  3. 字符内部的停顿(在点和划之间):0 (时间占据1t )

  4. 字符间停顿:000 ( 时间占据3t )

  5. 单词间的停顿:0000000 ( 时间占据7t )

有了上面的规则,我们大致能知道摩尔斯电码长什么样,那么怎么甄别它代表什么内容呢?这时候需要查找一本代码表才能知道每个字母数字符号等对应的内容,其中一些主要内容如下:

319337bedde9b36acd8c6a3220ca03d1.png

来源维基百科

我靠,这个看起来好像有点记忆难度啊,确实是有难度的,根据这些内容符号的特性,有些教授给摩尔斯密码搞成一棵二叉搜索树让大家更便捷记忆摩尔斯密码,二叉树表示的国际摩尔斯电码。图中每一分叉的左支为点(·),右支为划(-),直到到达所需要表示的字符为止,这样一棵树可以更容易找到相似内容的联系:

c7340938dec8c571d45d2e5310e8c413.png

来自维基百科

不过,摩尔斯电码还是非常有智慧的(这里不清楚是发明者这么有智慧还是记忆大师发现这么牛批的规律),摩尔斯电码的字母和数字还有着一套象形记忆的方式,这个可不是跟咱们牛批的中文有点相似么,其具体的记忆图为:

06f3484b8d1af82440ce6a9c8de95542.png

来源dreamstime.com

一个MORSE CODE 的摩尔斯电码的表示和记忆为:

7bc663a670bfea12acba1f3a0cab8ab9.png

掌握摩尔斯密码

好了,通过上面的介绍,想必你对摩尔斯电码有了一定的了解,对于我们普通人来说,不需要会记住每个字母数字对应的摩尔斯电码,我们需要掌握的就是能够懂得摩尔斯电码编解码的方式和规则即可。

简单的说,我们要掌握发送和接收的规则,将单词字母转成摩尔斯电码发送,将接收的摩尔斯电码转成单词单词字母即可。

比如我们现在有:ge gie hao 这段话,其中

a : .- ;e : .;g : --.;h : .... ;i : ..;o: ---

那么纸面上对应的摩尔斯编码为(视觉上可甄别的距离):

--. .     --. .. .    .... .- ---

如果用声音来表示(滴哒),那就是这样的:

--.  . /  --.   ..  .  /  ....   .-   ---  
哒哒滴 滴 哒哒滴 滴滴 滴   滴滴滴滴 滴哒 哒哒哒

上面就大概是声音的传播过程(/表示单词停顿时间长一些),如果用非常精确的二进制来表示,0表示没数据,1表示有数据(电铃按下),其实哒是滴的三倍时常,其二进制对应为:

--.  . /  --.   ..  .  /  ....   .-   --- 
111011101 000 1 0000000  111011101 000 101 000 1 0000000 1010101 000 10111 000 11101110111

可能看起来不是很直观,我优化一下(实际上01是连续的没有括号的)

--.        .      /       --.        ..      .    /     ....        .-          --- 
(111011101)000(1)0000000(111011101)000(101)000(1)0000000(1010101)000(10111)000(11101110111)哒哒滴       滴  (大停顿)  哒哒滴       滴滴     滴 (大停顿) 滴滴滴滴      滴哒         哒哒哒

上面就是比较标准的摩尔斯电码,其中三个1表示哒(三倍滴的时常),一个1表示滴,0表示没有电流数据,这个空档期也要把握火候的,滴哒之间是1t空闲时间,几个滴哒组成的字符之间是3t空闲时间,几个字符组成的一个单词之间是7t空闲时间。

这样,摩尔斯电码的规则你就差不多是拿捏了。同样给你一个摩尔斯电码,比照电码表也很容易给它转成对应语句。

不过在那个时代很多电报是按照长度收费的,然而很多人就用一些简要的单词字母表示一句话,于是常用缩写被很多人使用,这里不进行太多介绍,知道有点类似暗语就比如plmm:

4f9aae02b42e227e46f9c4451ab29383.png

此外,摩尔斯电码还有一些特殊符号,表示发错了、停止、终止、错误等等用来确保摩尔斯电码发送的正确性(毕竟人肯定会有脑子糊涂或者手抖时刻就按错了是吧)。

中文电码

对于欧美一些国家来说,他们用那些单词和字母使用标准的摩尔斯电码来通讯是没有任何问题的,毕竟26字母+数字+10个数字+少量符号就足够了,自摩尔斯电码在1835年发明后,一直只能用来传送英语或以拉丁字母拼写的文字,但是在中国甚至其他国家,怎么用电报进行通信呢?

拼音?

拼音虽然勉强传递一些消息,但是拼音会有很多造成很多解释错误,举个例子:

tai shuai le 可以表示太帅了,也可以表示太衰了。

ni tai mei le 可以表示你太美了,还能表示你太没了,还能表示镍钛没了……

主要是中文博大精深,所以拼音行不太通顺,于是清朝时候政府雇外国人设计了中文电报,中文电码表采用了四位阿拉伯数字作代号,简称“四码电报”,从0001到9999按四位数顺序排列,用四位数字表示最多一万个汉字、字母和符号。

中文电码,又称标准中文电码、中文商用电码、中文电报码或中文电报明码,原本是于电报之中传送中文信息的方法,它是第一个把汉字化作电子讯号的编码表,大家只需要知道它在初始时候采用的这种方式就行了

如果大家想查阅相关中文汉字对应的数字,可以在下面网站上查询:

https://apps.chasedream.com/chinese-commercial-code/

百科对应的中文电码也有:

https://baike.baidu.com/item/%E4%B8%AD%E6%96%87%E7%94%B5%E7%A0%81/2667759?fr=aladdin

但是中文电码是无理码并且数量也太多了,所以一般用户根本没法记忆使用,随着通信发展、电话、手机计算机的发展,中文电码的应用场景还是比较少的。

现在的各个网站中的中文摩斯密码,大家实现的大多不是标准的中文电码表对应的数字,很多是借助了其他编码—Unicode编码。Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode给每个字符提供了一个唯一的数字,不论是什么平台、不论是什么程序、不论是什么语言。

所以大部分实现中文摩斯密码的时候将对应中文字符转成4字节unicode(UCS-4),然后再将这四个字符进行摩尔斯编码即可。

b62c6f9fbedfd97f927806e496c31b39.png

当然,各家实现方案细节上还是有所区别的,但是问题不大,但是大部分对其编码过程只对中文进行Unicode编码保证英文与标准的摩尔斯电码进行统一。

还有就是为了让解码过程更容易,在中文摩斯密码中每个字符之间用\划分,这样通过\可以准确知道一个字符的起始位置直接进行对应转换即可,就不用担心因为字符、数字凑在一起造成的混淆处理了。

实现一个简单的中文摩斯密码

上面说了那么多,对于程序员来说,写的code才是真的,这里面针对上面的介绍,实现一个简单的摩斯密码啦。

这里面实现说明一下:

  • 标准形式无论中英文都以`\`作为字符划分

  • 中文的处理不采取标准中文电码表,这里采用转成Unicode编码的4个16进制数字

  • 不处理空格,字符间用斜杠分割(放开头),中文字符内的Unicode字符间用空格分开(本质属于一个中文字符内)

  • 要将字符转成大写(或者小写),在进行Unicode编码时候16进制有的字母也要转成统一大小写

实现的代码为:

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;//公众号:bigsai
//2021 1.3
public class MorseCode {Map<Character, String> encMap = new HashMap<Character, String>();// 摩尔斯编码表集合Map<String, Character> decMap = new HashMap<String, Character>();// 摩尔斯解码表集合public static void main(String[] args) {MorseCode morseCode=new MorseCode();String val="big赛6啊 不错 sai66";String encode=morseCode.Encryption(val);String decode=morseCode.Decryption(encode);System.out.println(encode);System.out.println(decode);}public MorseCode() {encMap.put('A', ".-");encMap.put('B', "-...");encMap.put('C', "-.-.");encMap.put('D', "-..");encMap.put('E', ".");encMap.put('F', "..-.");encMap.put('G', "--.");encMap.put('H', "....");encMap.put('I', "..");encMap.put('J', ".---");encMap.put('K', "-.-");encMap.put('L', ".-..");encMap.put('M', "--");encMap.put('N', "-.");encMap.put('O', "---");encMap.put('P', ".--.");encMap.put('Q', "--.-");encMap.put('R', ".-.");encMap.put('S', "...");encMap.put('T', "-");encMap.put('U', "..-");encMap.put('V', "...-");encMap.put('W', ".--");encMap.put('X', "-..-");encMap.put('Y', "-.--");encMap.put('Z', "--..");/* 数字电码0-9 */encMap.put('0', "-----");encMap.put('1', ".----");encMap.put('2', "..---");encMap.put('3', "...--");encMap.put('4', "....-");encMap.put('5', ".....");encMap.put('6', "-....");encMap.put('7', "--...");encMap.put('8', "---..");encMap.put('9', "----.");/* 标点符号,可自增删 */encMap.put(',', "--..--"); // ,逗号encMap.put('.', ".-.-.-"); // .句号encMap.put('?', "..--.."); // ?问号encMap.put('!', "-.-.--"); // !感叹号encMap.put('\'', ".----.");// '单引号encMap.put('\"', ".-..-.");// "引号encMap.put('=', "-...-");     // =等号encMap.put(':', "---..."); // :冒号encMap.put(';', "-.-.-."); // ;分号encMap.put('(', "-.--.");     // (前括号encMap.put(')', "-.--.-"); // )后括号encMap.put(' ', " ");        // 留空格,这里的星号是自定义的for(Character ch:encMap.keySet()){decMap.put(encMap.get(ch),ch);}}boolean isChinese(char ch){//获取此字符的UniCodeBlockCharacter.UnicodeBlock ub = Character.UnicodeBlock.of(ch);//  GENERAL_PUNCTUATION 判断中文的“号//  CJK_SYMBOLS_AND_PUNCTUATION 判断中文的。号//  HALFWIDTH_AND_FULLWIDTH_FORMS 判断中文的,号if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION         // 判断中文的。号|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS       // 判断中文的,号|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION                 // 判断中文的“号){return true;}return false;}//带中文的转成unicodeString Encryption(String str){str=str.toUpperCase();// System.out.println(str);StringBuilder sBuilder=new StringBuilder();char chs[]=str.toCharArray();for(char ch:chs){if(ch==' '){//不处理空格continue;}sBuilder.append("\\");//转义字符 字符间斜杠分开if(isChinese(ch)){String unicodeStr=Integer.toHexString(ch).toUpperCase();//转成unicoedefor(int i=0;i<unicodeStr.length();i++){sBuilder.append(encMap.get(unicodeStr.charAt(i)));if(i!=unicodeStr.length()-1)sBuilder.append(' ');//一个字符见的 摩斯密码用空格隔开}}else {sBuilder.append(encMap.get(ch));}}return  sBuilder.toString();}String Decryption(String morseCode){StringBuilder sBuilder=new StringBuilder();String morseStrs[]=morseCode.split("\\\\");//转义字符for(String morseStr:morseStrs){//一个字符 可能中if(morseStr!=null&&!"".equals(morseStr)){//去掉开头空的String strs[]=morseStr.split(" ");if(strs.length==1){//非中文直接找sBuilder.append(decMap.get(morseStr));}else {//中文先转成4位unicode然后转成中文StringBuilder unicodeStr=new StringBuilder();for(String uniChar:strs){if(uniChar!=null&&!"".equals(uniChar)){//去掉开头空的unicodeStr.append(decMap.get(uniChar));}}int chr = Integer.parseInt(unicodeStr.toString(), 16);sBuilder.append((char)chr);//(char)别忘了}}}return sBuilder.toString();}
}

测试为:

56a7dad7bd33bd5728a1eeb508e31126.png

空格不处理

结语

到此,摩尔斯电码的内容介绍就结束啦,对于摩尔斯电码,我也只是介绍一点点,实现也是简单实现一个中文的摩斯密码转换,有可能情况没考虑(有错误欢迎指正,今天写的比较匆忙),大家参考学习即可啦!

另外,在这个季节,祝愿大家在新的一年万事如意,快快乐乐!

推荐阅读:

  再见2021,2022加油!

  一次倒在LRU上的经历

  备战蓝桥杯  这样准没错!

  动态规划,它来了

欢迎卷王们一起加入力扣打卡群,坚持学习,欢迎加我好友「bigsai66」拉你进群。

e9c7f781aa52ed113774ef2ca526caf3.png

2022第一篇开头,求彦祖西施们点个点赞、再看谢谢


http://chatgpt.dhexx.cn/article/5gqBLKuS.shtml

相关文章

摩斯密码是什么?

摩斯密码是什么&#xff1f; 摩斯密码&#xff08;摩尔斯电码&#xff09;是一种时通时断的信号代码&#xff0c;通过不同的排列顺序来表达不同的英文字母、数字和标点符号&#xff1b;它的代码包括五种&#xff1a; 点、划、点和划之间的停顿、每个字符之间短的停顿、每个词之…

为什么很多人吐槽谭浩强的C语言程序设计?

这个观点在网络上已经论战了很长时间&#xff0c;出现这种情况还是历史遗留问题&#xff0c;老谭出的C语言教材几乎是国内的第一版&#xff0c;由于中英翻译问题或者对编程文化理解的差异性导致出来的书多多少少存在一些纰漏。不能只是记住其缺点&#xff0c;老谭书最主要在那个…

谭浩强老师C语言第五版第六章(上)

第3、7题难在了数学思路上&#xff08;不会或理解不了私信&#xff09; 仅代表个人看法 如有错误请指正 题目1&#xff1a;用筛选法求100 之内的素数。 代码如下&#xff1a; #include <stdio.h> #include <math.h> int main() { int i, j, n, a[101]; …

第1章 引论 - 数据结构与算法分析 c语言描述

前言&#xff1a;此类型的文章皆为本人在阅读此书后给出的关于此书的理解&#xff0c;以及知识的梳理复习。若对文章有不解之处&#xff0c;或者文章有错欢迎评论区留言。 1.1 本书讨论的内容 有一组N个数&#xff0c;要找出其中第k个最大者&#xff0c;我们称之为选择问题(se…

谭浩强老师C语言第五版第五章(上)

本文涉及字符宽度&#xff0c;暂不做讲解&#xff0c;不懂留言 仅代表个人看法 如有侵权请说明 题目1&#xff1a;请画出例 5.6 中给出的3个程序段的流程图。 程序如下1、 #include <stdio.h> int main() { int i, j, n 0; for (i 1; i < 4; i) …

谭浩强C语言程序设计(1-3章代码学习)

谭浩强C语言程序设计 参考书 C语言学习笔记记录&#xff0c;学习为主&#xff0c;新手小白入门 我所用的C语言在线编译器&#xff1a;lightly在线编译工具 可新建工程 谭浩强C语言程序设计书籍所包含的代码示例加注释说明如下&#xff1a; /*笔记记录者&#xff1a;xy;学习教…

谭浩强C语言第九章知识总结

第九章 shyu 结构体&#xff1a;用户自定义的数据类型 如&#xff1a;在描述一个学生的相关信息时&#xff0c;需要整型变量来记录学号&#xff0c;字符数组来记录名字&#xff0c;等等&#xff0c;物品们可以通过定义结构体改变变量的数据类型&#xff0c;把这些信息整成一…

谭浩强C语言第七章知识总结

第七章 定义函数 定义没有参数的函数&#xff0c; 类型名 函数名&#xff08;&#xff09; 类型名 函数名&#xff08;void&#xff09; { { 函数体 或 函数体 } …

C语言 谭浩强 题目 -第六章

文章目录 笔记字符数组字符数组输出字符串处理函数输入字符串的函数 gets&#xff08;&#xff09;字符串连接函数--strcat字符串赋值函数--strcpy字符串比较函数---strcmp测字符串长度的函数--strlen转换为大小写的函数 EG 1EG 2EG 3 排序 冒泡排序 不用函数EG 4EG 5EG 6EG 7E…

C语言 谭浩强 题目 -第八章

文章目录 笔记通过指针引用数组用数组名作函数参数以变量名和数组名作为函数参数的比较 例题【例8.2】【例8.6】【例8.3】【例 8.4】【例 8.5】【例 8.6】【例8.7】【例8.8】【例8.9】【例 8.10】选择法起泡法 【例 8.11】【例 8.12】【例 8.13】【例8.30】 用指向数组的指针作…

C语言 谭浩强 题目 -第七章

文章目录 笔记函数参数函数调用返回值函数的嵌套函数的递归数组作为函数参数多维数组名作函数参数局部变量和全局变量全局变量 变量的存储方式和生存期自动变量(auto变量)static静态局部变量寄存器变量(register变量) 全局变量在一个文件内扩展外部变量的作用域将外部变量的作用…

【C语言】谭浩强

1.分支选择结构 #include<stdio.h> int main(){ char grade; scanf(“%c”,&grade); printf(“Your score:”); switch(grade) { case’A’:printf(“85~100\n”);break; case’B’:printf(“70~84\n”);break; case’C’:printf(“60~69\n”);break; case’D’:prin…

C语言 谭浩强第五版 课后习题解答

第一章 1.什么是程序?什么是程序设计? 程序&#xff1a;就是一组能识别和执行的指令&#xff0c;每一条指令使计算机执行特定的操作 程序设计&#xff1a;是指从确定任务到得到结果、写出文档的全过程 2.为什么需要计算机语言?高级语言有哪些特点? 为什么需要计算机语言&am…

谭浩强c语言课后习题(更新中)

1.第三章 纯代公式题 #include<stdio.h>int main() {float p1.07; //第一年倍数for (int i 1; i < 10; i) //只用循环了9次&#xff0c;因为是从第一年开始{p p * 1.07;}printf("%f%%%",p*100); }第2题也是代进公式即可 其实也是代给出的公式&#xff0…

C语言学习笔记(C程序设计-谭浩强)

入门&#xff1a; 计算机程序&#xff1a; 一组计算机能够识别和执行的指令。计算机的每一个操作都是根据指令进行的&#xff0c;计算机的一切操作都是由程序控制的 计算机指令&#xff1a;指挥机器工作的指示和命令。 指令包含操作码和操作数&#xff0c;操作码决定要完成的…

清风数学建模笔记--熵权法

是一种可以客观赋权的方法&#xff08;我们可以从数据中查看权重&#xff09; 依据的原理&#xff1a;指标的变异程度越小&#xff0c;所反映的信息量也越少&#xff0c;其对应的权值也应该越低。 本文借鉴了数学建模清风老师的课件与视频&#xff0c;如果大家发现文章中有不正…

c语言计算文本信息熵,C语言求信息熵,条件熵,联合熵

C语言求信息熵,条件熵,联合熵 (3页) 本资源提供全文预览&#xff0c;点击全文预览即可全文预览,如果喜欢文档就下载吧&#xff0c;查找使用更方便哦&#xff01; 11.90 积分 #include#include#define u 20int i,j,n,m;float H_X,H_Y,H_XY,H_XpY,Pypx[u][u],Px[u],H_YpX,Py[u],…

谭浩强C语言笔记

文章目录 谭浩强C语言笔记1.C语言基础知识1.常量和变量1.1入门程序1.2 常量1.2.1 整型常量1.2.2 实型&#xff08;浮点型&#xff09;常量1.2.3 字符常量1.2.4 字符串常量1.2.5 符号常量 1.3 变量1.4 常变量 2.标识符和关键字2.1 标识符2.2 关键字2.3 小习题 3. 基本数据类型3.…

天池比赛总结1

这次参加天池的一场比赛 先把数据读取了如下 接下来准备使用YOLO框出图片中的字符&#xff0c;然后进行识别

比赛总结+近期总结

比赛总结&#xff1a; 这次比赛没考好 20(没加高精度)0&#xff08;文件输出写错&#xff09;1000120 T1&#xff1a;这一题的方法是分解质因数高精度 T2&#xff1a;明显就是一道spfa的题嘛 T3&#xff1a;强大的四维DP&#xff08;我的神啊&#xff01;&#xff09; T4&#…