golang -- 网络字节编解码(1)

golang -- 网络字节编解码(1),第1张

概述在网络传输协议过程中,封包常见的方式一般是: ①头标识+数据头(类型/属性/数据长度)+数据体+尾标识 -->一般还需要转义 ②固定长度 --> 编解码方便,浪费宽带 ③通过结尾标识(eg.通过base64传输,以\0结束) -->编解码方便,浪费 宽带 下面是golang在编解码的常用手段 解码 首先需要把[]byte的ascii串转化为uint8,uint16,uint32,uint64等 (

在网络传输协议过程中,封包常见的方式一般是:
①头标识+数据头(类型/属性/数据长度)+数据体+尾标识 -->一般还需要转义
②固定长度 --> 编解码方便,浪费宽带
③通过结尾标识(eg.通过base64传输,以宽带结束) -->编解码方便,浪费

//这是一个例子,解码出">HHI"funcunpack(data[]byte,edianbyte)(uint16,[]byte){dataType:=ToUInt16(data[0:2],edian)dataAttr:=ToUInt16(data[2:4],edian)dataLen:=ToUInt32(data[4:8],edian)extra:=data[8:]returndataType,dataAttr,dataLen,extra}funcToUInt8(buf[]byte,edianbyte)uint8{//len(buf)==1-->Bt:=uint8(buf[0])returnt}funcToUInt16(buf[]byte,edianbyte)uint16{//len(buf)==2-->Ht:=uint16(buf[0])ifedian==62{//">"t=t<<8|uint16(buf[1])}elseifedian==60{//"<"t=t|uint16(buf[1])<<8}returnt}funcToUInt32(buf[]byte,edianbyte)uint32{//len(buf)==4-->It:=uint32(buf[0])ifedian==62{t=t<<24t=t|uint32(buf[1])<<16t=t|uint32(buf[2])<<8t=t|uint32(buf[3])}elseifedian==60{t=t|uint32(buf[1])<<8t=t|uint32(buf[2])<<16t=t|uint32(buf[3])<<24}returnt}funcToUInt64(buf[]byte,edianbyte)uint64{//len(buf)==8-->Qt:=uint64(buf[0])ifedian==62{t=t<<56t=t|uint64(buf[1])<<48t=t|uint64(buf[2])<<40t=t|uint64(buf[3])<<32t=t|uint64(buf[4])<<24t=t|uint64(buf[5])<<16t=t|uint64(buf[6])<<8t=t|uint64(buf[7])}elseifedian==60{t=t|uint64(buf[1])<<8t=t|uint64(buf[2])<<16t=t|uint64(buf[3])<<24t=t|uint64(buf[4])<<32t=t|uint64(buf[5])<<40t=t|uint64(buf[6])<<48t=t|uint64(buf[7])<<56}returnt}


下面是golang在编解码的常用手段

解码
首先需要把[]byte的ascii串转化为uint8,uint16,uint32,uint64等 (分别对应python的B,H,I,Q).特别要注意大端和小端对齐方式(python大端">",小端"<",这里也用它们的ascii吧)

//这是一个例子,编码为">HHI"funcpack(dataTypeuint16,dataAttruint16,dataLenuint32)[]byte{buf:=make([]byte,8)PutUInt16(dataType,buf[0:2],62)PutUInt16(dataAttr,buf[2:4],62)PutUInt32(dataLen,buf[4:8],62)//buf=bufType+bufAttr+bufLenreturnbuf}funcputUInt8(numuint8,buf[]byte,edianbyte){//len(buf)==1buf[0]=byte(num)}funcputUInt16(numuint16,edianbyte){//len(buf)==2buf[0]=byte(num>>8)buf[1]=byte(num)ifedian==62{//">"}elseifedian==60{//"<"buf[0]^=buf[1]buf[1]^=buf[0]buf[0]^=buf[1]}}funcputUInt32(numuint32,edianbyte){//len(buf)==4buf[0]=byte(num>>24)buf[1]=byte(num>>16)buf[2]=byte(num>>8)buf[3]=byte(num)ifedian==62{}elseifedian==60{buf[0]^=buf[3]buf[3]^=buf[0]buf[0]^=buf[3]buf[1]^=buf[2]buf[2]^=buf[1]buf[1]^=buf[2]}}funcputUInt64(numuint64,edianbyte){//len(buf)==8ifedian==62{buf[0]=byte(num>>56)buf[1]=byte(num>>48)buf[2]=byte(num>>40)buf[3]=byte(num>>32)buf[4]=byte(num>>24)buf[5]=byte(num>>16)buf[6]=byte(num>>8)buf[7]=byte(num)}elseifedian==60{buf[0]=byte(num)buf[1]=byte(num>>8)buf[2]=byte(num>>16)buf[3]=byte(num>>24)buf[4]=byte(num>>32)buf[5]=byte(num>>40)buf[6]=byte(num>>48)buf[7]=byte(num>>56)}}

编码
解码的逆过程,把uint8,uint32转化为[]byte -->ascii slice

总结

以上是内存溢出为你收集整理的golang -- 网络字节编解码(1)全部内容,希望文章能够帮你解决golang -- 网络字节编解码(1)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1291841.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存