起因是现在做的东西需要解析二进制数据帧。本来是没有这么多麻烦事的,直接用Java或Python什么的几行代码就出来了。可是呢,事情没有这么简单,我要在前台直接解析这个帧!!我不能去数据库拿解析好的数据,也不能丢到后台解析完再拿回来,只能在前台解析,惆怅。
由于技术不够,查了好多资料,花了一天时间才搞出来。所以赶紧写记下来。
1.先看看我要干嘛
下面是我拿到的一帧数据,这一步的任务就是把这一大串数据的每一字节都解析出来!当然,下面还有说明,我就开始对着这张表干活了。。
var msg =[0xFB,0xFB,0x00,0x62,0xFF,0x02,0x3F,0x00,0x00,0x00,0x13,0x22,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x27,0x10,0x01,0xBC,0xC6,0xCB,0xE3,0xD6,0xD0,0xD0,0xC4,0x32,0x30,0x34,0xCA,0xAA,0xB6,0xC8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x0E,0x6C,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x27,0x10,0x01,0xFE];
2.第一步
上面是我为了方便阅读写成了十六进制的数组,真正的帧就是一大串00000111111,所以呢,得先把它存起来,一般的数组肯定是不行的。首先我就先发现了这个↓↓↓↓↓
[二进制数组的说明](http://javascript.ruanyifeng.com/stdlib/arraybuffer.html#toc10)
简单的说,要想一位一位的操作二进制数据,得按它的标准来。首先,要有一个**ArrayBuffer**对象,它代表内存之中的一段二进制数据,你的二进制数据有多长,就用多大的空间就可以了。在这里,先这样:
var buffer = new ArrayBuffer (str.length);
我这么理解:我需要一个这么大的空间(袋子),我要把数据放进去(我要去买面)。接下来,要确定以什么样的方式去处理这些数据。因为我这里的格式挺乱的,所以用这个:
var dv =new DataView (buffer);
其实这里用别的也行,比如:
var u8v = new Uint8Array (buffer);
可以这么理解:我现在有一袋子面,我要用它做面包(Uint8Array),也可以用来做馒头(Int16Array),或者我还没想好,反正就是做吃的(DataView)。光说是没用的,还得把数据放进去才能处理:
for (var i =0 ;i <str. length ;i ++){
dv[i]=str[i];
}
这样,就把这一段信息存好了。也就是说,面装到袋子里面了。(你也可以先存数据在确定数据视图,不过我没有尝试)
3.第二步
现在就可以进行数据处理了。首先就根据说明进行判断吧。
if(dv.getUint8(6 ) & 0 x02) {
这里,取第7个字节,按照格式uint8来处理,直接操作二进制数就可以了。(就是0x3F & 0x02即 00111111 & 00000010),就这样,很愉快的把前面的都信息都解决了。额外提一下,因为数值部分我拿到的时候已经乘以100,所以没有小数。且数值没有负数,就用uint8就可以了。
4.第三步
然后我就卡壳了。位置部分是GBK编码的汉字,关键是我查了很多资料,并没有找到我想要的方法。并且,好多解析的方法都是直接解析编码后的字符串,不是二进制。所以,我还得先把二进制给转成字符串。
function Bytes2Str (arr)
{
}
这样,我就拿到一串abcd。我知道它是GBK编码,可格式根本不对,怎么办?手动拼!
function insert_flg (str,flg,sn) {
}
这样,abcd就变成了%ab%cd。距离大功告成只有一步之遥了!关键是,这又卡壳了。js不能把GBK编码转成汉字,还不能把它转成utf8。"\u"替换"%"根本就不对,因为他本身就不一样。然后我又查了半天,看到一个大神写的帖子,惊为天人!(链接忽然找不到了,找到补上),就是说js虽然不能直接解析gbk(要不就是自己查字库。。。。),但是浏览器会解析!就像搜索的时候,关键字是汉字,地址栏后面一大串编码都是gbk的!(不信可以Google百度试一下),思路就是在页面中创建一个隐身的iframe,然后把这段gbk丢到iframe里面,浏览器就会自动解析了,这时候去做个抢劫,把解析出来的内容拿过了就OK了,完事把iframe删除了事。简直6的不行!
iframe. contentWindow. document. write('<html><scrip' + 't charset=" gbk" src=" data:text/javascript;charset=gbk,parent. _decodeStr_=\'' + str + '\'" ></s' +'cript></html>' );
setTimeout(function () {
callback(_decodeStr_);
iframe. parentNode. removeChild(iframe);
}, 300 )
这两行代码就是核心部分,最后callback拿出来保存下就可以了,bingo!