如何在 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 转换为字符串,然后使用 strconvAtoi 将字符串转换为 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的主要内容,如果未能解决你的问题,请参考以下文章

如何在Go中将字节数组转换为字符串[重复]

如何在 C# 中将 Byte* 从 C++ 转换为 Byte[]

在 Go 中将字符串转换为整数类型?

如何在 C 中将 wchar_t 转换为 BYTE*

如何在 C# 中将 List<byte> 转换为 byte[]?

如何在 C++ CLR 中将数组<System::Byte> 转换为 char*?