>  기사  >  백엔드 개발  >  Go 언어의 기본값은 빅 엔디안 또는 리틀 엔디안입니다.

Go 언어의 기본값은 빅 엔디안 또는 리틀 엔디안입니다.

青灯夜游
青灯夜游원래의
2023-01-05 10:28:504255검색

go 언어는 기본적으로 빅엔디안으로 설정되어 있습니다. 일반적으로 네트워크 전송의 바이트 순서는 소프트웨어가 시작될 때 통신 당사자의 프로토콜 규정에 따라 빅 엔디안 또는 리틀 엔디안이 될 수 있습니다. TCP/IP 프로토콜 RFC1700은 네트워크 바이트 순서로 "빅 엔디안" 바이트 순서를 사용하도록 규정합니다. 이 규칙은 기본적으로 개발 중에 따라야 하며, golang은 빅 엔디안 순서를 사용합니다.

Go 언어의 기본값은 빅 엔디안 또는 리틀 엔디안입니다.

이 튜토리얼의 운영 환경: Windows 7 시스템, GO 버전 1.18, Dell G3 컴퓨터.

1. 개요

바이트 순서: 컴퓨터에 저장될 때의 바이트 순서와 입출력 순서는 멀티바이트 데이터를 저장하는 바이트(바이트) 순서를 의미하기도 합니다. 정수가 메모리에 저장되는 방식과 네트워크를 통해 전송되는 순서.

먼저 기본 개념을 살펴보겠습니다.

  • 1. 빅 엔디안 모드(Big endian): 상위 바이트를 시작 주소에 저장합니다(데이터의 상위 바이트를 하위 바이트에 저장). 낮은 주소에서 높은 주소 순으로) 바이트)

  • 2. 리틀 엔디안 모드(Little endian): 시작 주소에 하위 바이트를 저장합니다(낮은 순서의 바이트를 상위 주소에 저장합니다). 낮은 주소부터 높은 주소 순으로)

컴퓨터 분야에서 엔디안은 하드웨어 아키텍처와 관련이 있습니다.

예: var a = 0x11223344, 이 변수의 가장 높은 바이트는 0x11이고 가장 낮은 바이트는 0x44입니다. 주소는 다음과 같이 메모리에 할당된다고 가정합니다(주소는 모두 연속적입니다)

0x00010x00020x00030x0004...

빅 엔디안 모드와 스몰 엔디안 모드일 때 내용은 다음과 같이 저장됩니다

(1) 빅 엔디안 모드 저장(저장 주소는 16비트)

주소 데이터

0x0004(상위 주소) 0x44

0x0003 0x33

0x0002 0x22

0x0001(하위 주소) 0x11

(2) 리틀 엔디안 모드 저장(저장 주소는 16비트)

주소 데이터

0x0004(상위 주소) 0x11

0x00 03 0x22

0x0002 0x33

0x0001( 하위 주소) 0x44

2. 빅엔디안과 리틀엔디안

앞서 빅엔디안과 빅엔디안의 정의를 간략하게 설명하였고, 다음으로 간단한 예를 들어 설명하겠습니다. 설명:

1. 빅엔디안: 또는 빅엔디안 순서

A 유형: int32 숫자 0X0A0B0C0D의 메모리 저장 상황

Go 언어의 기본값은 빅 엔디안 또는 리틀 엔디안입니다.

데이터는 8비트입니다.

Go 언어의 기본값은 빅 엔디안 또는 리틀 엔디안입니다.

예제에서 , 가장 높은 유효한 비트는 가장 낮은 메모리 주소에 0x0A를 저장하고 그 다음 주소에 0x0B를 저장하는 것입니다. 이는 16진수 바이트의 왼쪽에서 오른쪽 순서와 유사합니다.

데이터는 16비트입니다

Go 언어의 기본값은 빅 엔디안 또는 리틀 엔디안입니다.

최상위 16비트 단위인 0x0A0B가 하위비트에 저장됩니다

2 리틀엔디안: 또는 리틀엔디안

Go 언어의 기본값은 빅 엔디안 또는 리틀 엔디안입니다.

데이터는 8비트입니다

Go 언어의 기본값은 빅 엔디안 또는 리틀 엔디안입니다.

예제에서 최하위 비트는 0x0D에 저장된 메모리 주소이며, 다음 주소에 순차적으로 저장됩니다.

데이터는 16비트 단위입니다

Go 언어의 기본값은 빅 엔디안 또는 리틀 엔디안입니다.

최하위 16비트 단위인 0x0C0D가 하위 비트에 저장됩니다.

3. 요약

빅엔디안 순서를 사용하는 CPU와 리틀엔디안 순서를 사용하는 CPU는 바이트 단위뿐만 아니라 비트 단위에서도 반대입니다.

예를 들어 메모리에 0x01을 저장하는 경우

빅 엔디안: 메모리 하위 비트 00000001 메모리 상위 비트

리틀 엔디안: 메모리 하위 비트 10000000 메모리 상위 비트

예: 0x00000001

빅 엔디안: 메모리 하위 비트 0000000 0 00000000 00000000 00000001 높은 메모리

리틀 엔디안: 낮은 메모리 10000000 00000000 00000000 00000000 높은 메모리

Application

사실 위에 나열된 것들은 결국 다음 단계를 위한 선택에 관한 것입니다. 언제 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

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.