【JS入门进阶】手写uin8数组解析工具:解析二进制字节,太快太方便了!
时间:2023-04-05 23:59:10
HTML5
我是公众号线下派对游戏的作者HullQin(欢迎关注公众号,发加微信,交友),转载本文需作者HullQin授权。我独立开发了《联机桌游合集》,这是一个网页,在这里你可以轻松地和朋友一起玩网络游戏,五子棋等游戏,不收费,也没有广告。还为GameJam2022开发了《Dice Crush》,喜欢的话可以关注我HullQin哦~有空我会分享制作游戏的相关技术。背景我经常需要处理二进制数据。每次面对一堆二进制数据,都需要一个字节一个字节的转换成二进制和十六进制,以便阅读理解,排查问题。比如:有一个场景我的《我做了个《联机桌游合集: UNO+斗地主+五子棋》不需要下载,直接点击播放!打电话给你的朋友,现在就开始玩吧!不看广告,不做任务,享受“纯”游戏!》,我用websocket传输二进制数据,序列化协议我用protocolbuffer,所有变量的值都是用二进制表示,变量名也用数字表示,所以体积很小。(另一种常见的序列化协议是JSON,它是一种基于文本的序列化协议,空间利用率低,所以经常需要压缩。)使用二进制的好处:空间利用率高,节省带宽,提高速度。使用二进制的缺点:高调试难度大,开发成本高,对二进制数据要求高,通常用uin8数组表示,8个二进制位表示一个字节(十进制值为0-255,即十六进制的00到FF),我们在调试二进制数据的时候,往往看到数据如436c6f73,是16进制的,16进制每2位代表一个字节,当然有时候也用十进制打印,但是十进制和16进制都不能满足需求,有时候需要用二进制表示直观地看到每个位的值。有时我们需要将整体视为一个整数(例如整体作为uint32)并查看其值。有时候我们需要把每一位都按照ASCII转换成字符串,也许它是有语义的。分享工具网上有一些现成的二进制转换工具,但是都不好用。而且还有广告,比较慢。于是自己做了一个工具:https://tool.hullqin.cn/byte-parser.html特点如下:支持“十进制表示的uint8数组,二进制表示的uint8数组,十六进制表示的uint8数组,总体为一个数字,一个ASCII数组”并相互转换。输入任意一项,只要合法,其他项会自动生成并格式化,生成的结果可以随意编辑转换。如果有错误,会有错误提示,并保留最后的结果。如果字节太多(超过6),那么(整体值)十进制意义不大,不再计算。如果有字节不是合法的ASCII,则认为ASCII无意义,不再统计。轻量级、开源,不到200行代码,如果有定制需求,可以fork代码修改。如何开发核心html:
(uin8array)decimal:
(uin8array)binary:
(uin8array)十六进制:
(总值)十进制:
(整体值)ASCII:
提前做一个dom查询,存储它,并避免以后检查它:letbytes=[];constbytesEle={2:document.getElementById('bytes-2'),10:document.getElementById('bytes-10'),16:document.getElementById('bytes-16'),};constvalueIntEle=document.getElementById('value-int');constvalueAsciiEle=文档.getElementById('value-ascii');constmessageEle=document.getElementById('message');constpad={2:8,16:2,10:0,};手写setter,即设置字节数:constsetBytes=(value)=>{bytes=value;控制台日志(字节);Object.keys(bytesEle).forEach(radix=>{constele=bytesEle[radix];ele.value=bytes.map(i=>i.toString(radix).padStart(pad[radix],'0').padStart(8,'')).join('')});if(bytes.length>6){valueIntEle.value='';}else{valueIntEle.value=bytes.map((i,index)=>i*(256**(bytes.length-1-index))).reduce((a,b)=>a+b).toString();}if(bytes.every(i=>(i===10||i>31)&&i<127)){valueAsciiEle.value=String.fromCharCode(...bytes);}else{valueAsciiEle.value='';}};手写click触发的事件,根据输入内容生成字节,然后调用setBytes触发视图更新:constchangeBytesByUin8=(value,radix)=>{constnewBytes=value.split(/[^\da-fA-F]+/).filter(i=>i!=='').map(i=>parseInt(i.trim(),radix));if(newBytes.findIndex(i=>Number.isNaN(i)||i>=256)>=0){thrownewError('解析失败');}setBytes(newBytes);};constchangeBytesByInt=(value)=>{让num=Number(value.trim());if(Number.isNaN(num)){thrownewError('解析失败');}常量结果=[];while(num>0){result.splice(0,0,num%256);num=Math.floor(num/256);}setBytes(result);};constchangeBytesByAscii=(value)=>{constresult=Array.from(value).map(i=>i.charCodeAt(0));if(result.findIndex(i=>i>256)>=0){thrownewError('解析失败');}setBytes(结果);};将事件绑定到dom:constonUint8ValueChange=(radix)=>(event)=>{try{messageEle.innerText='';changeBytesByUin8(event.target.value.trim(),radix);}catch(e){messageEle.innerText=e.message;}}Object.keys(bytesEle).forEach(radix=>{bytesEle[radix].addEventListener('change',onUint8ValueChange(radix));});地址&源码体验地址:https://tool.hullqin.cn/byte-parser.html源码:https://github.com/HullQin/tool-hullqin-cn最后我是HullQin,公众号线下派对游戏作者(欢迎关注公众号,发送加微信,交友)。转发本文前必须获得作者HullQin的授权。我独立开发了《联机桌游合集》。等待游戏,不收费,无广告。还为GameJam2022开发了《Dice Crush》,喜欢的话可以关注我HullQin哦~有空我会分享制作游戏的相关技术。