Rumah >pembangunan bahagian belakang >Golang >Bahasa Go lalai kepada endian besar atau endian kecil
Bahasa go lalai kepada big endian. Secara umumnya, susunan bait penghantaran rangkaian mungkin endian besar atau endian kecil, bergantung pada peruntukan protokol pihak komunikasi apabila perisian dimulakan. Protokol TCP/IP RFC1700 menetapkan penggunaan pesanan bait "enddian besar" sebagai susunan bait rangkaian Peraturan ini perlu dipatuhi semasa pembangunan secara lalai, golang menggunakan susunan bait besar.
Persekitaran pengendalian tutorial ini: sistem Windows 7, GO versi 1.18, komputer Dell G3.
Endianness: jujukan bait apabila disimpan dalam komputer dan jujukan input/output juga merujuk kepada storan berbilang bait susunan bait data, biasanya cara integer disimpan dalam ingatan dan susunan penghantaran penghantaran rangkaian.
Mari kita lihat konsep asas dahulu:
1. Mod endian besar (Endian besar): Simpan bait tertib tinggi pada alamat permulaan (dari rendah alamat untuk Simpan bait tertib tinggi data dalam susunan alamat tinggi kepada bait tertib rendah)
2. Mod endian kecil (Endian kecil): Simpan bait tertib rendah pada alamat permulaan (mengikut alamat permulaan) Bait tertib rendah data disimpan dalam susunan dari alamat rendah ke alamat tinggi)
Dalam medan komputer, besar dan endianness kecil berkaitan dengan seni bina perkakasan.
Contohnya: Contohnya, a var a = 0x11223344, bait tertinggi pembolehubah ini ialah 0x11, dan bait terendah ialah 0x44. Andaikan bahawa alamat diperuntukkan dalam ingatan seperti berikut (alamat semuanya berturut-turut)
... | 0x0001 | 0x0002 | 0x0003 | 0x0004 | ... |
---|
Apabila dalam mod endian besar dan kecil, kandungan disimpan seperti berikut
(1) Storan mod endian besar (alamat storan ialah 16 bit)
Alamat data
0x0004 (alamat tinggi) 0x44
0x0003 0x33
0x0002 0x22
0x0001 (alamat rendah
(2) Storan mod endian kecil (alamat storan ialah 16 bit)
Data alamat0x0004 (alamat tinggi) 0x110x0003 0x220x0002 0x33 0x0001 (alamat rendah) 0x44Storan memori jenis: int32 nombor 0X0A0B0C0D
Data berada dalam 8bit Dalam contoh , bit yang paling ketara ialah menyimpan 0x0A pada alamat memori terendah, diikuti dengan 0x0B pada alamat seterusnya, serupa dengan susunan bait perenambelasan dari kiri ke kanan.Data berada dalam unit 16bit
Unit 16bit tertinggi 0x0A0B disimpan dalam bit rendah 2. Susunan Little endian (little-endian): atau little-endian
Data berada dalam unit 8bits
Contoh Bit yang paling tidak ketara ialah alamat memori yang disimpan dalam 0x0D, dan disimpan pada alamat berikutnya mengikut urutan.
Data berada dalam unit 16bit
Unit 16bit 0x0C0D terendah disimpan dalam bit rendah. 3. RingkasanCPU yang menggunakan susunan big-endian dan CPU yang menggunakan susunan little-endian bukan sahaja bertentangan dalam bait, tetapi juga dalam bit . Contohnya, storan 0x01 dalam ingatan
Endian besar: ingatan rendah 00000001 ingatan tinggi
Endian kecil: ingatan rendah 10000000 ingatan tinggi Bit memori
Contohnya, 0x00000001
Endian besar: memori rendah bit 00000000 00000000 00000000 00000001 Memori tinggi bit
AplikasiMalah, perkara yang disenaraikan di atas akhirnya untuk tujuan penghantaran rangkaian dan storan fail dalam golang. Secara umumnya, susunan bait penghantaran rangkaian mungkin endian besar atau endian kecil, bergantung pada peruntukan protokol pihak komunikasi apabila perisian dimulakan. Protokol TCP/IP RFC1700 menetapkan penggunaan pesanan bait "enddian besar" sebagai susunan bait rangkaian, dan peraturan ini perlu dipatuhi semasa pembangunan. Secara lalai golang menggunakan susunan endian besar. Untuk butiran, lihat pengekodan/perduaan pakej golang yang menyediakan penggunaan endian besar dan kecil
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() }RPCX
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
Pengajaran Pengaturcaraan
]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}
Atas ialah kandungan terperinci Bahasa Go lalai kepada endian besar atau endian kecil. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!