package main import ( "encoding/binary" "fmt" ) const ( posMajor int = 1 + iota posMinor posPatch posRelFlag ) var ( singleValVer uint32 singleValVerBytes []byte = []byte{ 0x01, 0x02, 0x03, 0x01, // A version of 1.2.3 with the PreRelease release flag enabled } ord binary.ByteOrder = binary.BigEndian ) func main() { var verVal uint8 singleValVer = ord.Uint32(singleValVerBytes) // fmt's Printf, for some silly reason, strips leading 0's from hex formatting unless you explicitly pad or align precision. fmt.Printf("%d\n%#.8x\n", singleValVer, singleValVer) // Prints: /* 16909057 0x01020301 */ /* The individual versions can be fetched by the following. This comment is an explanation of the condensed form below in code. 1. n = 8 * i // i is the version component you want. See the pos* constants at the top. 8 to align to a byte (8 bits). 2. offset = 32 - n // 32 because singleValVar is a uint32 (and thus 4 bytes, or 32 bits, in memory). 3. cmp = singleValVer >> offset // Shift to the bit offset we're interested in. 4. val32 = cmp & 0xff // It's then AND'd with 0xff (256) to get the set bits -- but still a uint32, so 5. verVal = uint8(val32) */ // For example: for i, verNm := range map[int]string{ posMajor: "Major", posMinor: "Minor", posPatch: "Patch", posRelFlag: "Release Flag(s)", } { verVal = uint8((singleValVer >> (32 - (8 * i))) & 0xff) fmt.Printf("%s: %d (%#02x)\n", verNm, verVal, verVal) } // Prints: /* Major: 1 (0x01) Minor: 2 (0x02) Patch: 3 (0x03) Release Flag(s): 1 (0x01) */ }