Golang中如何将Uint64转换为切片[]Uint8
Golang中如何将Uint64转换为切片[]Uint8 我正在使用 satori/uuid 包来获取 UUID 值 但在我这种情况下,获取新 UUID 后需要将其转换为简单的整数类型 我找到了一些解决方案,但不明白在处理完整数值后如何将其重新转换为 UUID 格式 如何高效简单地实现这一点? 谢谢!
例如 https://play.golang.org/p/A139r2NvfN7
newValue, _ := uuid.NewV4()
log.Println(newValue)
log.Printf("%T", newValue)
//convert to slice []uint8
b, _ := newValue.MarshalBinary()
log.Printf("%T, %v", b, b)
//convert to uint64
data := binary.BigEndian.Uint64(b)
log.Printf("%T, %v", data, data)
结果:
ee397b32-8ea1-46fd-99dc-a3c0c1267b87
uuid.UUID
[]uint8, [238 57 123 50 142 161 70 253 153 220 163 192 193 38 123 135]
uint64, 17165886911770871549
但是如何将 uint64 -> []uint8 -> uuid 转换? 最佳方案是在 uuid -> int 和 int -> uuid 之间转换 不使用 uint 格式 - 但我不明白如何实现 使用 runes 还是其他方法? 谢谢!
更多关于Golang中如何将Uint64转换为切片[]Uint8的实战教程也可以访问 https://www.itying.com/category-94-b0.html
NobbZ:
通常应避免在JSON中使用数字(特别是在需要精确值的情况下),因为JSON不区分浮点数和整数,它只认识"数字"类型。如果给定的整数字面量无法在读取器的整数类型中表示,则允许读取器将其静默强制转换为浮点数。理论上,读取器甚至不需要尝试将其转换为整型,它从一开始就可以将1读取为1.0。
谢谢! 是的,我了解UUID的String()方法
更多关于Golang中如何将Uint64转换为切片[]Uint8的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
func main() {
fmt.Println("hello world")
}
你好 - 感谢描述
当我创建每个对象时(小型生成器 - 但可能是数千个对象(并且需要并发工作)) 我需要为每个对象提供唯一的ID 然后我想将新对象转换为json格式(使用需要ID int的google/jsonapi包) 以便通过http发送到下一步 我认为使用uuid是最独特的解决方案 可能我错了 也许我可以使用反射或其他方法 通过循环从uuid.String()转换字符到int … 我想
无法直接将 UUID 转换为简单的整数类型。UUID 是 128 位的,而 Go 中最大的整数类型只有 64 位。这意味着要将 UUID 存储为整数,您需要两个整数值。
您也不能将 uint64 转换为 UUID,因为 UUID 是 128 位的,需要两个 uint64 才能正确表示它。所以如果从 uint64 转换为 UUID,意味着您大大降低了 ID 的唯一性,因为只设置了 128 位中的 64 位。
为什么需要将其转换为简单的整数类型?您打算将这些数据用于什么目的?
至少给您一个代码片段,以下是我将 uint64 转换为 []byte 的方法:
我应该补充一点,还有 math/big 包,它包含 big.Int 类型。您可以使用它来表示大于 64 位的整数,尽管我不认为这是一个简单的整数。
@YongGopher 如果你想要一个能容纳在64位整数内的唯一标识符,就不能使用UUID。问题在于UUID的尺寸太大,无论进行何种处理都无法放入整数中。这就像试图将两升水装入一升容量的瓶子,物理上是不可能的。
如果你需要唯一ID,可以尝试生成随机的uint64数值并使用它们。这样最多能提供18,446,744,073,709,551,615个唯一值。而128位随机值拥有约340,282,366,920,938,463,463,374,607,431,768,211,455个可能值。发生冲突的概率会显著降低。
另一个需要考虑的因素是你使用的JSON系统是否支持64位数值。例如JavaScript的整数精度只能达到53位。因此需要注意对接的语言是否支持你所需的大整数。
如果要在JSON中包含UUID,最安全的方式是直接使用其字符串表示形式。
您使用的UUID包正确实现了Stringer接口,因此可以轻松地将其放入JSON中:
func (u UUID) String() string {
buf := make([]byte, 36)
hex.Encode(buf[0:8], u[0:4])
buf[8] = '-'
hex.Encode(buf[9:13], u[4:6])
buf[13] = '-'
hex.Encode(buf[14:18], u[6:8])
buf[18] = '-'
hex.Encode(buf[19:23], u[8:10])
buf[23] = '-'
hex.Encode(buf[24:], u[10:])
return string(buf)
}
一般来说,您应该避免在JSON中使用数字(至少在需要精确值的情况下),因为JSON不区分浮点数和整数,它只知道"数字"。如果给定的整数字面量无法在读取器的整数类型中表示,允许读取器静默强制转换为浮点数。理论上,读取器甚至不需要尝试将其放入int类型中。它被允许从一开始就将1读取为1.0。
在Golang中,将uint64转换回UUID格式需要理解UUID的结构。UUID是128位值,而uint64只有64位,所以直接转换会丢失数据。以下是完整的转换方案:
package main
import (
"encoding/binary"
"fmt"
"log"
"github.com/satori/go.uuid"
)
func main() {
// 原始UUID
originalUUID, _ := uuid.NewV4()
log.Printf("原始UUID: %s", originalUUID)
// UUID -> []byte
uuidBytes, _ := originalUUID.MarshalBinary()
log.Printf("UUID字节切片: %v", uuidBytes)
// 从字节切片提取uint64(取前8字节)
uuidToUint64 := binary.BigEndian.Uint64(uuidBytes[:8])
log.Printf("转换后的uint64: %d", uuidToUint64)
// uint64 -> UUID 转换
reconstructedUUID := uint64ToUUID(uuidToUint64)
log.Printf("重建的UUID: %s", reconstructedUUID)
}
func uint64ToUUID(value uint64) uuid.UUID {
// 创建16字节的切片来存储UUID
uuidBytes := make([]byte, 16)
// 将uint64写入前8字节
binary.BigEndian.PutUint64(uuidBytes[:8], value)
// 后8字节可以填充默认值或随机值
// 这里简单填充零值
for i := 8; i < 16; i++ {
uuidBytes[i] = 0
}
return uuid.UUID(uuidBytes)
}
如果你需要保留完整的128位UUID信息,应该使用两个uint64:
func uuidToUint64s(u uuid.UUID) (uint64, uint64) {
bytes, _ := u.MarshalBinary()
return binary.BigEndian.Uint64(bytes[:8]), binary.BigEndian.Uint64(bytes[8:])
}
func uint64sToUUID(high, low uint64) uuid.UUID {
uuidBytes := make([]byte, 16)
binary.BigEndian.PutUint64(uuidBytes[:8], high)
binary.BigEndian.PutUint64(uuidBytes[8:], low)
return uuid.UUID(uuidBytes)
}
// 使用示例:
func main() {
originalUUID, _ := uuid.NewV4()
fmt.Printf("原始UUID: %s\n", originalUUID)
// 转换为两个uint64
high, low := uuidToUint64s(originalUUID)
fmt.Printf("高位uint64: %d, 低位uint64: %d\n", high, low)
// 转换回UUID
reconstructed := uint64sToUUID(high, low)
fmt.Printf("重建的UUID: %s\n", reconstructed)
}
如果你只需要简单的整数表示而不关心UUID格式的完整性,可以直接使用第一个方法。但要注意这会丢失UUID的后64位信息。

