清晰的理解大端和小端

首先从byte聊起:

        最早的计算机有 4-bit、6-bit、7-bit 等好多种。IBM在 1950 年设计 IBM 7030 Stretch 的时候引入 byte 的概念,byte表示访问内存的最小单位

布鲁克斯被问到:“您认为自己最大的技术成就是什么?”

Brooks回答说:“我做出的最重要的决定是将IBM 360系列从6位更改为8位字节,从而允许使用小写字母。这种变化传播到了所有地方。

微型计算机要到 1970 年代早期才出现,那个时候8位byte已经用了将近十年了,自然大家就继续使用了。

大端和小端:

byte表示访问内存的最小单位且为8个bit,这个是人为规定出来的,延续至今是个历史原因。有最小的储存单位,就有更大的储存单位,如int ,long ,一般情况下int 是32位的,long是64位的。

那 int 和 long 是由最小访问内存单位byte构成的,那么问题就来了,当byte构成 int 和 long时,顺序怎么放?于是就有了大端的摆放方式  和  小端的摆放方式,如下:

 那其实,这里就可以看到,所谓的大小端是针对,比byte大的单位,内部的byte如何摆放的。

 什么时候要进行大小端字节序的转换?

出现了大端和小端,说明是出现的分歧,有的地方,觉得小端好,有的地方,觉得大端好。那既然有了分歧,作为程序员,就多了一份转换的工作

那那些地方用的大端那些地方用的小端?

Motorola的PowerPC系列CPU采用Big Endian方式存储数据。


Intel的x86系列CPU采用Little Endian方式存储数据。


ARM既可以工作在大端模式,也可以工作在小端模式。在ARM上,我见到的都是用Little Endian方式存储数据。


Windos(x86,x64)和Linux(x86,x64)都是Little Endian操作系统


C/C++语言编写的程序里数据存储顺序是跟编译平台所在的CPU相关的。


JAVA编写的程序则唯一采用Big Endian方式来存储数据。


所有网络协议也都是采用Big Endian的方式来传输数据的。所以有时我们也会把Big Endian方式称之为网络字节序。

知道了这些,大概就知道什么时候需要转换了。举几个例子:

c# 到网络
c#在windows平台上是小端字节序(Windos(x86,x64)和Linux(x86,x64)都是Little Endian操作系统,不止是c#)。网络发送字节流是按大端序发送,也就是从左到右发送,和c#的小端序相反,造成网关不能正常识别协议。所以需要转换。

c# 到JAVA

在你的C#程序传给JAVA程序之前有必要进行字节序的转换工作。


字符串不需要大小端转换

上面的转换其实针对的都是数字,应为顺序变了,数学的大小就变了,但是字符串不同,它有自己的编码顺序(UTF8 ASCC  gb2312 等等)

所以,我们可以看到这样的代码:

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public static byte[] BuildMsgCmd(string msg)
        {
            var arr = new List<byte> { };
            //转为byte数组并进行大小端转换
            var byteHeader = BitConverter.GetBytes(HeartMsg).Reverse().ToList();
            //字符串不用进行大小端转换
            var byteMsg = Encoding.UTF8.GetBytes(msg);
            //转为byte数组并进行大小端转换
            var byteLength = BitConverter.GetBytes((ushort)byteMsg.Length).Reverse().ToList();

            arr.AddRange(byteHeader);
            arr.AddRange(byteLength);
            arr.AddRange(byteMsg);
            return arr.ToArray();
        }

数字相关的都进行了,大小端转换,字符串就不用了。


参考资料:

大小端字节序(Big Endian和Little Endian)_编程爱好者熊浪的博客-CSDN博客_大小端字节序

为什么一个字节定义成8位? - 知乎 (zhihu.com)

posted @ 2022-07-15 11:56  宋桓公  阅读(93)  评论(0编辑  收藏  举报