理解网络中大端和小端往往是一道基础面试题 ,这里作为记录和整理,希望能帮到大家

目录

前言

一、字节序     

二、什么小端顺序

三、什么大端顺序

四、处理器体系所属网络字节顺序

五、大小端转换

1、大端整形转换为小端

2、小端转换为小端

3、C# 字节转换接口

六、为什么有大小端之分


前言

        在实际开发中,做过网络的小伙伴一定会碰到网络字节顺序(大端和小端)的问题,尤其unity游戏开发。因为对于C++和Java默认是大端开发,C#就非常另类,默认的网络的字节顺序是小端,这里就牵扯到大小端的转换问题。

一、字节序     

         字节顺序又称端序或尾序(Endianness),在计算机科学领域中,指电脑内存中或在数字通信链路中,组成多字节的字的字节的排列顺序。在几乎所有的机器上,多字节对象都被存储为连续的字节序列。

        例如在 C 语言中,一个类型为 int 的变量 x 地址为 0x100,那么其对应地址表达式 &x 的值为 0x100,x 的四个字节将被存储在电脑内存的 0x100,0x101,0x102,0x103 位置。字节的排列方式常见的方式有两种:将一个多位数的低位放在较小的地址处,高位放在较大的地址处,则称小端序(Little-Endian);反之则称大端序(Big-Endian)。

        为什么需要字节序这个规定,主要是因为在网络应用中字节序是一个必须被考虑的因素,对于不同 CPU 可能采用不同标准的字节序,所以均按照网络标准转化成相应的字节序。

二、什么小端顺序

Little-Endian:将低序字节存储在起始地址(低位编址),在变量指针转换的时候地址保持不变,比如 int64* 转到 int32*,对于机器计算来说更友好和自然。

java 小端字节序转大端字节序 字节大小端转换_java 小端字节序转大端字节序

三、什么大端顺序

Big-Endian:将高序字节存储在起始地址(高位编址),内存顺序和数字的书写顺序是一致的,对于人的直观思维比较容易理解,网络字节序统一规定采用 Big-Endian。

java 小端字节序转大端字节序 字节大小端转换_java 小端字节序转大端字节序_02

四、处理器体系所属网络字节顺序

       网络字节顺序,通常和CPU的架构相关,不同的CPU网络字节顺序有可能不同。它们主要分为三类:

CPU架构

字节顺序

x86、MOS Technology 6502

、Z80、VAX、PDP-11

小端

Motorola 6800、Motorola 68000、PowerPC 970、System/370、SPARC(除V9外)

大端

ARM、PowerPC(除PowerPC 970外)、DEC Alpha、SPARC V9、MIPS、PA-RISC及IA64

字节顺序配置

五、大小端转换

1、大端整形转换为小端

//int 大端转小端
int order2little(int be)
{
    return ((be >> 24) &0xff ) 
        | ((be >> 8) & 0xFF00) 
        | ((be << 8) & 0xFF0000) 
        | ((be << 24));    
}

2、小端转换为小端

//int 小端转大端
int order2big(int le) {

    return (le & 0xff) << 24 
            | (le & 0xff00) << 8 
            | (le & 0xff0000) >> 8 
            | (le >> 24) & 0xff;
}

3、C# 字节转换接口

//---------大小端整型转换
short i = 100;//小端100

short bigValue = System.Net.IPAddress.HostToNetworkOrder(i);//把i转成相应的大端字节数

short little = System.Net.IPAddress.NetworkToHostOrder(bigValue);//将bigValue转换为小端


//---------byte数组转换大端,data是小端数据
var orders= new byte[4];

Array.Copy(data, 0, orders, 0, 4);

orders= orders.Reverse().ToArray();

var n = BitConverter.ToInt32(orders, 0);


//---------字符串反转,大小端判断

int data = 439041118; // 十六进制为 1A2B3C5E
byte[] bData = BitConverter.GetBytes( data );
            
if (BitConverter.IsLittleEndian) // 若为 小端模式
{
   Array.Reverse( bData ); // 转换为 大端模式               
}
string s = BitConverter.ToString( bData );

六、为什么有大小端之分

1、网络协议指定的网络字节顺序是大端
2、不同的CPU架构有不同的网络字节顺序

3、不同语言默认网络字节顺序有小端之分

4、计算机电路先处理低位字节,效率比较高。因为计算就是从低位开始的,所以计算机内部很多

        都是小端字节序。

5、而大端字节序更符合人类的思维习惯