当前位置:首页 > 文章列表 > Golang > Go教程 > go语言默认是大端吗

go语言默认是大端吗

来源:亿速云 2023-03-08 09:12:16 0浏览 收藏

本篇文章主要是结合我之前面试的各种经历和实战开发中遇到的问题解决经验整理的,希望这篇《go语言默认是大端吗》对你有很大帮助!欢迎收藏,分享给更多的需要的朋友学习~

本篇内容主要讲解“go语言默认是大端吗”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“go语言默认是大端吗”吧!

go语言默认是大端。一般来说网络传输的字节序,可能是大端序或者小端序,取决于软件开始时通讯双方的协议规定。TCP/IP协议RFC1700规定使用“大端”字节序为网络字节序,开发的时候需要遵守这一规则;而默认golang是使用大端序的。

一、概述

字节序:字节在电脑中存放时的序列与输入/输出时的序列;也指的是存放多字节数据的字节(byte)的顺序,典型的情况是整数在内存中的存放方式和网络传输的传输顺序。

先看下基本概念:

  • 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

0x0003 0x22

0x0002 0x33

0x0001(低地址) 0x44

二、大端序和小端序

在前面也简单阐述了大小端序的定义并结合简单实例来说明,接下来会给出详细实例来说明:

1、大端序(Big-Endian):或称大尾序

一个类型: int32 的数 0X0A0B0C0D的内存存放情况

go语言默认是大端吗

数据是以8bits为单位

go语言默认是大端吗

示例中,最高有效位是将0x0A存储在最低的内存地址处,接着是0x0B存在后面的地址,类似十六进制字节从左往右的顺序。

数据以16bits为单位

go语言默认是大端吗

最高的16bit单元0x0A0B存储在低位

2、小端序(little-endian):或称小尾序

go语言默认是大端吗

数据以8bits为单位

go语言默认是大端吗

示例中最低有效位则是0x0D存储的内存地址处,后面依次存放在后面的地址处。

数据以16bits为单位

go语言默认是大端吗

最低的16bit单元0x0C0D存储在低位。

3、总结

采用大端序的CPU和采用小端序的CPU不仅在字节上是相反的,在比特位上也是相反的。

比如0x01在内存中的存储

大端序:内存低比特位 00000001 内存高比特位

小端序:内存低比特位 10000000 内存高比特位

比如0x00000001

大端序:内存低比特位 00000000 00000000 00000000 00000001 内存高比特位

小端序:内存低比特位 10000000 00000000 00000000 00000000 内存高比特位

应用

其实在前面罗列出那么东西,最终是为了接下来讲述的在golang中涉及到网络传输、文件存储时的选择。一般来说网络传输的字节序,可能是大端序或者小端序,取决于软件开始时通讯双方的协议规定。TCP/IP协议RFC1700规定使用“大端”字节序为网络字节序,开发的时候需要遵守这一规则。默认golang是使用大端序。详情见golang中包encoding/binary已提供了大、小端序的使用

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语言默认是大端吗”有了更深的了解,不妨来实际操作一番吧!这里是golang学习网,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

版本声明
本文转载于:亿速云 如有侵犯,请联系study_golang@163.com删除
go语言支持安卓开发吗go语言支持安卓开发吗
上一篇
go语言支持安卓开发吗
go语言必须要有的包是什么
下一篇
go语言必须要有的包是什么
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    542次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    508次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    497次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • PPTFake答辩PPT生成器:一键生成高效专业的答辩PPT
    PPTFake答辩PPT生成器
    PPTFake答辩PPT生成器,专为答辩准备设计,极致高效生成PPT与自述稿。智能解析内容,提供多样模板,数据可视化,贴心配套服务,灵活自主编辑,降低制作门槛,适用于各类答辩场景。
    21次使用
  • SEO标题Lovart AI:全球首个设计领域AI智能体,实现全链路设计自动化
    Lovart
    SEO摘要探索Lovart AI,这款专注于设计领域的AI智能体,通过多模态模型集成和智能任务拆解,实现全链路设计自动化。无论是品牌全案设计、广告与视频制作,还是文创内容创作,Lovart AI都能满足您的需求,提升设计效率,降低成本。
    20次使用
  • 美图AI抠图:行业领先的智能图像处理技术,3秒出图,精准无误
    美图AI抠图
    美图AI抠图,依托CVPR 2024竞赛亚军技术,提供顶尖的图像处理解决方案。适用于证件照、商品、毛发等多场景,支持批量处理,3秒出图,零PS基础也能轻松操作,满足个人与商业需求。
    33次使用
  • SEO标题PetGPT:智能桌面宠物程序,结合AI对话的个性化陪伴工具
    PetGPT
    SEO摘要PetGPT 是一款基于 Python 和 PyQt 开发的智能桌面宠物程序,集成了 OpenAI 的 GPT 模型,提供上下文感知对话和主动聊天功能。用户可高度自定义宠物的外观和行为,支持插件热更新和二次开发。适用于需要陪伴和效率辅助的办公族、学生及 AI 技术爱好者。
    34次使用
  • 可图AI图片生成:快手可灵AI2.0引领图像创作新时代
    可图AI图片生成
    探索快手旗下可灵AI2.0发布的可图AI2.0图像生成大模型,体验从文本生成图像、图像编辑到风格转绘的全链路创作。了解其技术突破、功能创新及在广告、影视、非遗等领域的应用,领先于Midjourney、DALL-E等竞品。
    56次使用
查看更多
相关文章
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码