将数据从字节片解码到Uint32

package main

import (
        "bytes"
        "encoding/binary"
        "fmt"
)

func main() {
        aa := uint(0xFFFFFFFF)
        fmt.Println(aa)
        byteNewbuf := []byte{0xFF, 0xFF, 0xFF, 0xFF}
        buf := bytes.NewBuffer(byteNewbuf)
        tt, _ := binary.ReadUvarint(buf)
        fmt.Println(tt)
}

Need to convert 4 bytes array to uint32 but why the results are not same ? go verion : beta 1.1

tt := uint32(buf[0])<<24 | uint32(buf[1])<<16 | uint32(buf[2]) <<8 |
        uint32(buf[3])

for BE or

tt := uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2]) <<16 |
        uint32(buf[3]) <<24

for LE.

[u]varint is a different kind of encoding (32 bit numbers can have as much as 5 bytes in the encoded form, 64 bit numbers up to 10).

  • No need to create a buffer for []byte. Use Varint or Uvarint directly on the byte slice instead.

  • You're throwing away the error returned by the function. The second result indicates how many bytes were read or if there was a problem. There is a problem while decoding 0xff, 0xff, 0xff, 0xff as an uvarint.

Here is how to use the encoding/binary package to do what you want. Note that you don't want to use any of the var functions as those do variable length encoding.

Playground version

package main

import (
    "bytes"
    "encoding/binary"
    "fmt"
    "log"
)

func main() {
    aa := uint(0xFFFFFF0F)
    fmt.Println(aa)
    tt := uint32(0)

    byteNewbuf := []byte{0x0F, 0xFF, 0xFF, 0xFF}
    buf := bytes.NewBuffer(byteNewbuf)
    err := binary.Read(buf, binary.LittleEndian, &tt)
    if err != nil {
        log.Fatalf("Decode failed: %s", err)
    }
    fmt.Println(tt)
}

Result is

4294967055
4294967055

Numeric types

byte        alias for uint8

Since byte is an alias for uint8, your question, "Need to convert 4 bytes array to uint32", has already been answered:

How to convert [4]uint8 into uint32 in Go?

Package binary

[Uvarints and] Varints are a method of encoding integers using one or more bytes; numbers with smaller absolute value take a smaller number of bytes. For a specification, see http://code.google.com/apis/protocolbuffers/docs/encoding.html.

Since Uvarints are a peculiar form of integer representation and storage, you should only use the ReadUvarint function on values that have been written with the Uvarint function.

For example,

package main

import (
    "bytes"
    "encoding/binary"
    "fmt"
)

func main() {
    buf := make([]byte, 10)
    x := uint64(0xFFFFFFFF)
    fmt.Printf("%2d %2d %v
", x, len(buf), buf)
    n := binary.PutUvarint(buf, x)
    buf = buf[:n]
    fmt.Printf("%2d %2d %v
", x, len(buf), buf)
    y, err := binary.ReadUvarint(bytes.NewBuffer(buf))
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("%2d %2d %v
", y, len(buf), buf)
}

Output:

4294967295 10 [0 0 0 0 0 0 0 0 0 0]
4294967295  5 [255 255 255 255 15]
4294967295  5 [255 255 255 255 15]

You can do this with one of the ByteOrder objects from the encoding/binary package. For instance:

package main

import (
        "encoding/binary"
        "fmt"
)

func main() {
        aa := uint(0x7FFFFFFF)
        fmt.Println(aa)
        slice := []byte{0xFF, 0xFF, 0xFF, 0x7F}
        tt := binary.LittleEndian.Uint32(slice)
        fmt.Println(tt)
}

If your data is in big endian format, you can instead use the same methods on binary.BigEndian.