论坛风格切换切换到宽版
  • 6794阅读
  • 15回复

从二进制的角度来理解Morse代码的定义 [复制链接]

上一主题 下一主题
离线BH1KZM
 
发帖
1604
只看楼主 倒序阅读 0楼 发表于: 2009-08-26
陶思良tase@163.com

原创文章,首发 www.hellocq.net

前言:

前些日子开发一个小玩意,由于体积限制,只能有一个按钮,而设置功能又比较多,无意中想到了morse code,就一只电键,千军万马都能呼来唤去,于是就萌发了用morse 按钮来控制设备的想法。在网上搜了一下,morse的解释器还真不少,下载了很多但没有我想要的,传统的方法是将.-(嘀嗒)形成01序列,然后再循环查找,但大多摆脱不了字符或字符串比较,单片机中字符串的操作是非常缓慢的,我是一个追求代码效率的人,就想简单,快捷,那些冗长的代码我看了看就放弃了!后来无意中找到了一种新的思路,就是下面我归纳的morse识别算法,(这里是归纳,不是创作)。它让我只用几百个字节就实现了morse代码的解释引擎,并且速度比传统的方法快很多,因为它没有二维查表,没有多重循环,也没有字符串或者字符的比较。最后这个小玩意非常好用,完全满足我的要求。(-.) n 开关机(防止误触发),(---)o 进入设置程序,(.)e 触发最常用的功能....

虽然很早就在hellocq.net 上注册了,但潜水多,冒泡少,更不要提贡献了,多年来就对cw通讯有所渴望,由于长期在生命线上挣扎,业余爱好只能搁置多年,近期有空重温旧梦,浸泡在www.hellocq.net 各个板块中,受益菲浅,突有灵感,想把近期对morse代码的理解写成文章,其中不免有错漏,请各位前辈批评指教。


正文:

我们把0定义成“嘀”,把 1 定义成 “嗒”
0=.
1=-

1 bit 的二进制数最大表示范围为2
0   .   e
1   -   t

2 bit 的二进制数最大表示范围为4
00   .. i
01   .- a
10   -. n
11   -- m

3 bit 的二进制数最大表示范围为8
000 ... s
001 ..- u
010 .-. r
011 .-- w
100 -.. d
101 -.- k
110 --. g
111 --- o

4 bit 的二进制数最大表示范围为16
0000 .... h
0001 ...- v
0010 ..-. f
0011 ..-- ü 拼音里面的u:,两点在u的上面
0100 .-.. l
0101 .-.- a: 两点在a的上面
0110 .--. p
0111 .--- j
1000 -... b
1001 -..- x
1010 -.-. c
1011 -.-- y
1100 --.. z
1101 --.- q
1110 ---. ó
1111 ----

5 bit 以上的情况就不详细列举了。 2^5 = 32, 2^6= 64

通常在4码以内,可能的字符有 2+4+8+16 = 30 ,这里面包含了英文的26个字母,和4个自定义字符,但1111 ---- 我没有找到,这么好记的编码没有分配字符太可惜了。

5bit 能表示32 码,6bit 能表示 64码,通常我们的数字长码都在5bit 范围内。

11111 ----- 0   x (罗马数字好像没有0,x是10)
01111 .---- 1   i
00111 ..--- 2   ii
00011 ...-- 3   iii
00001 ....- 4   iv
00000 ..... 5   v
10000 -.... 6   vi
11000 --... 7   vii
11100 ---.. 8   viii
11110 ----. 9   ix

从上述可见,数字编码比较有趣,只利用了5bit编码的很少一部分,编码规则有点象罗马数字,是以5为中心的,左右延伸。

下面一些常用的标点符号也是5bit的,
10001 -...- =
10110 -.--. (
10010 -..-. /
01010 .-.-. + 或者 end of message
01000 .-... | 或者 wait
00010 ...-. * 或者 understood
10101 -.-.- > 这个是起始信号 starting signal

还有一些5bit的编码,基本都是一些生僻的字母,在我们的键盘上一般是敲不出来的,这里就不列举了。

从上面两个5bit的编码组看,个人感觉它的分配规则基本上是视觉规则,或者说是听觉规则,人类最容易识别的编码方法,当然即使再复杂的5bit编码,通过训练也是能正确识别的。
但从代码的空间上看,5bit的编码存着严重的浪费。

6bit 基本都是标点符号和生僻字母了,编码空间64个,很大,不过这个空间内代码的利用率应该是最低的,这里就不罗唆了。

6bit以内的代码空间能表示的字符数最多是: 2+4+8+16+32+64 = 126 个 ,英文ascii码表中,一共有127个字符,也就是说,理论上morse 的编码可以处理ascii码表中的所有可打印字符,还能近似完全的处理那些不可打印的字符,对于那些怀疑morse代码的表示能力的朋友,应该能放心了吧!







morse 代码的取反和派生



在morse代码中我们能发现许多有趣的事,其中有一点就是取反(逻辑非)和派生,还有一些是“约等于”(近似),发现这些“规律”,morse 代码变得非常好记。


取反的情况:


先看看第一组:

0   .   e
1   -   t
它们简单的让我我无法用语言描述了。

接下来:
00   .. i
11   -- m

01   .- a
10   -. n

3bit 的情况
000 ... s
111 --- o   这时我才发现原来它们如此的对称,难怪 会出现一个常用的 sos,原来就是 000 111 000

001 ..- u
110 --. g

010 .-. r
101 -.- k

011 .-- w
100 -.. d

4bit 的情况
0010 ..-. f
1101 --.- q

0100 .-.. l
1011 -.-- y

0111 .--- j
1000 -... b

0110 .--. p
1001 -..- x

01010 .-.-. + 或者 end of message
10101 -.-.- > 这个是起始信号 starting signal

这里归纳的取反,有点牵强,因为实际在听的时候,它们差别很大,就像是磁带上的一首歌,即使歌词你很熟悉,倒过来放虽然你可能会觉得很好听,但基本听不懂,不过这也许是一种记忆方法。




派生的情况:


01   .- a
010 .-. r
011 .-- w

0   .   e
00   ..   i
000 ... s
0000 .... h

1   -   t
11   --   m
111 --- o

100 -.. d
1000 -... b

001 ..- u
0010 ..-. f

101 -.- k
1011 -.-- y

010 .-. r
0100 .-.. l


派生很容易举一反三,通过联想记忆法,很容易记住派生的字母,例如我记f就是这样记的,u多一点就是f。

像一些特殊的符号可以把它们记成2个字母的连发,如下所示
ar .-.-. 停止 (消息结束 end of message)
as .-... 等待wait |
sk ...-.- 终止 (联络结束)
bt -...- 分隔符
sn ...-. (我将重新发送最後一个单词)

近似的情况:

100 -.. d
110 --. g

1010 -.-. c
1011 -.-- y

0001 ...- v
0010 ..-. f

000 ... s
0000 .... h
可能近似的还有很多,尤其是快速抄报的时候,像我这样的初学者还是很糊涂的,关于近似的概念,可能每个cw的学习者对它的理解还是很个性化的,不同的人可能有不同的近似感觉。

morse代码的识别:

上述文章我们叙述了morse代码的二进制关系,下面我想和大家讨论一下morse代码的计算机处理。
既然morse代码有唯一的编码规则,那么我们是否可以将它对应的数值唯一化? 回答是肯定的。

回顾上文中提到的:

1 bit 的二进制数最大表示范围为2
0   .   e     十进制数值 0
1   -   t     十进制数值 1

2 bit 的二进制数最大表示范围为4
00   .. i     十进制数值 0
01   .- a     十进制数值 1
10   -. n     十进制数值 2
11   -- m     十进制数值 3

我们很快就看到一个问题,仅仅在1bit 和 2bit 的编码中我们就遇到了严重的重码的现象(重复50%),那么在3bit,4bit,5bit,6bit 的编码中一定还会有更多的重码。
下面我们引入一种非常简单的算法将它们对应的十进制数值唯一化。

这个算法我把它编成了一句口诀,“索引遇0加权值,最后一位加权值,权值初始总是1,遇0遇1左移1。”
这个算法并不是我设计的,我是根据varela morales 的思想将它实现的,但口诀绝对是原创,希望在这里能抛砖引玉。

下面我举几个例子来解释这个算法:

1就是这个权值的初始值,我们用mask 来表示权值,0 是索引的初始值,我们用index表示索引值。

0   .   e    
e的二进制编码是0b,索引值index初始化是0,权值mask初始化是1,当前位0b符合“索引遇0加权值”,index=index+mask =0+1=1,“遇0遇1左移1”,权值mask左移1 ,1<<1 =2 ,1 的进制代码是001b(为了区别二进制和10进制,二进制结尾用b结束),左移1位后变成010b 换成10进制就是2,索引现在是1,在这里由于0也是最后一位,符合“最后一位加权值”。index = index + mask = 1+2 = 3,计算出10进制数值3。


1   -   t     t的二进制编码是1,index初始值是0,mask初始值是1,由于当前位是1b,因此不符合“索引遇0加权值”,所以index还是0。“遇0遇1左移1”,权值mask左移1 ,1<<1 =2,在这里由于1b也是最后一位,符合“最后一位加权值”。index = index + mask = 0+2 = 2。

读者可能会说我耍赖,e 和 t 太简单,这个算法未必适合所有的morse代码,那么我们随便再举几个例子

0000 .... h ,直接看对应的10进制值也是0, 那么套用我创作口诀:这个编码有4位,我们分为5轮计算
1) index = 0, mask = 1 ,“索引遇0加权值” index = index+mask = 0+1 = 1; “遇0遇1左移1”,权值mask左移1, mask = mask <<1 = 1<<1 = 2;
2) index = 1, mask = 2 ,“索引遇0加权值” index = index+mask = 1+2 = 3; “遇0遇1左移1”,权值mask左移1, mask = mask <<1 = 2<<1 = 4;
3) index = 3, mask = 4 ,“索引遇0加权值” index = index+mask = 3+4 = 7; “遇0遇1左移1”,权值mask左移1, mask = mask <<1 = 4<<1 = 8;
4) index = 7, mask = 8 ,“索引遇0加权值” index = index+mask = 7+8 = 15; “遇0遇1左移1”,权值mask左移1, mask = mask <<1 = 8<<1 = 16;
5)“最后一位加权值” index = index + mask = 15 + 16 = 31. 最终计算出来h的索引值是31

1011 -.-- y 再来一个例子,这样更容易理解我的算法,为什么选择y,y比较复杂,并且y并不是对称的代码,更容易让读者理解计算的顺序,仍旧是5轮计算。
1) index = 0, mask = 1 ,“索引遇0加权值”,当前位1xxxb不符合(非当前位用x表示),跳过,“遇0遇1左移1”,权值mask左移1, mask = mask <<1 = 1<<1 = 2;
2) index = 0, mask = 2 ,“索引遇0加权值”,当前位x0xxb符合, index = index+mask = 0+2 = 2; “遇0遇1左移1”,权值mask左移1, mask = mask <<1 = 4<<1 = 4;
3) index = 2, mask = 4 ,“索引遇0加权值”,当前位xx1xb不符合,跳过,“遇0遇1左移1”,权值mask左移1, mask = mask <<1 = 2<<1 = 8;
4) index = 2, mask = 8 ,“索引遇0加权值”当前位xxx1b不符合,跳过,“遇0遇1左移1”,权值mask左移1, mask = mask <<1 = 8<<1 = 16;
5)“最后一位加权值” index = index + mask = 2 + 16 = 18. 最终计算出来y的索引值是18

其他的morse代码读者可以自行计算,下表是一张计算好的列表,那么在程序中只需要简单的查表即可,众所周知,一个好的hash算法能够提高搜索的速度,这里提供的就是一种morse hash算法,简单实用。


附表:

索引index   morse代码
-------------------------
0 '.' ;无效字符,占位,因为计算机编程语言中数组通常是从下标0开始
1 '.' ;占位
2 't'      ; -
3 'e'      ; .
4 'm'      ; --
5 'a'      ; .-
6 'n'      ; -.
7 'i'      ; ..
8 'o'      ; ---
9 'w'      ; .--
10 'k'      ; -.-
11 'u'      ; ..-
12 'g'      ; --.
13 'r'      ; .-.
14 'd'      ; -..
15 's'      ; ...
16 '.'      ; ----
17 'j'      ; .---
18 'y'      ; -.--
19 0xf5      ; ..-- ?
20 'q'      ; --.-
21 0xe1      ; .-.- ?
22 'x'      ; -..-
23 'v'      ; ...-
24 0xef      ; ---. ?
25 'p'      ; .--.
26 'c'      ; -.-.
27 'f'      ; ..-.
28 'z'      ; --..
29 'l'      ; .-..
30 'b'      ; -...
31 'h'      ; ....
32 Ɔ'      ; -----
33 Ƈ'      ; .----
34 '.'      ; -.---
35 ƈ'      ; ..---
36 0xee      ; --.--      ?
37 '.'      ; .-.--
38 '.'      ; -..--
39 Ɖ'      ; ...--
40 '.'      ; ---.-
41 'a'      ; .--.- ?
42 0x7e      ; -.-.- starting signal
43 '.'      ; ..-.-
44 '.'      ; --..-
45 '.'      ; .-..-
46 '='      ; -...-
47 Ɗ'      ; ....-
48 Ə'      ; ----.
49 '.'      ; .---.
50 '('      ; -.--.
51 '.'      ; ..--.
52 '.'      ; --.-.
53 '+'      ; .-.-. end of message
54 '/'      ; -..-.
55 '*'      ; ...-. understood
56 Ǝ'      ; ---..
57 '.'      ; .--..
58 '.'      ; -.-..
59 'e'      ; ..-..      ?
60 ƍ'      ; --...
61 0x7c      ; .-... wait
62 ƌ'      ; -....
63 Ƌ'      ; .....
64 '.'      ; ------
65 '.'      ; .-----
66 '.'      ; -.----
67 '.'      ; ..----
68 '.'      ; --.---
69 '.'      ; .-.---
70 '.'      ; -..---
71 '.'      ; ...---
72 '.'      ; ---.--
73 '.'      ; .--.--
74 '.'      ; -.-.--
75 '.'      ; ..-.--
76 ','      ; --..--      ','
77 '.'      : .-..--
78 '.'      ; -...--
79 '.'      ; ....--
80 '.'      ; ----.-
81 '.'      ; .---.-
82 ')'      ; -.--.-
83 '_'      ; ..--.-
84 '.'      ; --.-.-
85 '.'      ; .-.-.-      '.'
86 '.'      ; -..-.-
87 0xff      ; ...-.- end of work
88 '.'      ; ---..-
89 '.'      ; .--..-
90 '.'      ; -.-..-
91 '.'      ; ..-..-
92 '.'      ; --...-
93 '.'      ; .-...-
94 '-'      ; -....-
95 '.'      ; .....-
96 '.'      ; -----.
97 '.'      ; .----.
98 '.'      ; -.---.
99 '.'      ; ..---.
100 '.'      ; --.--.
101 '.'      ; .-.--.
102 '.'      ; -..--.
103 '.'      ; ...--.
104 '.'      ; ---.-.
105 '.'      ; .--.-.
106 ''      ; -.-.-.
107 '.'      ; ..-.-.
108 '.'      ; --..-.
109 '"'      ; .-..-.
110 '.'      ; -...-.
111 '.'      ; ....-.
112 '.'      ; ----..
113 '.'      ; .---..
114 '.'      ; -.--..
115 '?'      ; ..--..      
116 '.'      ; --.-..
117 0xf0      ; .-.-.. paragraph
118 '.'      ; -..-..
119 '.'      ; ...-..
120 ':'      ; ---...
121 '.'      ; .--...



愚文浅薄,故只增笑尔!
离线BG2BHC
发帖
5337
只看该作者 1楼 发表于: 2009-08-26
不会编程,先顶下!
发帖
689
只看该作者 2楼 发表于: 2009-08-26
厉害
虽然看不懂
帮顶
离线BG6IYQ
发帖
7037
只看该作者 3楼 发表于: 2009-08-26
厉害!虽然看不懂,但牵扯cw了就要顶!
离线BG2ATP
发帖
184
只看该作者 4楼 发表于: 2009-09-02
离线BH1KZM
发帖
1604
只看该作者 5楼 发表于: 2009-09-02
今天是我学习抄morse 代码第22天,已经可以听完26个字母和4个标点符号了。 抄报速度目前只有9wpm (保证错2个左右),但已经比我预计的快了,初学的那几天,两天才能学一个字母,计划80天学完字母再学抄短语,已经比我的计划提前了。
离线danju
发帖
415
只看该作者 6楼 发表于: 2009-09-02
'
陶思良tase@163.com

原创文章,首发 www.hellocq.net
前言:
前些日子开发一个小玩意,由于体积限制,只能有一个按钮,而设置功能又比较多,无意中想到了morse code,就一只电键,千军万马都能呼来唤去,于是就萌发了用morse 按钮来控制设备的想法。在网上搜了一下,morse的解释器还真不少,下载了很多但没有我想要的,传统的方法是将.-(嘀嗒)形成01序列,然后再循环查找,但大多摆脱不了字符或字符串比较,单片机中字符串的操作是非常缓慢的,我是一个追求代码效率的人,就想简单,快捷,那些冗长的代码我看了看就放弃了!后来无意中找到了一种新的思路,就是下面我归纳的morse识别算法,(这里是归纳,不是创作)。它让我只用几百个字节就实现了morse代码的解释引擎,并且速度比传统的方法快很多,因为它没有二维查表,没有多重循环,也没有字符串或者字符的比较。最后这个小玩意非常好用,完全满足我的要求。(-.) n 开关机(防止误触发),(---)o 进入设置程序,(.)e 触发最常用的功能....
虽然很早就在hellocq.net 上注册了,但潜水多,冒泡少,更不要提贡献了,多年来就对cw通讯有所渴望,由于长期在生命线上挣扎,业余爱好只能搁置多年,近期有空重温旧梦,浸泡在www.hellocq.net 各个板块中,受益菲浅,突有灵感,想把近期对morse代码的理解写成文章,其中不免有错漏,请各位前辈批评指教。
正文:
我们把0定义成“嘀”,把 1 定义成 “嗒”
0=.
1=-
1 bit 的二进制数最大表示范围为2
0   .   e
1   -   t
2 bit 的二进制数最大表示范围为4
00   .. i
01   .- a
10   -. n
11   -- m
3 bit 的二进制数最大表示范围为8
000 ... s
001 ..- u
010 .-. r
011 .-- w
100 -.. d
101 -.- k
110 --. g
111 --- o
4 bit 的二进制数最大表示范围为16
0000 .... h
0001 ...- v
0010 ..-. f
0011 ..-- ü 拼音里面的u:,两点在u的上面
0100 .-.. l
0101 .-.- a: 两点在a的上面
0110 .--. p
0111 .--- j
1000 -... b
1001 -..- x
1010 -.-. c
1011 -.-- y
1100 --.. z
1101 --.- q
1110 ---. ó
1111 ----
5 bit 以上的情况就不详细列举了。 2^5 = 32, 2^6= 64
通常在4码以内,可能的字符有 2+4+8+16 = 30 ,这里面包含了英文的26个字母,和4个自定义字符,但1111 ---- 我没有找到,这么好记的编码没有分配字符太可惜了。
5bit 能表示32 码,6bit 能表示 64码,通常我们的数字长码都在5bit 范围内。
11111 ----- 0   x (罗马数字好像没有0,x是10)
01111 .---- 1   i
00111 ..--- 2   ii
00011 ...-- 3   iii
00001 ....- 4   iv
00000 ..... 5   v
10000 -.... 6   vi
11000 --... 7   vii
11100 ---.. 8   viii
11110 ----. 9   ix
从上述可见,数字编码比较有趣,只利用了5bit编码的很少一部分,编码规则有点象罗马数字,是以5为中心的,左右延伸。
下面一些常用的标点符号也是5bit的,
10001 -...- =
10110 -.--. (
10010 -..-. /
01010 .-.-. + 或者 end of message
01000 .-... | 或者 wait
00010 ...-. * 或者 understood
10101 -.-.- > 这个是起始信号 starting signal
还有一些5bit的编码,基本都是一些生僻的字母,在我们的键盘上一般是敲不出来的,这里就不列举了。
从上面两个5bit的编码组看,个人感觉它的分配规则基本上是视觉规则,或者说是听觉规则,人类最容易识别的编码方法,当然即使再复杂的5bit编码,通过训练也是能正确识别的。
但从代码的空间上看,5bit的编码存着严重的浪费。
6bit 基本都是标点符号和生僻字母了,编码空间64个,很大,不过这个空间内代码的利用率应该是最低的,这里就不罗唆了。
6bit以内的代码空间能表示的字符数最多是: 2+4+8+16+32+64 = 126 个 ,英文ascii码表中,一共有127个字符,也就是说,理论上morse 的编码可以处理ascii码表中的所有可打印字符,还能近似完全的处理那些不可打印的字符,对于那些怀疑morse代码的表示能力的朋友,应该能放心了吧!
morse 代码的取反和派生
在morse代码中我们能发现许多有趣的事,其中有一点就是取反(逻辑非)和派生,还有一些是“约等于”(近似),发现这些“规律”,morse 代码变得非常好记。
取反的情况:
先看看第一组:
0   .   e
1   -   t
它们简单的让我我无法用语言描述了。
接下来:
00   .. i
11   -- m
01   .- a
10   -. n
3bit 的情况
000 ... s
111 --- o   这时我才发现原来它们如此的对称,难怪 会出现一个常用的 sos,原来就是 000 111 000
001 ..- u
110 --. g
010 .-. r
101 -.- k
011 .-- w
100 -.. d
4bit 的情况
0010 ..-. f
1101 --.- q
0100 .-.. l
1011 -.-- y
0111 .--- j
1000 -... b
0110 .--. p
1001 -..- x
01010 .-.-. + 或者 end of message
10101 -.-.- > 这个是起始信号 starting signal
这里归纳的取反,有点牵强,因为实际在听的时候,它们差别很大,就像是磁带上的一首歌,即使歌词你很熟悉,倒过来放虽然你可能会觉得很好听,但基本听不懂,不过这也许是一种记忆方法。
派生的情况:
01   .- a
010 .-. r
011 .-- w
0   .   e
00   ..   i
000 ... s
0000 .... h
1   -   t
11   --   m
111 --- o
100 -.. d
1000 -... b
001 ..- u
0010 ..-. f
101 -.- k
1011 -.-- y
010 .-. r
0100 .-.. l
派生很容易举一反三,通过联想记忆法,很容易记住派生的字母,例如我记f就是这样记的,u多一点就是f。
像一些特殊的符号可以把它们记成2个字母的连发,如下所示
ar .-.-. 停止 (消息结束 end of message)
as .-... 等待wait |
sk ...-.- 终止 (联络结束)
bt -...- 分隔符
sn ...-. (我将重新发送最後一个单词)
近似的情况:
100 -.. d
110 --. g
1010 -.-. c
1011 -.-- y
0001 ...- v
0010 ..-. f
000 ... s
0000 .... h
可能近似的还有很多,尤其是快速抄报的时候,像我这样的初学者还是很糊涂的,关于近似的概念,可能每个cw的学习者对它的理解还是很个性化的,不同的人可能有不同的近似感觉。
morse代码的识别:
上述文章我们叙述了morse代码的二进制关系,下面我想和大家讨论一下morse代码的计算机处理。
既然morse代码有唯一的编码规则,那么我们是否可以将它对应的数值唯一化? 回答是肯定的。
回顾上文中提到的:
1 bit 的二进制数最大表示范围为2
0   .   e     十进制数值 0
1   -   t     十进制数值 1
2 bit 的二进制数最大表示范围为4
00   .. i     十进制数值 0
01   .- a     十进制数值 1
10   -. n     十进制数值 2
11   -- m     十进制数值 3
我们很快就看到一个问题,仅仅在1bit 和 2bit 的编码中我们就遇到了严重的重码的现象(重复50%),那么在3bit,4bit,5bit,6bit 的编码中一定还会有更多的重码。
下面我们引入一种非常简单的算法将它们对应的十进制数值唯一化。
这个算法我把它编成了一句口诀,“索引遇0加权值,最后一位加权值,权值初始总是1,遇0遇1左移1。”
这个算法并不是我设计的,我是根据varela morales 的思想将它实现的,但口诀绝对是原创,希望在这里能抛砖引玉。
下面我举几个例子来解释这个算法:
1就是这个权值的初始值,我们用mask 来表示权值,0 是索引的初始值,我们用index表示索引值。
0   .   e    
e的二进制编码是0b,索引值index初始化是0,权值mask初始化是1,当前位0b符合“索引遇0加权值”,index=index+mask =0+1=1,“遇0遇1左移1”,权值mask左移1 ,1<<1 =2 ,1 的进制代码是001b(为了区别二进制和10进制,二进制结尾用b结束),左移1位后变成010b 换成10进制就是2,索引现在是1,在这里由于0也是最后一位,符合“最后一位加权值”。index = index + mask = 1+2 = 3,计算出10进制数值3。
1   -   t     t的二进制编码是1,index初始值是0,mask初始值是1,由于当前位是1b,因此不符合“索引遇0加权值”,所以index还是0。“遇0遇1左移1”,权值mask左移1 ,1<<1 =2,在这里由于1b也是最后一位,符合“最后一位加权值”。index = index + mask = 0+2 = 2。
读者可能会说我耍赖,e 和 t 太简单,这个算法未必适合所有的morse代码,那么我们随便再举几个例子
0000 .... h ,直接看对应的10进制值也是0, 那么套用我创作口诀:这个编码有4位,我们分为5轮计算
1) index = 0, mask = 1 ,“索引遇0加权值” index = index+mask = 0+1 = 1; “遇0遇1左移1”,权值mask左移1, mask = mask <<1 = 1<<1 = 2;
2) index = 1, mask = 2 ,“索引遇0加权值” index = index+mask = 1+2 = 3; “遇0遇1左移1”,权值mask左移1, mask = mask <<1 = 2<<1 = 4;
3) index = 3, mask = 4 ,“索引遇0加权值” index = index+mask = 3+4 = 7; “遇0遇1左移1”,权值mask左移1, mask = mask <<1 = 4<<1 = 8;
4) index = 7, mask = 8 ,“索引遇0加权值” index = index+mask = 7+8 = 15; “遇0遇1左移1”,权值mask左移1, mask = mask <<1 = 8<<1 = 16;
5)“最后一位加权值” index = index + mask = 15 + 16 = 31. 最终计算出来h的索引值是31
1011 -.-- y 再来一个例子,这样更容易理解我的算法,为什么选择y,y比较复杂,并且y并不是对称的代码,更容易让读者理解计算的顺序,仍旧是5轮计算。
1) index = 0, mask = 1 ,“索引遇0加权值”,当前位1xxxb不符合(非当前位用x表示),跳过,“遇0遇1左移1”,权值mask左移1, mask = mask <<1 = 1<<1 = 2;
2) index = 0, mask = 2 ,“索引遇0加权值”,当前位x0xxb符合, index = index+mask = 0+2 = 2; “遇0遇1左移1”,权值mask左移1, mask = mask <<1 = 4<<1 = 4;
3) index = 2, mask = 4 ,“索引遇0加权值”,当前位xx1xb不符合,跳过,“遇0遇1左移1”,权值mask左移1, mask = mask <<1 = 2<<1 = 8;
4) index = 2, mask = 8 ,“索引遇0加权值”当前位xxx1b不符合,跳过,“遇0遇1左移1”,权值mask左移1, mask = mask <<1 = 8<<1 = 16;
5)“最后一位加权值” index = index + mask = 2 + 16 = 18. 最终计算出来y的索引值是18
其他的morse代码读者可以自行计算,下表是一张计算好的列表,那么在程序中只需要简单的查表即可,众所周知,一个好的hash算法能够提高搜索的速度,这里提供的就是一种morse hash算法,简单实用。
附表:
索引index   morse代码
-------------------------
0 '.' ;无效字符,占位,因为计算机编程语言中数组通常是从下标0开始
1 '.' ;占位
2 't'      ; -
3 'e'      ; .
4 'm'      ; --
5 'a'      ; .-
6 'n'      ; -.
7 'i'      ; ..
8 'o'      ; ---
9 'w'      ; .--
10 'k'      ; -.-
11 'u'      ; ..-
12 'g'      ; --.
13 'r'      ; .-.
14 'd'      ; -..
15 's'      ; ...
16 '.'      ; ----
17 'j'      ; .---
18 'y'      ; -.--
19 0xf5      ; ..-- ?
20 'q'      ; --.-
21 0xe1      ; .-.- ?
22 'x'      ; -..-
23 'v'      ; ...-
24 0xef      ; ---. ?
25 'p'      ; .--.
26 'c'      ; -.-.
27 'f'      ; ..-.
28 'z'      ; --..
29 'l'      ; .-..
30 'b'      ; -...
31 'h'      ; ....
32 Ɔ'      ; -----
33 Ƈ'      ; .----
34 '.'      ; -.---
35 ƈ'      ; ..---
36 0xee      ; --.--      ?
37 '.'      ; .-.--
38 '.'      ; -..--
39 Ɖ'      ; ...--
40 '.'      ; ---.-
41 'a'      ; .--.- ?
42 0x7e      ; -.-.- starting signal
43 '.'      ; ..-.-
44 '.'      ; --..-
45 '.'      ; .-..-
46 '='      ; -...-
47 Ɗ'      ; ....-
48 Ə'      ; ----.
49 '.'      ; .---.
50 '('      ; -.--.
51 '.'      ; ..--.
52 '.'      ; --.-.
53 '+'      ; .-.-. end of message
54 '/'      ; -..-.
55 '*'      ; ...-. understood
56 Ǝ'      ; ---..
57 '.'      ; .--..
58 '.'      ; -.-..
59 'e'      ; ..-..      ?
60 ƍ'      ; --...
61 0x7c      ; .-... wait
62 ƌ'      ; -....
63 Ƌ'      ; .....
64 '.'      ; ------
65 '.'      ; .-----
66 '.'      ; -.----
67 '.'      ; ..----
68 '.'      ; --.---
69 '.'      ; .-.---
70 '.'      ; -..---
71 '.'      ; ...---
72 '.'      ; ---.--
73 '.'      ; .--.--
74 '.'      ; -.-.--
75 '.'      ; ..-.--
76 ','      ; --..--      ','
77 '.'      : .-..--
78 '.'      ; -...--
79 '.'      ; ....--
80 '.'      ; ----.-
81 '.'      ; .---.-
82 ')'      ; -.--.-
83 '_'      ; ..--.-
84 '.'      ; --.-.-
85 '.'      ; .-.-.-      '.'
86 '.'      ; -..-.-
87 0xff      ; ...-.- end of work
88 '.'      ; ---..-
89 '.'      ; .--..-
90 '.'      ; -.-..-
91 '.'      ; ..-..-
92 '.'      ; --...-
93 '.'      ; .-...-
94 '-'      ; -....-
95 '.'      ; .....-
96 '.'      ; -----.
97 '.'      ; .----.
98 '.'      ; -.---.
99 '.'      ; ..---.
100 '.'      ; --.--.
101 '.'      ; .-.--.
102 '.'      ; -..--.
103 '.'      ; ...--.
104 '.'      ; ---.-.
105 '.'      ; .--.-.
106 ''      ; -.-.-.
107 '.'      ; ..-.-.
108 '.'      ; --..-.
109 '"'      ; .-..-.
110 '.'      ; -...-.
111 '.'      ; ....-.
112 '.'      ; ----..
113 '.'      ; .---..
114 '.'      ; -.--..
115 '?'      ; ..--..      
116 '.'      ; --.-..
117 0xf0      ; .-.-.. paragraph
118 '.'      ; -..-..
119 '.'      ; ...-..
120 ':'      ; ---...
121 '.'      ; .--...
愚文浅薄,故只增笑尔!
'
不错的介绍,做个记号,谢谢!
离线HiXGod
发帖
1608
只看该作者 7楼 发表于: 2009-09-09
“这里提供的就是一种morse hash算法”

一句话道破天机……
离线BH1KZM
发帖
1604
只看该作者 8楼 发表于: 2009-09-10
'
“这里提供的就是一种morse hash算法”
一句话道破天机……
'

终于有人看懂了!呜呜呜~~~ 感动啊! 一万字写的还是值得的!
离线VR2UW
发帖
1571
只看该作者 9楼 发表于: 2009-09-10
离线BH1KZM
发帖
1604
只看该作者 10楼 发表于: 2009-09-14
感谢 vr2uw 老师提供的链接,我的英文不好,看起来比较费劲,但基本看懂了,原来很多人都在研究morsehash,我是闭门造车了。
离线BA4ST
发帖
5571
只看该作者 11楼 发表于: 2009-09-21
很有创意,向您学习!
离线jnwysh
发帖
225
只看该作者 12楼 发表于: 2009-10-08
经典,收藏
离线好奇,
发帖
653
只看该作者 13楼 发表于: 2010-02-04
呵呵,很耗费脑细胞,分析的不错
发帖
774
只看该作者 14楼 发表于: 2010-02-04
看到lz的贴子后,我深感惭愧,
离线BA2AB
发帖
5336
只看该作者 15楼 发表于: 2010-02-08
莫尔斯


看到了


也高兴