如何将十六进制字节切片转换为整数?

huangapple go评论88阅读模式
英文:

How to convert a slice of hexadecimal bytes to integer

问题

我正在将一个十进制整数转换为十六进制字符串,然后将其存储在文件中:

str := fmt.Sprintf("%08x", 1662489944)

b, _ := hex.DecodeString(str)

file.Write(b) //似乎写入了63179558

是的,我知道这看起来可能有些愚蠢,而且我毫不怀疑有更好的方法来做到这一点:我想用前导0填充这个值。

当我读取文件的内容时,我得到了一个字节切片:

[]byte{63, 17, 95, 58}

如何将这个切片转换回十进制值1662489944(32位)?

英文:

I'm converting a base 10 integer to a hexadecimal string before storing it in a file:

str := fmt.Sprintf("%08x", 1662489944)

b, _ := hex.DecodeString(str)

file.Write(b) //seems to write 63179558

Yes I know this probably looks silly and I have no doubt there's better ways to do this: I wanted to pad this value with leading 0's.

When I read the contents of the file, I get a slice of bytes:

[]byte{63, 17, 95, 58}

How do I convert this slice back into the base 10 value of 1662489944 (32 bit)?

答案1

得分: 2

以下代码将值作为四字节大端数写入文件。

str := fmt.Sprintf("%08x", 1662489944)
b, _ := hex.DecodeString(str)
file.Write(b)

使用以下代码来反转转换:

b = make([]byte, 4)
io.ReadFull(file, b)
n := int(binary.BigEndian.Uint32(b))

PlayGround示例

以下是将数字作为四字节大端数直接写入文件的更直接的方法。

b := make([]byte, 4)
binary.BigEndian.PutUint32(b, 1662489944)
file.Write(b)
英文:

The following code writes the value to the file as a four byte big endian number.

str := fmt.Sprintf("%08x", 1662489944)
b, _ := hex.DecodeString(str)
file.Write(b)

Use this code to reverse the transformation:

b = make([]byte, 4)
io.ReadFull(file, b)
n := int(binary.BigEndian.Uint32(b))

PlayGround example.

Here's a more direct way to write the number to the file as a four byte big endian number.

b := make([]byte, 4)
binary.BigEndian.PutUint32(b, 1662489944)
file.Write(b)

答案2

得分: 1

你的实际十六进制字符串是如何写入文件和读取回来的并不太清楚。但根据你的一条评论:

> 当我在文件上运行hexdump时,显示的是63 17 95 58

这足以证明你应该处理的字节切片应该是十六进制表示,而不是十进制表示,即[]byte{0x63, 0x17, 0x95, 0x58}或者十进制字节切片[]byte{99, 23, 149, 88},但肯定不是你在原始问题中发布的那个。这可以通过hex包中的几种方法来确认,它们可以将十六进制字符串编码为字节并进行反向转换。

对于将十六进制字节切片转换回十进制的原始问题,你可以使用encoding/binary包中的ByteOrder实现来将其转换为32位、64位数字。所以简单地写成:

binary.BigEndian.Uint32([]byte{0x63, 0x17, 0x95, 0x58})

Go playground

英文:

It is not quite clear, how your actual hex-string is written to the file and read back. But based on one your comment,

> When I run hexdump on the file, it shows 63 17 95 58

Which is evident enough that the byte slice you should be dealing with, should be in hex notation and not in decimal, i.e. []byte{0x63, 0x17, 0x95, 0x58} or in decimal byte slice []byte{99, 23, 149, 88}, but definitely not the one posted in OP. This can be confirmed by couple of methods in hex package, that encode hex string to bytes and vice-versa,

package main

import (
	"encoding/hex"
	"fmt"
	"log"
)

func main() {
	const s = "63179558"
	decoded, err := hex.DecodeString(s)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%v\n", decoded)
	fmt.Printf("%s\n", hex.EncodeToString([]byte{0x63, 0x17, 0x95, 0x58}))

}

which produces

[99 23 149 88]
63179558

confirming my above assumption.

As for your original question to convert the slice of hex bytes back to base 10, you could use the the encoding/binary package's implementation of ByteOrder, to convert to 32-bit, 64-bit numbers. So quite simply just

binary.BigEndian.Uint32([]byte{0x63, 0x17, 0x95, 0x58})

Go playground

huangapple
  • 本文由 发表于 2022年10月7日 11:36:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/73982100.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定