gpt4 book ai didi

go - 在go中将int32转换为字节数组

转载 作者:IT老高 更新时间:2023-10-28 13:10:58 24 4
gpt4 key购买 nike

我正在使用 big.NewInt(int64(e)).Bytes() 将 int32 转换为字节数组。有没有更优雅的方法来做到这一点?

我希望 AQAB 是 e 的 base64 编码值

http://play.golang.org/p/M46X7OpZpu

const e = 65537

func base64Encode(b []byte) string {
return strings.TrimRight(base64.StdEncoding.EncodeToString(b), "=")
}

func main() {
fmt.Printf("exp %d\n", e)

b := make([]byte, 4)
binary.BigEndian.PutUint32(b, e)
fmt.Printf("b: BigEndian.PutUint32 %x (Bad) %s\n", b, base64Encode(b))

b2 := make([]byte, 4)
binary.BigEndian.PutUint32(b2, e)
for i := range b2 {
if b2[i] != 0 {
b2 = b2[i:]
break
}
}
fmt.Printf("b2: BigEndian.PutUint32 %x (Good) %s\n", b2, base64Encode(b2))

b4 := big.NewInt(int64(e)).Bytes()
fmt.Printf("b4: big.NewInt(int64(e)).Bytes() %x (Good) %s\n", b4, base64Encode(b4))
}

输出:

exp 65537
b: BigEndian.PutUint32 00010001 (Bad) AAEAAQ
b2: BigEndian.PutUint32 010001 (Good) AQAB
b4: big.NewInt(int64(e)).Bytes() 010001 (Good) AQAB

exp 1
b: BigEndian.PutUint32 00000001 (Bad) AAAAAQ
b2: BigEndian.PutUint32 01 (Good) AQ
b4: big.NewInt(int64(e)).Bytes() 01 (Good) AQ

exp 1000000
b: BigEndian.PutUint32 000f4240 (Bad) AA9CQA
b2: BigEndian.PutUint32 0f4240 (Good) D0JA
b4: big.NewInt(int64(e)).Bytes() 0f4240 (Good) D0JA

编辑:

我已经对 b2 和 b4 进行了基准测试:

b2  1000000000          68.1 ns/op         8 B/op          1 allocs/op
b4 200000000 248 ns/op 90 B/op 3 allocs/op

我现在将使用 b2...

最佳答案

对于这类任务,我认为您的首选应该始终是使用 encoding/binary并且,如果这还不够,则按位数学。但是,在某些情况下,复制数据的开销太大或这些安全解决方案太慢:

虽然我不认为它很优雅,但你可以使用 Go 的 unsafereflect * 包可以非常快速地做到这一点。请记住,这不会复制数据;相反,它只是为您提供了另一种“观点”。并且非常不安全意味着您需要非常小心(您好单元测试和代码审查)并记住您正在破坏 Go 的 memory safety .但是,当执行速度是主要关注点并且您的团队同意时 unsafe有保证,unsafe很少能被打败。

const BYTES_IN_INT32 = 4

func UnsafeCaseInt32ToBytes(val int32) []byte {
hdr := reflect.SliceHeader{Data: uintptr(unsafe.Pointer(&val)), Len: BYTES_IN_INT32, Cap: BYTES_IN_INT32}
return *(*[]byte)(unsafe.Pointer(&hdr))
}

func UnsafeCastInt32sToBytes(ints []int32) []byte {
length := len(ints) * BYTES_IN_INT32
hdr := reflect.SliceHeader{Data: uintptr(unsafe.Pointer(&ints[0])), Len: length, Cap: length}
return *(*[]byte)(unsafe.Pointer(&hdr))
}

*注意:您可能需要使用 SizeOf而不是一个常数。我更喜欢常数。

更新:以下是一些基准测试结果:

BenchmarkB2     20000000     88.7  ns/op
BenchmarkB4 5000000 309 ns/op
BenchmarkUnsafe 1000000000 2.25 ns/op

关于go - 在go中将int32转换为字节数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17539001/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com