Encoding with little endianness Go lang
Asked Answered
L

1

5

I am having to work on a web server for work and there are portions of our code written by our chief engineers that I don't understand and am currently trying to decipher. Here is a similar and much simpler version of what is happening within our code base, and I was wondering if anyone could give me a deep explanation of what this is doing step by step.

package main
import "fmt"
import "encoding/binary"
func main() {
////////////////////////////////// no need to explain anything
    b := []byte{2,3,5,7,11,13} /// within this comment block.
    for _,e := range b {        //
    fmt.Printf("%d ",e)         //
    }                           //
    fmt.Printf("\n")            //
    //////////////////////////////
    length:= binary.LittleEndian.Uint32(b)  /// <<< Why this results in                                                 
                                            /// 117768962 is the question.
    fmt.Printf("customLen=%d\n",int(length))

}
Liminal answered 2/3, 2018 at 21:13 Comment(5)
Is the confusion because a uint32 is only 32 bits, so the 11 and 13 are ignored?Scintilla
no, if you you chop off the 11 and 13 its still going to give you 117768962, my biggest question here is wondering what that new number "represents"Liminal
yes, you can add as many extra values as you want, but you can only decode 32 bits into a 32 bit value. The LittleEndian.Uint32 function is only really 1 line of code: golang.org/src/encoding/binary/binary.go#L62Scintilla
It represents the first 4 bytes (size of a uint32) as a uint32. All of the stdlib code is available to view, and it's even linked from the documentation, if you're curious to know what any stdlib function does step by step.Jourdain
@smokums, The fact that you're decoding the value into something named "length" means that this is probably extracted from some code to parse a larger binary format. Perhaps supplying the context for what you're doing here would help guide someone to an answer. As it is, this is not much different than asking why 0x07050302 is the same as 117768962, the former is just a different representation or encoding the latter.Scintilla
Z
25

When we write numbers in English, we write them in big-endian base-10 representation. For example the number "4567" is understood to mean 4*10^3 + 5*10^2 + 6*10^1 + 7*10^0. This is base-10 because each written digit differs in significance by a factor of 10 from adjacent digits, and it is big-endian because the first written digit is associated with the biggest power of 10.

The same number 4567 could be written in little-endian base-10 as "7654", which in little-endian representation would mean 7*10^0 + 6*10^1 + 5*10^2 + 4*10^3, numerically the same as in the previous paragraph. This is little-endian because the first written digit is associated with the littlest power of 10.

The binary.LittleEndian.Uint32 function receives a slice of bytes and reads out of it a 32-bit unsigned integer represented in little-endian base-256.

So if the base-256 digits in the input slice b are 2,3,5,7 as they are in your code, the little-endian base-256 interpretation of those bytes is 2*256^0 + 3*256^1 + 5*256^2 + 7*256^3. The same number written in big-endian base-10 (which is what fmt.Printf will show you) is "117768962".

Zonation answered 3/3, 2018 at 7:5 Comment(1)
You sir are a godsend. This is EXACTLY the response I was looking for. I was completely unaware that it was represented in base 256. I couldnt find that anywhere in the Go API.Liminal

© 2022 - 2024 — McMap. All rights reserved.