看了happyparrot 的一篇关于AIS解码的文章http://blog.csdn.net/happyparrot/article/details/1585185,
发现有两个问题这里做下笔记,首先还是感激作者提供珍贵的资料,这些资料真不多见。
1、博文说“编码格式的目的一是为了压缩信息内容”是不正确的。
这个编码是将原始的每6bit映射到一个特定集合中的某个ASCII字符,
即变为8bit(解码时最高2bit是没用的),数据不是压缩,相反是膨胀。
至于为什么要做这样的编码,我想可能是便于报文数据的发送和传输。
另,AIS报文数据中定义的字符串字段,如船名、目的地等,则是将8bitASCII码映射到6bit码,
这个过程才是压缩,解码时需要根据映射表将6bit还原成8bit的ASCII字符(ITU-R M.1371)
2、 关于那个奇怪的解码算法
outSix = inEight + 0x28; //加上101000
if(outSix > 0x80) //如果SUM>10000000
outSix += 0x20; //加上100000
else
outSix += 0x28; //加上101000
outSix = outSix<<2; //右移两位,获取LSB
由于映射的字符集合是个分段的,所以if(outSix > 0x80)是个分段点,
两段:[0x30, 0x57] 和 [ 0x60,0x77],分别将端点加0x28变为:
[0x58, 0x7F] 和 [ 0x88,0x9F]
注意一下第一段的分界点0x7F,就明白为什么用0x80做分支了。
然后各个分支中为什么又做加法?
按照转换表,直观思路应该是字符与0x57比较,小于减0x30,大于则减0x38,没错这个算法就是这样算的:
只是二进制中减法可以转换为加法运算,即减一个数等于加上这个数的负数的补码,即减0x30等于加上-0x30的补码。
0x30 : 0110000
-0x30: 1110000(1bit符号位+6bit数据位)
-0x30补码:10000000-0110000 = 1010000 = 0x50 = 0x28 + 0x28
0x38 : 0111000
-0x38: 1111000
-0x38补码:10000000-0111000 = 01001000 = 0x48 = 0x28 + 0x20
这下应该看清楚了吧!
附上字符映射表(IEC 61162-1-2007)
ASCII HEX = binary | Valid Character | Binary Field represented | ASCII HEX = binary | Valid Character | Binary Field represented |
30=00110000 | 0 | 000000 | 50=01010000 | P | 100000 |
31=00110001 | 1 | 000001 | 51=01010001 | Q | 100001 |
32=00110010 | 2 | 000010 | 52=01010010 | R | 100010 |
33=00110011 | 3 | 000011 | 53=01010011 | S | 100011 |
34=00110100 | 4 | 000100 | 54=01010100 | T | 100100 |
35=00110101 | 5 | 000101 | 55=01010101 | U | 100101 |
36=00110110 | 6 | 000110 | 56=01010110 | V | 100110 |
37=00110111 | 7 | 000111 | 57=01010111 | W | 100111 |
38=00111000 | 8 | 001000 | 60=01100000 | ‘ | 101000 |
39=00111001 | 9 | 001001 | 61=01100001 | a | 101001 |
3A =00111010 | : | 001010 | 62=01100010 | b | 101010 |
3B=00111011 | ; | 001011 | 63=01100011 | c | 101011 |
3C =00111100 | < | 001100 | 64=01100100 | d | 101100 |
3D=00111101 | = | 001101 | 65=01100101 | e | 101101 |
3E=00111110 | > | 001110 | 66=01100110 | f | 101110 |
3F =00111111 | ? | 001111 | 67=01100111 | g | 101111 |
40=01000000 | @ | 010000 | 68=01101000 | h | 110000 |
41=01000001 | A | 010001 | 69=01101001 | i | 110001 |
42=01000010 | B | 010010 | 6A =01101010 | j | 110010 |
43=01000011 | C | 010011 | 6B=01101011 | k | 110011 |
44=01000100 | D | 010100 | 6C =01101100 | l | 110100 |
45=01000101 | E | 010101 | 6D=01101101 | m | 110101 |
46=01000110 | F | 010110 | 6E=01101110 | n | 110110 |
47=01000111 | G | 010111 | 6F =01101111 | o | 110111 |
48=01001000 | H | 011000 | 70=01110000 | p | 111000 |
49=01001001 | I | 011001 | 71=01110001 | q | 111001 |
4A =01001010 | J | 011010 | 72=01110010 | r | 111010 |
4B=01001011 | K | 011011 | 73=01110011 | s | 111011 |
4C =01001100 | L | 011100 | 74=01110100 | t | 111100 |
4D=01001101 | M | 011101 | 75=01110101 | u | 111101 |
4E=01001110 | N | 011110 | 76=01110110 | v | 111110 |
4F =01001111 | O | 011111 | 77=01110111 | w | 111111 |