我有一个缓冲区:
buffer := bytes.NewBuffer([]byte{
0x85, 0x02, 0xFF, 0xFF,
0x00, 0x01, 0x00, 0x02,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x03,
0x41, 0x42, 0x43,
})
我试图返回缓冲区的int值[8:24] 我得到了
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1]
不确定如何移动如此大的部分。字节。
这个新手。任何帮助都会很棒。我的初步方法是
requestid := (uint64(buffer.Bytes()[8]&0xff)<<24 + uint64(buffer.Bytes()[9]&0xff)<<16 + uint64(buffer.Bytes()[10]&0xff)<<8 + uint64(buffer.Bytes()[11]&0xff.....)))
但这很乏味,我知道必须有一个更简单的方法。
答案 0 :(得分:2)
您必须进行手动位移和“删除”,但可以通过删除所有buffer.Bytes()
次来清除您的代码。
您也不需要&0xff
部分。 n&0xff
的作用是清除0-255
范围之外的所有位。由于缓冲区中的每个值都是一个字节(0-255),因此这些操作根本不执行任何操作。如果我们想22 & 255
,我们会收到以下信息:
Hexadecimal | Decimal | Binary
--------------|-------------|----------------------
x 0x16 | 22 | 00010110
y 0xff | 255 | 11111111
--------------|-------------|---------------------- AND (&)
0x16 | 22 | 00010110 = x
如您所见,该操作完全没有效果。将x
替换为任何8位值,您将看到相同的结果。 x & 0xff
的结果始终为x
。
此外,当您分配到requestId
时,您可以先移动24位。这告诉我你正在读一个32位整数。为什么然后继续读取超过32位的值并将其全部转换为64位整数?
如果您正在Big Endian中读取64位int,请尝试以下操作:
data := buf.Bytes()[8:]
requestid := uint64(data[0])<<56 | uint64(data[1])<<48 |
uint64(data[2])<<40 | uint64(data[3])<<32 |
uint64(data[4])<<24 | uint64(data[5])<<16 |
uint64(data[6])<<8 | uint64(data[7])
如果您正在Little Endian中读取64位int,请尝试以下操作:
data := buf.Bytes()[8:]
requestid := uint64(data[7])<<56 | uint64(data[6])<<48 |
uint64(data[5])<<40 | uint64(data[4])<<32 |
uint64(data[3])<<24 | uint64(data[2])<<16 |
uint64(data[1])<<8 | uint64(data[0])
如果您正在Big Endian中读取32位int,请尝试以下操作:
data := buf.Bytes()[8:]
requestid := uint32(data[0])<<24 | uint32(data[1])<<16 |
uint32(data[2])<<8 | uint32(data[3])
如果您正在Little Endian中读取32位int,请尝试以下操作:
data := buf.Bytes()[8:]
requestid := uint32(data[3])<<24 | uint32(data[2])<<16 |
uint32(data[1])<<8 | uint32(data[0])
或者,您可以使用encoding/binary包:
var value uint64
err := binary.Read(buf, binary.LittleEndian, &value)
....