# AIS解码算法

3 篇文章 2 订阅

 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

1．Convert ASCII-code to 6-bit binary field（将ASCII码转换成6位二进制值）

//转换单个字符
bool EightByteToSix(BYTE inEight,BYTE &outSix)
{
//以下两个判断用于检测所输入的ASCII码是否有效
if(inEight < 0x30 || inEight > 0x77)
return false;
if(inEight > 0x57 && inEight < 0x60)
return false;
//检查结束
outSix = inEight + 0x28;    //加上101000
if(outSix > 0x80)          //如果SUM>10000000
outSix += 0x20;       //加上100000
else
outSix += 0x28;       //加上101000
outSix = outSix<<2;       //右移两位，获取LSB
return true ;
}
//转换整个压缩信息
2. Convert ASCII-code String to 6-bit binary field Array （将ASCII 码字符串转换成6 位二进制值表示的字符数组）

//返回参数用LPBYTE而不用CString，是因为转换的数据中可能出现0x00。这在字符串中会作为串结束符看待，因此将无法得到串的真实长度
bool EightStrToSix(CString inEight, LPBYTE outSix)
{
BYTE len = inEight.GetLength();
BYTE nowBt = 0x00;//用于记录当前未用完的记录6Bits码的字节
BYTE midBt;//中间转换记录字节
BYTE outLen = 0;
for(int i=0;i<len;i++)//处理所有ASCII码
{
BYTE bt = inEight.GetAt(i);
BYTE six;
If(EightByteToSix(bt,six)==false)//将当前ASCII码转换成6 bits码
return false;
int res = i%4;//因为4个ASCII码转换成3个字节的6bits码，因此将是每4个ASCII码的转换成为一个循环过程
switch(res)
{
//当是第一个ASCII码时，不能直接完成一个6bits码的字节转换，因为还有两个bits没有填入数据。用nowBt暂先保存6bits码正在记录数据的字节
case 0:
nowBt = six;
break;
//当处理第二个ASCII码时，显然，加上第一个ASCII码的转换，2个6bits码将是12bits，因此可以完成一个字节的数据，另外余下的4bits记录到nowBt中，等待下一个ASCII码的处理。
case 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码的第5，6位移到高二位后记录到nowBt中
case 2:
midBt = six >>4;//将高四位移到低四位
nowBt = nowBt | midBt;//完成6bits码的第二个字节
outSix[outLen] = nowBt;//保存到输出的字节数组
outLen ++;
//将新的6bits码的第5，6位移到高二位后记录到nowBt中
nowBt = six >>2;
nowBt = nowBt <<6;
break;
//当处理第四个ASCII码时，nowBt中的有效位是高二位，因此将新的6bits码的高6位移到nowBt的低6位，正好完成一个循环
case 3:
midBt = six >>2;//将高六位移到低六位
nowBt = nowBt | midBt;//完成6bits码的第三个字节
outSix[outLen] = nowBt;//保存到输出的字节数组
outLen ++;
nowBt = 0x00;//nowBt复位
break;
}
default:
{
break;
}
}
return true;
}

3. 从解码数据中获取指定类型的数据内容
3．1获取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;
}
else
{
byInfo = *(lpInfo + byStartByte);
byInfo = byInfo << byStartBit;
byInfo = byInfo >> 8 - byLen;
}
return byInfo;
}
3．2获取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;
}
else
{
wInfo = *(WORD*)(lpInfo + byStartByte);
wInfo = ntohs(wInfo);
wInfo = wInfo << byStartBit;
wInfo = wInfo >> 16 - wLen;
}
return wInfo;
}

3．3获取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;
}
else //占三字节
{
DWORD dwInfo = 0x00FFFFFF;
dwInfo = dwInfo & *(DWORD*)(lpInfo + byStartByte - 1);
dwInfo = ntohl(dwInfo);
dwInfo = dwInfo << byStartBit;
dwInfo = dwInfo >> 24 - dwLen;
}
}
else//占四个或者五个字节
{
if( (32 - 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;
}
else//占四个字节
{
dwInfo = *(DWORD*)(lpInfo + byStartByte);
dwInfo = ntohl(dwInfo);
dwInfo = dwInfo << byStartBit;
dwInfo = dwInfo >> 32 - dwLen;
}
}
return dwInfo;
}

3．4获取字符串类型数据
CString GetStringValFromInfo(const LPBYTE lpInfo, DWORD dwBitStart, DWORD dwLen)
{
WORD wChars = dwLen/6;
BYTE byStartByte = dwBitStart/8;
BYTE byStartBit = dwBitStart%8;
CString sRtnStr;

for(WORD wChar = 0; wChar < wChars; wChar++)
{
BYTE byChar = *(lpInfo + byStartByte);
byChar = byChar << byStartBit;
byChar = byChar >> 2;
if(byStartBit > 2)//表示该BYTE数据跨字节了
{
BYTE by1 = *(lpInfo + byStartByte + 1);
by1 = by1 >> 16 - 6 - byStartBit;
byChar = byChar | by1;
byStartByte ++;
byStartBit = byStartBit - 2;
}
else
{
byStartBit += 6;
if(byStartBit == 8)
{
byStartBit = 0;
byStartByte ++;
}
}
//字符串解码，如果小于0x20，需要加上0x40
//具体规则参考ITU-R M-1371-1文件第41，42页
if(byChar < 0x20)
byChar += 0x40;
sRtnStr += byChar;
}
return sRtnStr;
}

• 7
点赞
• 79
收藏
觉得还不错? 一键收藏
• 打赏
• 18
评论
06-02
02-28
07-27
10-24
12-27 895
05-08
10-20 890
09-30 833
10-26 516
05-24 906
02-27
02-26
10-16
08-10 2517

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

¥2 ¥4 ¥6 ¥10 ¥20

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、C币套餐、付费专栏及课程。