golang 仿python pack/unpack
写得不完善也不完美 尤其是高低位转换那(go和c 二进制高地位相反 需要转换,还有go int转[]byte长度是4位),希望牛人看后指导一下
项目需要通过socket调取 客户端是go ,服务器端是python,由于需要封包解包,就参照python写的
python 的pack/unpack 参考 Python使用struct处理二进制(pack和unpack用法)
package includes import (
"bytes"
"encoding/binary"
"fmt"
_ "os"
"strconv"
"strings"
) type Protocol struct {
Format []string
} //封包
func (p *Protocol) Pack(args ...interface{}) []byte {
la := len(args)
ls := len(p.Format)
ret := []byte{}
if ls > && la > && ls == la {
for i := ; i < ls; i++ {
if p.Format[i] == "H" {
ret = append(ret, IntToBytes2(args[i].(int))...)
} else if p.Format[i] == "I" {
ret = append(ret, IntToBytes4(args[i].(int))...)
} else if strings.Contains(p.Format[i], "s") {
num, _ := strconv.Atoi(strings.TrimRight(p.Format[i], "s"))
ret = append(ret, []byte(fmt.Sprintf("%s%s", args[i].(string), strings.Repeat("\x00", num-len(args[i].(string)))))...)
}
}
}
return ret
} //解包
func (p *Protocol) UnPack(msg []byte) []interface{} {
la := len(p.Format)
ret := make([]interface{}, la)
if la > {
for i := ; i < la; i++ {
if p.Format[i] == "H" {
ret[i] = Bytes4ToInt(msg[:])
msg = msg[:len(msg)]
} else if p.Format[i] == "I" {
ret[i] = Bytes4ToInt(msg[:])
msg = msg[:len(msg)]
} else if strings.Contains(p.Format[i], "s") {
num, _ := strconv.Atoi(strings.TrimRight(p.Format[i], "s"))
ret[i] = string(msg[:num])
msg = msg[num:len(msg)] }
}
}
return ret
} func (p *Protocol) Size() int {
size :=
ls := len(p.Format)
if ls > {
for i := ; i < ls; i++ {
if p.Format[i] == "H" {
size = size +
} else if p.Format[i] == "I" {
size = size +
} else if strings.Contains(p.Format[i], "s") {
num, _ := strconv.Atoi(strings.TrimRight(p.Format[i], "s"))
size = size + num
}
}
}
return size
} //整形转换成字节
func IntToBytes(n int) []byte {
m := int32(n)
bytesBuffer := bytes.NewBuffer([]byte{})
binary.Write(bytesBuffer, binary.BigEndian, m) gbyte := bytesBuffer.Bytes() return gbyte
} //整形转换成字节4位
func IntToBytes4(n int) []byte {
m := int32(n)
bytesBuffer := bytes.NewBuffer([]byte{})
binary.Write(bytesBuffer, binary.BigEndian, m) gbyte := bytesBuffer.Bytes()
//c++ 高低位转换
k :=
x := len(gbyte)
nb := make([]byte, k)
for i := ; i < k; i++ {
nb[i] = gbyte[x-i-]
}
return nb
} //整形转换成字节2位
func IntToBytes2(n int) []byte {
m := int32(n)
bytesBuffer := bytes.NewBuffer([]byte{})
binary.Write(bytesBuffer, binary.BigEndian, m) gbyte := bytesBuffer.Bytes()
//c++ 高低位转换
k :=
x := len(gbyte)
nb := make([]byte, k)
for i := ; i < k; i++ {
nb[i] = gbyte[x-i-]
}
return nb
} //字节转换成整形
func BytesToInt(b []byte) int {
bytesBuffer := bytes.NewBuffer(b) var x int32
binary.Read(bytesBuffer, binary.BigEndian, &x) return int(x)
} //4个字节转换成整形
func Bytes4ToInt(b []byte) int {
xx := make([]byte, )
if len(b) == {
xx = []byte{b[], b[], , }
} else {
xx = b
} m := len(xx)
nb := make([]byte, )
for i := ; i < ; i++ {
nb[i] = xx[m-i-]
}
bytesBuffer := bytes.NewBuffer(nb) var x int32
binary.Read(bytesBuffer, binary.BigEndian, &x) return int(x)
}
调用
p := new(Protocol)
p.Format = []string{"H", "H", "I", "16s", "I", "I", "I"}
h_byte := p.Pack(, , , "abc", , , len(request_buf))
conn.Write(h_byte)
附加:
int 转 二进制 fmt.Printf("%08b\n", ) //
二进制转int i, _ := strconv.ParseInt("", , ) //
int 转 []byte IntToBytes() // [0 0 3 232] 3*256+232=1000
func IntToBytes(n int) []byte {
m := int32(n)
bytesBuffer := bytes.NewBuffer([]byte{})
binary.Write(bytesBuffer, binary.BigEndian, m)
gbyte := bytesBuffer.Bytes()
return gbyte
}
[]byte 转int BytesToInt([]byte{,,,}) //
func BytesToInt(b []byte) int {
bytesBuffer := bytes.NewBuffer(b)
var x int32
binary.Read(bytesBuffer, binary.BigEndian, &x)
return int(x)
}
int 转 byte byte() //
golang 仿python pack/unpack的更多相关文章
- python struct中的pack unpack
python struct中的pack unpack pytyon tuple元组 print struct.unpack("!ihb", buffer) 结果为7 //pyth ...
- PHP: 深入pack/unpack
https://my.oschina.net/goal/blog/195749 PHP作为一门为web而生的服务器端开发语言,被越来越多的公司所采用.其中不乏大公司,如腾迅.盛大.淘米.新浪等.在对性 ...
- PHP: 深入pack/unpack 字节序
http://my.oschina.net/goal/blog/195749?p=1 目录[-] 写在前面的话 什么是字节序 MSB和LSB 大端序 小端序 网络字节序 主机字节序 总结 pack/u ...
- [转]PHP: 深入pack/unpack
From : http://my.oschina.net/goal/blog/195749 http://www.w3school.com.cn/php/func_misc_pack.asp PHP作 ...
- PHP: 深入pack/unpack <转> [链接]
PHP: 深入pack/unpack PHP: chr和pack.unpack那些 PHP: pack/unpack补遗
- 2017年的golang、python、php、c++、c、java、Nodejs性能对比(golang python php c++ java Nodejs Performance)
2017年的golang.python.php.c++.c.java.Nodejs性能对比 本人在PHP/C++/Go/Py时,突发奇想,想把最近主流的编程语言性能作个简单的比较, 至于怎么比,还是不 ...
- 2017年的golang、python、php、c++、c、java、Nodejs性能对比[续]
2017年的golang.python.php.c++.c.java.Nodejs性能对比[续] 最近忙,这个话题放了几天,今天来个续集. 上篇传送门: 2017年的golang.python.p ...
- golang与python多线程的并发速度
一.golang的代码 package main import ( "fmt" "time" ) func Text_goroute(a int, b int) ...
- 想涨工资吗?那就学习Scala,Golang或Python吧
[编者按]据薪水调查机构 PayScale 提供的数据显示,掌握 Scala,Golang 和 Python 语言以及诸如 Apache Spark 之类的大数据技术,能带来最大的薪水提升.本文作者为 ...
随机推荐
- Android HttpClient自己主动登陆discuz论坛!
你登陆论坛的时候,我们先看看浏览器干了什么事儿: 用Firefox打开HiPda 的登陆页面,输入用户名和password,点登陆. 以下是通过firebug插件获取的数据: 能够看到浏览器这个htt ...
- BZOJ1002:[FJOI2007]轮状病毒(找规律,递推)
Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子 和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下 ...
- .Net Core SignalR 初体验
前言 Asp.Net SignalR已经出来很久了,但是一直没有静下心来好好看看.昨天花了几个小时的时间看了下.首先借鉴了官方文档,如何搭建一个SignalR的Demo. 参考文章:https://d ...
- Nginx 作为静态资源服务器
Nginx Windows 版本的启动停止,重新加载配置 启动 Windows版本下载解压后有一个nginx.exe可执行文件,双击启动. 启动后 浏览器访问http://127.0.0.1 可以看到 ...
- Css3 实现关键帧动画
<div class="person"> </div> <script> var str1 = "@keyframes move{&q ...
- 【题解】洛谷P1514 [NOIP2010TG] 引水入城(DFS+DP)
次元传送门:洛谷P1514 思路 可以证明如果有解 那么每个蓄水池可以覆盖到的干旱区必定是线段 证明: 举个栗子 8 9 8 7 9 7 6 9 6 明显到不了中间的点 如果不是连续的线段 中间肯定有 ...
- 第21章 DMA—直接存储区访问
本章参考资料:<STM32F76xxx参考手册>DMA控制器章节. 学习本章时,配合<STM32F76xxx参考手册>DMA控制器章节一起阅读,效果会更佳,特别是涉及到寄存器说 ...
- HTML&CSS笔记001
lesson1 <!DOCTYPE html><html lang="en,zh"><!-- 告诉搜索引擎爬虫,我们的网站是关于什么内容的 --> ...
- sudo命令: 在其他用户下操作root用户权限
一. 场景: 在某个远程服务器 A 上,用 账户1 登陆, 想要在root用户的目录下创建一个 .sh文件, 如果直接 用 touch test.sh 创建,会提示权限不足 此时可以用sudo命令: ...
- iOS之改变UIAlertViewController字体的颜色
NSString *message = @"请确认信息是否正确?"; NSString *title = @"提示"; UIAlertController *a ...