Maison  >  Article  >  développement back-end  >  La langue par défaut est big endian ou little endian

La langue par défaut est big endian ou little endian

青灯夜游
青灯夜游original
2023-01-05 10:28:504250parcourir

La langue go est par défaut big endian. D'une manière générale, l'ordre des octets de transmission réseau peut être big endian ou little endian, en fonction des dispositions du protocole des parties en communication au démarrage du logiciel. Le protocole TCP/IP RFC1700 stipule l'utilisation de l'ordre des octets « big endian » comme ordre des octets du réseau. Cette règle doit être suivie pendant le développement, par défaut, golang utilise l'ordre big endian.

La langue par défaut est big endian ou little endian

L'environnement d'exploitation de ce tutoriel : système Windows 7, GO version 1.18, ordinateur Dell G3.

1. Présentation

Ordre des octets : la séquence d'octets lorsqu'ils sont stockés dans l'ordinateur et la séquence d'entrée/sortie fait également référence à l'ordre des octets (octets) pour stocker les données multi-octets, typique. la manière dont les entiers sont stockés en mémoire et l'ordre dans lequel ils sont transmis sur le réseau.

Regardons d'abord les concepts de base :

  • 1. Mode Big endian (Big endian) : stocke les octets de poids fort à l'adresse de départ (stocke les octets de poids fort des données dans les octets de poids faible). dans l'ordre de l'adresse basse à l'adresse haute) Octets)

  • 2. Mode Little endian (Little endian) : stockez les octets de poids faible à l'adresse de départ (stockez les octets de poids faible dans les octets de poids fort de les données dans l'ordre de l'adresse basse à l'adresse haute)

Dans le domaine informatique, le grand et le petit boutisme sont liés à l'architecture matérielle.

Par exemple : Par exemple, une var a = 0x11223344, l'octet le plus élevé de cette variable est 0x11 et l'octet le plus bas est 0x44. Supposons que les adresses sont allouées en mémoire comme suit (les adresses sont toutes consécutives)

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

En modes grand et petit endian, le contenu est stocké comme suit

(1) Stockage en mode big endian (l'adresse de stockage est de 16 bits)

Données d'adresse

0x0004 (adresse haute) 0x44

0x0003 0x33

0x0002 0x22

0x0001 (adresse basse) 0x11

(2) Stockage en mode Little endian (l'adresse de stockage est de 16 bits)

Données d'adresse

0x0004 (adresse haute) 03 0x22

0x0002 0x33

0x0001 (adresse basse) 0x44

2. Big-endian et small-endian

La définition de big-endian et big-endian a été brièvement expliquée plus tôt et expliquée avec des exemples simples. Ensuite, des exemples détaillés seront donnés. pour illustrer :

1. Big-Endian : Ou ordre Big-endian

Un type : la situation de stockage mémoire du numéro int32 0X0A0B0C0D

La langue par défaut est big endian ou little endianLes données sont en 8bits

La langue par défaut est big endian ou little endianDans l'exemple , le bit valide le plus élevé consiste à stocker 0x0A à l'adresse mémoire la plus basse, suivi de 0x0B aux adresses suivantes, similaire à l'ordre des octets hexadécimaux de gauche à droite.

Les données sont en 16 bits

La langue par défaut est big endian ou little endianL'unité de 16 bits la plus élevée 0x0A0B est stockée dans les bits faibles


2.

Dans l'exemple, le bit le moins significatif est l'adresse mémoire stockée à 0x0D et est stockée aux adresses suivantes dans l'ordre.

La langue par défaut est big endian ou little endianLes données sont en unités de 16 bits

La langue par défaut est big endian ou little endianL'unité de 16 bits la plus basse 0x0C0D est stockée dans le bit faible.

3. Résumé

Un CPU utilisant l'ordre big-endian et un CPU utilisant l'ordre small-endian sont non seulement opposés en termes d'octets, mais aussi en termes de bits. La langue par défaut est big endian ou little endian

Par exemple, le stockage de 0x01 en mémoire

Big endian : mémoire faible bit 00000001 mémoire élevée bit

Little endian : mémoire faible bit 10000000 mémoire élevée bit

par exemple 0x00000001

Big endian : mémoire faible bits 0000000 0 00000000 00000000 00000001 Bits de mémoire élevés

Little endian : Bits de mémoire faibles 10000000 00000000 00000000 00000000 Bits de mémoire élevés

Application

En fait, les éléments énumérés ci-dessus sont finalement destinés à ce qui suit. Il parle des choix en ce qui concerne la transmission réseau et le stockage de fichiers dans Golang. D'une manière générale, l'ordre des octets de transmission réseau peut être big endian ou little endian, en fonction des dispositions du protocole des parties en communication au démarrage du logiciel. Le protocole TCP/IP RFC1700 stipule l'utilisation de l'ordre des octets « big endian » comme ordre des octets du réseau, et cette règle doit être suivie pendant le développement. Par défaut, Golang utilise l'ordre big endian. Pour plus de détails, consultez le package encoding/binary dans golang, qui a fourni l'utilisation de l'ordre big et little endian

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()
}

Résultats de sortie :

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

Dans le framework RPCX, la livraison du message impliquée dans le. Le processus d'appel RPC est codé en mode It's big endian

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}

【Recommandations associées :
Tutoriel vidéo Go

,

Enseignement de la programmation

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn