AIS解码算法

更新时间:2023-11-25 08:16:06 阅读: 评论:0

站长软文-节能宣传周

AIS解码算法
2023年11月25日发(作者:多肉习性)

前文已经提到的信息内容是经过压缩的,压缩的方法比较特殊,因

AIS

为要求压缩的结果是可见字符。本文针对压缩以及解压缩进行描述。

对于VDM消息中的压缩码,编码格式是根据以下对照表来进行的。

制定这种编码格式的目的一是为了压缩信息内容,二是要求压缩以后的

信息能够以ASCII码显示,以便使用文本方式传输(如果直接压缩,可

能会产生不可见字符,这就是一般压缩文件以二进制方式存储的原因)

ASCIIValid Binary ASCIIValid Binary

HEX = binaryCharacterField HEX = binaryCharacterField

30=00110000000000050=01010000P100000

31=00110001100000151=01010001Q100001

32=00110010200001052=01010010R100010

33=00110011300001153=01010011S100011

34=00110100400010054=01010100T100100

35=00110101500010155=01010101U100101

36=00110110600011056=01010110V100110

37=00110111700011157=01010111W100111

38=00111000800100060=01100000101000

39=00111001900100161=01100001a101001

48=01001000H01100070=01110000p111000

49=01001001I01100171=01110001q111001

4A=01001010J01101072=01110010r111010

4B=01001011K01101173=01110011s111011

4C=01001100L01110074=01110100t111100

4D=01001101M01110175=01110101u111101

4E=01001110N01111076=01110110v111110

4F=01001111O01111177=01110111w111111

目前我们只需要考虑使用以上编码格式进行

解码就可以了。以下是解码

程。

1Convert ASCII-code to 6-bit binary field(将ASCII码转换成

6位二进制值)

算法图例:

第一个判断是因为经过编码的文本字符只可能为0x300x77间的可显示字

符。

第二个判断与第三个判断是由于在编码表中,我们可以看到,0x57以后并不

0x58,而是0x60,所以在0x580x5F间的字符是无效字符。

以上三个判断是对需要解码的字符有效性的判断。

其下的流程是真正的解码流程。至于为什么用这样的流程,大家可以推敲,

目前我们只需安照该流程执行,即可将VDM消息中的压缩信息转为6比特的信息

了。

解码

算法代码:

//转换单个字符

bool EightByteToSix(BYTE inEight,BYTE &outSix)

{

//以下两个判断用于检测所输入的ASCII码是否有效

if(inEight < 0x30 || inEight > 0x77)

return fal;

if(inEight > 0x57 && inEight < 0x60)

return fal;

//检查结束

outSix = inEight + 0x28; //加上101000

if(outSix > 0x80) //如果SUM>10000000

outSix += 0x20; //加上100000

el

outSix += 0x28; //加上101000

outSix = outSix<<2; //右移两位,获取LSB

return true ;

}

//转换整个压缩信息

2. Convert ASCII-code String to 6-bit binary field Array(将ASCII

字符串转换成6位二进制值表示的字符数组)

说明:将每个ASCII码转换成6bits码后,因为数据是以字节为单位保存的,因

此需要将这些6bits码放置到字节中去。比如ASCII码串”A2L9”,转换成6bits

二进制是这样的:010001 000010 011100 001001。用字节表示就是 01000100

00100111 000010010x44,0x27,0x09这三个ASCII码。

算法代码:

//返回参数用LPBYTE而不用CString,是因为转换的中可能出现0x00。这

数据

在字符串中会作为串结束符看待,因此将无法得到串的真实长度

bool EightStrToSix(CString inEight, LPBYTE outSix)

{

BYTE len = gth();

BYTE nowBt = 0x00;//用于记录当前未用完的记录6Bits码的字节

BYTE midBt;//中间转换记录字节

BYTE outLen = 0;

for(int i=0;i处理所有ASCII

{

BYTE bt = (i);

BYTE six;

If(EightByteToSix(bt,six)==fal)//将当前ASCII码转换成

6 bits

return fal;

int res = i%4;//因为4ASCII码转换成3个字节的6bits

码,因此将是每4ASCII码的转换成为一个循环过程

switch(res)

{

//当是第一个ASCII码时,不能直接完成一个6bits码的字节转换,因为还

有两个bits没有填入的字节

数据。用nowBt暂先保存6bits码正在记录数据

ca 0:

nowBt = six;

break;

//当处理第二个ASCII码时,显然,加上第一个ASCII码的转换,26bits

码将是12bits,因此可以完成一个字节的,另外余下的4bits记录到nowBt

数据

中,等待下一个ASCII码的处理。

ca 1:

midBt = six >>6; //将最高的两位移到末尾,以便将高

二位保存到nowBt的低二位中

nowBt = nowBt | midBt;//完成6bits码的第一个字节

outSix[outLen] = nowBt;//保存到输出的字节数组中

outLen ++;

//以下两步移位是将当前6bits码的中间4位移动到高

四位中。并记录到nowBt中。

nowBt = six >>2;

nowBt = nowBt <<4;

break;

//当处理第三个ASCII码时,nowBt中的有效位是高四位,因此需要将新的

6bits码的高四位放到nowBt的低四位中,然后保存nowBt到输出数组,再将新

6bits码的第56位移到高二位后记录到nowBt

ca 2:

midBt = six >>4;//将高四位移到低四位

nowBt = nowBt | midBt;//完成6bits码的第二个字节

outSix[outLen] = nowBt;//保存到输出的字节数组

outLen ++;

//将新的6bits码的第56位移到高二位后记录到nowBt

nowBt = six >>2;

nowBt = nowBt <<6;

break;

//当处理第四个ASCII码时,nowBt中的有效位是高二位,因此

将新的6bits码的高6位移到nowBt的低6位,正好完成一个循环

ca 3:

midBt = six >>2;//将高六位移到低六位

nowBt = nowBt | midBt;//完成6bits码的第三个字节

outSix[outLen] = nowBt;//保存到输出的字节数组

outLen ++;

nowBt = 0x00;//nowBt复位

break;

}

default:

{

break;

}

}

return true;

}

信息获取代码

压缩信息解码完成后,就可以从解码信息中读取指定的内容了。

根据读取的信息的比特长度不同,读取的方法也有所变化。

3.从解码数据中获取指定类型的数据内容

31获取1bits 8bits的整数

数据

//lpInfo—调用EightStrToSix获取的

解码数据

//dwBitStart –需要获取的的起始位. dwBitStart 0开始

数据

//byLen 所占位数

数据

BYTE GetByteValFromInfo(const LPBYTE lpInfo,DWORD dwBitStart,BYTE

byLen)

{

BYTE byStartByte = dwBitStart/8;//获取起始字节序号

BYTE byStartBit = dwBitStart%8;//获取起始字节中的起始位数

BYTE byInfo = 0x00;

if(8-byStartBit < byLen)//要获取的跨两个字节

数据

{

BYTE by1 = *(lpInfo + byStartByte);//获取第一个字节

数据

BYTE by2 = *(lpInfo + byStartByte + 1);//获取第二个字节

数据

//完成两个字节中位的拼接

by1 = by1 << byStartBit;

by1 = by1 << 8 - byLen; //byLen - (8 - byStartBit)

by2 = by2 >> 16 - byLen - byStartBit; //8 - (byLen - (8 -

byStartBit))

byInfo = by1 | by2;

}

el

{

byInfo = *(lpInfo + byStartByte);

byInfo = byInfo << byStartBit;

byInfo = byInfo >> 8 - byLen;

}

return byInfo;

}

32获取9bits 16bits的整数

数据

WORD GetWordValFromInfo(const LPBYTE lpInfo,DWORD dwBitStart,WORD wLen)

{

BYTE byStartByte = dwBitStart/8;

BYTE byStartBit = dwBitStart%8;

WORD wInfo = 0x0000;

if(16 - byStartBit < wLen)//要获取的跨三个字节

数据

{

wInfo = *(WORD*)(lpInfo + byStartByte);

wInfo = wInfo << byStartBit;

wInfo = wInfo >> 16 - wLen;

BYTE by1 = *(lpInfo + byStartByte + 2);

by1 = by1 >> 24- wLen - byStartBit;

wInfo = wInfo | by1;

}

el

{

wInfo = *(WORD*)(lpInfo + byStartByte);

wInfo = ntohs(wInfo);

wInfo = wInfo << byStartBit;

wInfo = wInfo >> 16 - wLen;

}

return wInfo;

}

33获取17bits 32bits的整数数据

DWORD GetDWordValFromInfo(const LPBYTE lpInfo,DWORD dwBitStart,DWORD

dwLen)

{

BYTE byStartByte = dwBitStart/8;

BYTE byStartBit = dwBitStart%8;

DWORD dwInfo = 0x00000000;

if(dwLen <= 24)//占三个或者四个字节

{

if(24 - byStartBit < dwLen)//占四字节

{

dwInfo = *(DWORD*)(lpInfo + byStartByte);

dwInfo = ntohl(dwInfo);

dwInfo = dwInfo << byStartBit;

dwInfo = dwInfo >> 32 - dwLen;

BYTE by1 = *(lpInfo + byStartByte + 4);

by1 = by1 >> 40 - dwLen - byStartBit;

dwInfo = dwInfo | by1;

}

el//占四个字节

{

byStartBit += 6;

if(byStartBit == 8)

{

byStartBit = 0;

byStartByte ++;

}

}

//字符串解码,如果小于0x20,需要加上0x40

//具体规则参考ITU-R M-1371-1文件第4142

if(byChar < 0x20)

byChar += 0x40;

sRtnStr += byChar;

毕业生自我推荐表-苏武牧羊翻译

AIS解码算法

本文发布于:2023-11-25 08:16:06,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/zhishi/a/170087136634748.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:AIS解码算法.doc

本文 PDF 下载地址:AIS解码算法.pdf

下一篇:返回列表
标签:ais
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 实用文体写作网旗下知识大全大全栏目是一个全百科类宝库! 优秀范文|法律文书|专利查询|