如何在 Go 编程中将 []byte 转换为 int
Posted
技术标签:
【中文标题】如何在 Go 编程中将 []byte 转换为 int【英文标题】:How to convert from []byte to int in Go Programming 【发布时间】:2012-06-26 09:55:21 【问题描述】:我需要通过 TCP 创建一个客户端-服务器示例。在客户端,我读取了 2 个数字并将它们发送到服务器。我面临的问题是我无法从[]byte
转换为int
,因为通信只接受[]byte
类型的数据。
有没有办法将[]byte
转换为int
或者我可以将int
发送到服务器?
一些示例代码将不胜感激。
谢谢。
【问题讨论】:
只是为了澄清任务,您是否同时编写客户端和服务器代码?并且都是用 Go 编写的? AFAIK 你必须做位移。 要将数据发送到网络,它需要以字节形式。 【参考方案1】:encoding/binary
中的binary.Read
提供了将字节数组转换为数据类型的机制。
请注意,网络字节顺序为BigEndian,因此在这种情况下,您需要指定binary.BigEndian
。
package main
import (
"bytes"
"encoding/binary"
"fmt"
)
func main()
var myInt int
b := []byte0x18, 0x2d // This could also be a stream
buf := bytes.NewReader(b)
err := binary.Read(buf, binary.BigEndian, &myInt) // Make sure you know if the data is LittleEndian or BigEndian
if err != nil
fmt.Println("binary.Read failed:", err)
return
fmt.Print(myInt)
查看此文档可能会有所帮助:https://pkg.go.dev/encoding/binary@go1.17.1#Read
【讨论】:
【参考方案2】:now := []byte0xFF,0xFF,0xFF,0xFF
nowBuffer := bytes.NewReader(now)
var nowVar uint32
binary.Read(nowBuffer,binary.BigEndian,&nowVar)
fmt.Println(nowVar)
4294967295
【讨论】:
【参考方案3】:如果 []byte 是 ASCII 字节数,则首先将 []byte 转换为字符串,然后使用 strconv
包 Atoi
将字符串转换为 int 的方法。
package main
import (
"fmt"
"strconv"
)
func main()
byteNumber := []byte("14")
byteToInt, _ := strconv.Atoi(string(byteNumber))
fmt.Println(byteToInt)
去游乐场 - https://play.golang.org/p/gEzxva8-BGP
【讨论】:
将一个 int 解析为一个字符串,然后解析为一个字节数组,然后反向看起来太长了 是的,一个字节到 int 会更便宜,但还没有找到方法。【参考方案4】:var bs []byte
value, _ := strconv.ParseInt(string(bs), 10, 64)
【讨论】:
这大概是因为没有任何解释,它返回 int64 而不是 int,所以它被投了很多票。如果您想要 int64 (我愿意),这将是一种有效的方法吗?到字符串转换似乎是一种冗余。 这个答案不符合提问者的意图。这会读取一个字节序列,将它们解释为字符,并查看这些字符是否包含数字。可以从 4 个字节返回的最大值是 '9999'。提问者在一个切片中有 4 个字节,当它们组合时,代表一个 4 字节整数,并且想知道提取其中整数的最简单方法。这可能会返回 -2^31 到 2^31-1 之间的结果。【参考方案5】:(转发this answer)
您可以使用 encoding/binary 的 ByteOrder 为 16、32、64 位类型执行此操作
Play
package main
import "fmt"
import "encoding/binary"
func main()
var mySlice = []byte244, 244, 244, 244, 244, 244, 244, 244
data := binary.BigEndian.Uint64(mySlice)
fmt.Println(data)
【讨论】:
偏移量是什么意思?例如,从 [] 字节的中间读取?只做 BigEndian.Uint64(bigSlice[10:18]) (基本上,读取切片中间的字节。还是你的意思是别的? 是的,我是在问了这个愚蠢的问题后才想到的。只是无法编辑它:D 谢谢。 它返回 uint16, uint32, unit64 但不返回 int。需要从uint转成int 有点明显,但起初只是想将 byte[] 转换为 int:这不适用于字节数组非常小的情况。对于我的一个案例,我有一个只有 2 个元素的字节数组,而Uint64
方法在源 _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
的这一行失败,因为显然索引超出了范围。我需要Uint16
方法。
@TinkalGogoi 使用 int64(value) 将值转换为 int64。【参考方案6】:
对于编码/解码数字到/从字节序列,有encoding/binary 包。文档中有示例:请参阅目录中的示例部分。
这些编码函数在io.Writer 接口上运行。 net.TCPConn 类型实现了 io.Writer,因此您可以直接写入/读取网络连接。
如果您在连接的任一端都有 Go 程序,您可能希望使用encoding/gob 查看。有关使用 gob 的演练,请参阅文章“Gobs of data”(跳到底部查看自包含示例)。
【讨论】:
你能举个例子说明如何在 TCP 应用程序中使用 gob 吗? 我添加了一个链接到一篇描述 gobs 的文章;如果您只想查看代码示例,可以跳到底部。构建编码器/解码器时,只需将*TCPConn
作为参数传递给gob.NewEncoder
/gob.NewDecoder
。【参考方案7】:
从字节数组开始,您可以使用binary package 进行转换。
例如,如果您想读取整数:
buf := bytes.NewBuffer(b) // b is []byte
myfirstint, err := binary.ReadVarint(buf)
anotherint, err := binary.ReadVarint(buf)
同一包允许使用通用Read 函数读取具有所需字节顺序的无符号整数或浮点数。
【讨论】:
Varint 专用于协议缓冲区,可能不是您想要的。规格:code.google.com/apis/protocolbuffers/docs/encoding.html 澄清一下,一个 32 位整数在经过 Varint 编码后最多可以使用 5 个字节。 这不适用于 OP 的用例。请改用binary.Read()
。见:codereview.stackexchange.com/questions/15945/…以上是关于如何在 Go 编程中将 []byte 转换为 int的主要内容,如果未能解决你的问题,请参考以下文章
如何在 C# 中将 Byte* 从 C++ 转换为 Byte[]