Go 言語のデフォルトはビッグ エンディアンです。一般に、ソフトウェア起動時の通信相手のプロトコル規定により、ネットワーク伝送のバイトオーダーはビッグエンディアンとなる場合とリトルエンディアンとなる場合があります。 TCP/IP プロトコル RFC1700 では、ネットワーク バイト オーダーとして「ビッグ エンディアン」バイト オーダーの使用が規定されており、開発中はこのルールに従う必要があります。デフォルトでは、golang はビッグ エンディアン オーダーを使用します。
このチュートリアルの動作環境: Windows 7 システム、GO バージョン 1.18、Dell G3 コンピューター。
エンディアン: コンピュータに保存されるときのバイトのシーケンスと入出力のシーケンス。マルチバイトのストレージも指します。データのバイト順、通常は整数がメモリに格納される方法とネットワーク送信の送信順序。
まず基本的な概念を見てみましょう:
1. ビッグ エンディアン モード (ビッグ エンディアン): 開始アドレスに上位バイトを格納します (下位アドレスからアドレスまで)。データの上位バイトをアドレスの上位から下位バイトの順に格納します)
#2. リトルエンディアンモード(Little endian):下位バイトを格納開始アドレスのバイト(開始アドレスに応じて) データの下位バイトは下位アドレスから上位アドレスの順に格納されます)
コンピュータ分野では、ビッグエンディアンとスモールエンディアンはハードウェア アーキテクチャに関連しています。
例: たとえば、var a = 0x11223344、この変数の最上位バイトは 0x11、最下位バイトは 0x44 です。メモリ上に割り当てられたアドレスが次のとおりであるとします(アドレスはすべて連続しています)
... | 0x0001 | 0x0002 | 0x0003 | 0x0004 | ... |
---|
コンテンツがそれぞれビッグエンディアンモードとスモールエンディアンモードの場合、以下のように格納されます。
(1) ビッグエンディアンモードの格納(格納アドレスは16ビット)
アドレスデータ
0x0004(上位アドレス) 0x44
0x0003 0x33
0x0002 0x22
0x0001(下位アドレス) 0x11
(2) リトルエンディアンモードストレージ (ストレージアドレスは 16 ビット)
アドレスデータ
0x0004 (上位アドレス) 0x11
0x0003 0x22
0x0002 0x33
0x0001 (低アドレス) 0x44
big-endian の定義エンディアンとビッグエンディアンについては上で簡単に説明しましたが、簡単な例で説明し、次に詳細な例を示します:
1. ビッグエンディアン: またはビッグエンディアン
A型: int32数値0X0A0B0C0D
データのメモリ格納状況は8ビットです
この例では、最上位ビットは、左から右への 16 進バイトの順序と同様に、最下位メモリ アドレスに 0x0A を格納し、その後のアドレスに 0x0B が続きます。
データは 16 ビット単位です
最上位の 16 ビット単位 0x0A0B が下位ビットに格納されます
2、リトルエンディアン 順序 (リトルエンディアン): またはリトルエンディアン
データは 8 ビットです
例 最下位ビットは 0x0D に格納されるメモリ アドレスで、以降のアドレスに順番に格納されます。
データは16ビット単位です
下位ビットには最下位16ビット単位の0x0C0Dが格納されます。
3. 概要
ビッグエンディアン順序を使用する CPU とリトルエンディアン順序を使用する CPU は、バイト数だけでなくビット数も逆です。
たとえば、メモリ内の 0x01 のストレージ
ビッグ エンディアン: メモリ下位ビット 00000001 メモリ上位ビット
リトル エンディアン: メモリ下位ビット 10000000 メモリ上位ビット
例: 0x00000001
ビッグ エンディアン: メモリの下位ビット 00000000 00000000 00000000 00000001 メモリの上位ビット
リトル エンディアン: メモリの下位ビット 10000000 00000000 00000000 00000000 メモリの上位ビット
実際、上記にリストされているものは、最終的には、golang でのネットワーク送信とファイル ストレージについての次の説明のためのものです。一般に、ソフトウェア起動時の通信相手のプロトコル規定により、ネットワーク伝送のバイトオーダーはビッグエンディアンとなる場合とリトルエンディアンとなる場合があります。 TCP/IP プロトコル RFC1700 では、ネットワーク バイト オーダーとして「ビッグ エンディアン」バイト オーダーを使用することが規定されており、開発時にはこの規則に従う必要があります。デフォルトでは、golang はビッグエンディアン順序を使用します。詳細については、ビッグ エンディアン順序とリトル エンディアン順序の使用を提供する golang パッケージのエンコーディング/バイナリを参照してください。
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() }
出力結果:
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 フレームワークでは、RPC 呼び出しプロセスに関係するメッセージをエンコードするためにビッグ エンディアン モードが使用されます。
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}
[関連する推奨事項: Go ビデオ チュートリアル 、プログラミング教育 ]
以上がGo言語のデフォルトはビッグエンディアンまたはリトルエンディアンですの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。