Home  >  Article  >  Backend Development  >  Go language defaults to big endian or little endian

Go language defaults to big endian or little endian

青灯夜游
青灯夜游Original
2023-01-05 10:28:504232browse

The go language defaults to big endian. Generally speaking, the byte order of network transmission may be big endian or little endian, depending on the protocol provisions of the communication parties when the software starts. The TCP/IP protocol RFC1700 stipulates the use of "big endian" byte order as network byte order. This rule needs to be followed during development; by default, golang uses big endian order.

Go language defaults to big endian or little endian

The operating environment of this tutorial: Windows 7 system, GO version 1.18, Dell G3 computer.

1. Overview

Endianness: the sequence of bytes when stored in the computer and the sequence of input/output; also refers to the storage of multi-bytes The order of bytes of data, typically the way integers are stored in memory and the transmission order of network transmission.

Let’s look at the basic concepts first:

  • 1. Big endian mode (Big endian): Store high-order bytes at the starting address (from low address to Store the high-order byte of the data in the order of the high address to the low-order byte)

  • 2. Little endian mode (Little endian): Store the low-order byte at the starting address (in accordance with the starting address) The low-order byte of the data is stored in the order from low address to high address)

In the computer field, big and small endianness is related to the hardware architecture.

For example: For example, a var a = 0x11223344, the highest byte of this variable is 0x11, and the lowest byte is 0x44. Assume that the addresses allocated in memory are as follows (the addresses are all consecutive)

... 0x0001 0x0002 0x0003 0x0004 ...

When the contents are in big and small endian modes respectively, they are stored as follows

(1) Big endian mode storage (storage address is 16 bits)

Address data

0x0004(High address) 0x44

0x0003 0x33

0x0002 0x22

0x0001(Low address) 0x11

(2) Little endian mode storage (storage address is 16 bits)

Address data

0x0004 (high address) 0x11

0x0003 0x22

0x0002 0x33

0x0001 (low address) 0x44

2. Big-endian and little-endian

The definition of big-endian and big-endian was briefly explained above. It will be explained with simple examples, and detailed examples will be given next:

1. Big-Endian: or Big-endian

A type: the memory storage situation of the int32 number 0X0A0B0C0D

Go language defaults to big endian or little endian

The data is in 8bits

Go language defaults to big endian or little endian

In the example , the most significant bit is to store 0x0A at the lowest memory address, followed by 0x0B at the subsequent address, similar to the order of hexadecimal bytes from left to right.

Data is in units of 16bits

Go language defaults to big endian or little endian

The highest 16bit unit 0x0A0B is stored in the low bit

2, little endian Order (little-endian): or little-endian

Go language defaults to big endian or little endian

The data is in 8bits

Go language defaults to big endian or little endian

Example The least significant bit is the memory address stored in 0x0D, and is stored at subsequent addresses in sequence.

Data is in units of 16bits

Go language defaults to big endian or little endian

The lowest 16bit unit 0x0C0D is stored in the low bit.

3. Summary

A CPU using big-endian order and a CPU using little-endian order are not only opposite in bytes, but also in bits. .

For example, the storage of 0x01 in memory

Big endian: low memory bit 00000001 high memory bit

Little endian: low memory bit 10000000 high memory bit Bits

For example, 0x00000001

Big endian: memory low bits 00000000 00000000 00000000 00000001 memory high bits

Little endian: memory low bits 10000000 00000000 00000000 00000000 memory High bits

Application

In fact, the things listed above are ultimately for the following description of network transmission and file storage in golang. choose. Generally speaking, the byte order of network transmission may be big endian or little endian, depending on the protocol provisions of the communication parties when the software starts. TCP/IP protocol RFC1700 stipulates the use of "big endian" byte order as network byte order, and this rule needs to be followed during development. By default golang uses big endian order. For details, see the golang package encoding/binary, which has provided the use of big and little endian order

import (   
   "encoding/binary"
   "fmt"
)
func BigEndian() {    // 大端序
   // 二进制形式:0000 0000 0000 0000 0001 0002 0003 0004  
   var testInt int32 = 0x01020304  // 十六进制表示
   fmt.Printf("%d use big endian: \n", testInt)   
   
   var testBytes []byte = make([]byte, 4)  
   binary.BigEndian.PutUint32(testBytes, uint32(testInt))   //大端序模式
   fmt.Println("int32 to bytes:", testBytes)  

   convInt := binary.BigEndian.Uint32(testBytes)  //大端序模式的字节转为int32
   fmt.Printf("bytes to int32: %d\n\n", convInt)
}

func LittleEndian() {  // 小端序
   //二进制形式: 0000 0000 0000 0000 0001 0002 0003 0004
   var testInt int32 = 0x01020304  // 16进制
   fmt.Printf("%d use little endian: \n", testInt)   

   var testBytes []byte = make([]byte, 4)
   binary.LittleEndian.PutUint32(testBytes, uint32(testInt)) //小端序模式
   fmt.Println("int32 to bytes:", testBytes)

   convInt := binary.LittleEndian.Uint32(testBytes) //小端序模式的字节转换
   fmt.Printf("bytes to int32: %d\n\n", convInt)
}

func main() {
   BigEndian()
   LittleEndian()
}

Output results:

16909060 use big endian:
int32 to bytes: [1 2 3 4] ### [0001 0002 0003 0004]
bytes to int32: 16909060

16909060 use little endian:
int32 to bytes: [4 3 2 1] ### [0004 0003 0002 0001]
bytes to int32: 16909060

RPCX

In the RPCX framework, the big-endian mode is used to encode the messages involved in the RPC call process

func (m Message) Encode() []byte {  // 编码消息
       // 编码metadata将key-value转为key=value&key=value形式
    meta := encodeMetadata(m.Metadata)  

    spL := len(m.ServicePath)   // 服务长度
    smL := len(m.ServiceMethod)  // 服务函数

    var err error
    payload := m.Payload   // 消息体
    if m.CompressType() != None {  // 压缩
        compressor := Compressors[m.CompressType()]
        if compressor == nil { // 默认使用None压缩类型
            m.SetCompressType(None)
        } else {
            payload, err = compressor.Zip(m.Payload)  // GZIP压缩
            if err != nil {   // 压缩失败 不对传输消息进行压缩
                m.SetCompressType(None)
                payload = m.Payload            }
        }
    }

    // RPCX数据包 = header + ID + total size +
    // 服务名及内容: servicePath(size(servicePath) 、len(servicePath)) +
    // 服务函数及内容:serviceMethod(size(serviceMethod) 、 len(serviceMethod)) +
    // 元数据及内容:   metadata(size(metadata) 、len(metadata)) +  
    // 消息体及内容:payload(size(payload) 、 len(payload)) 

        // 消息长度 = size(servicePath) + len(servicePath) + size(serviceMethod) 
       //        + len(serviceMethod) + size(metadata) + len(metadata) 
       //        + size(payload) + len(payload)
    totalL := (4 + spL) + (4 + smL) + (4 + len(meta)) + (4 + len(payload))  


    // header + dataLen + spLen + sp + smLen + sm 
       //              + metaL + meta + payloadLen + payload
    metaStart := 12 + 4 + (4 + spL) + (4 + smL) // meata开始位置

    payLoadStart := metaStart + (4 + len(meta)) // payLoad开始位置
    l := 12 + 4 + totalL

    data := make([]byte, l)
    copy(data, m.Header[:])  // 拷贝header内容

        // 将数据包以大端序模式进行编码 
    //totalLen
    binary.BigEndian.PutUint32(data[12:16], uint32(totalL))  // 

    binary.BigEndian.PutUint32(data[16:20], uint32(spL))
    copy(data[20:20+spL], util.StringToSliceByte(m.ServicePath))

    binary.BigEndian.PutUint32(data[20+spL:24+spL], uint32(smL))
    copy(data[24+spL:metaStart], util.StringToSliceByte(m.ServiceMethod))

    binary.BigEndian.PutUint32(data[metaStart:metaStart+4], uint32(len(meta)))
    copy(data[metaStart+4:], meta)

    binary.BigEndian.PutUint32(data[payLoadStart:payLoadStart+4],
                                       uint32(len(payload)))
    copy(data[payLoadStart+4:], payload)

    return data}

[Related recommendations: Go video tutorial, Programming teaching

The above is the detailed content of Go language defaults to big endian or little endian. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn