Go语言如何实现[32]byte与uint64互转并完整恢复原32字节数组
Go语言32字节数组与uint64转换问题解答
核心问题说明
- uint64是8字节无符号整数,最多只能存储8字节的信息,32字节数组的信息量远大于单个uint64的存储上限,因此不可能通过单个uint64完整还原32字节的原始内容,这是数据类型的固有属性,和binary包无关。
- 你使用的
binary.BigEndian.Uint64()、binary.BigEndian.PutUint64()方法本身就是专门处理uint64和8字节切片的转换:- 读取时仅会读取输入切片的前8字节转换为uint64,剩余24字节直接忽略
- 写入时仅会修改目标切片的前8字节,你看到的后24字节为0是初始化时的默认值,该方法并没有修改这部分内容
- 另外注意你代码里的拼写错误:是
BigEndian不是BigEdian,错误拼写会导致编译失败
可行方案
根据你的实际需求可以选择以下两种方案:
方案1:拆分32字节为多个uint64实现完整互转
如果需要完整保留32字节的所有信息,可以将32字节拆分为4个uint64分别存储,还原时再拼接回32字节数组,示例代码如下:
package main import ( "encoding/binary" "fmt" ) func main() { My32ByteArray := []byte{202, 79, 31, 160, 8, 87, 74, 158, 67, 245, 189, 58, 2, 168, 77, 65, 5, 53, 99, 81, 216, 156, 41, 36, 248, 179, 206, 111, 178, 71, 225, 77} // 拆分为4个uint64 var uintList [4]uint64 for i := 0; i < 4; i++ { uintList[i] = binary.BigEndian.Uint64(My32ByteArray[i*8 : (i+1)*8]) } // 还原为32字节数组 Restored32ByteArray := make([]byte, 32) for i := 0; i < 4; i++ { binary.BigEndian.PutUint64(Restored32ByteArray[i*8:(i+1)*8], uintList[i]) } fmt.Println(Restored32ByteArray) // 输出和原始数组完全一致 }
方案2:哈希映射为单个uint64(单向)
如果只需要将32字节映射为唯一的uint64标识,不需要还原原始数据,可以用哈希算法实现:
package main import ( "hash/fnv" "fmt" ) func main() { My32ByteArray := []byte{202, 79, 31, 160, 8, 87, 74, 158, 67, 245, 189, 58, 2, 168, 77, 65, 5, 53, 99, 81, 216, 156, 41, 36, 248, 179, 206, 111, 178, 71, 225, 77} h := fnv.New64a() h.Write(My32ByteArray) theUint64 := h.Sum64() fmt.Println(theUint64) }
常见疑问解答
- Q:binary包仅支持8字节数组的转换吗?
A:不是,binary包可以处理任意固定大小的Go类型和字节流的转换,但是对应到uint64类型的转换方法,本身就只处理8字节长度。如果要转换自定义的多字段结构体、固定长度数组等,也可以用binary.Read和binary.Write方法完成。
内容的提问来源于stack exchange,提问作者Jeff
相关产品推荐
相关产品推荐

