001-大端小端

发布时间 2023-10-27 12:27:24作者: 进阶的JFrame

大端小端

1 前言

在做项目时,需要将报文发送给硬件端,报文打包我都是用的大端写入Bytebuf(使用的netty),老大审查代码时,说我写错了,说硬件那边要求是小端传输。不过改成小端写入也容易,重要的是牢记这个知识点。于是趁这个机会复习一下大端和小端。

2 概念

大端(Big-Endian)和小端(Little-Endian)的定义如下:

小端(Little-Endian)数据的低位字节位存放在内存的低地址端,高位字节存放在内存的高地址端。

大端(Big-Endian) 数据的高位字节位存放在内存的低地址端,低位字节存放在内存的高地址端。

2.1 什么是低地址、低地址

地址编号小的是低地址,地址编号大的是高地址

image-20231027003002141

2.2 什么是低位字节、高位字节

那16进制的数字0x12345678来说,它有4个字节(一个字节八位,而两个16进制的数字占位,一个字节能表示的最大数字位0xFF)

低地址    <===============   高地址

高位字节 <=============== 低位字节

 0x12       |   0x34   |   0x56   |   0x78

在大端模式下的内存存储布局为

低地址    <===============   高地址

高位字节 <=============== 低位字节

 0x12       |   0x34   |   0x56   |   0x78

在小端模式下的内存存储布局为

低地址    <===============   高地址

高位字节 <=============== 低位字节

 0x78       |   0x56   |   0x34   |   0x12

3. 举例

3.1 代码

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

import static io.netty.buffer.ByteBufUtil.appendPrettyHexDump;
import static io.netty.util.internal.StringUtil.NEWLINE;


public class TestEndian {
    
    public static void main(String[] args) {
        ByteBuf buffer = Unpooled.buffer();
        // 大端写入
        buffer.writeInt(0x12345678);
        log(buffer);

        ByteBuf buffer2 = Unpooled.buffer();
        // 小端写入
        buffer2.writeIntLE(0x12345678);  
        log(buffer2);
    }
    
    /**
     * 显示数据在ByteBuf中的存储接口1
     * @param buffer ByteBuf
     */
    private static void log(ByteBuf buffer){
        int length=buffer.readableBytes();
        int rows=length/16+(length%15==0?0:1)+4;
        StringBuilder buf=new StringBuilder(rows*80*2)
                .append("read index:").append(buffer.readerIndex())
                .append(" write index:").append(buffer.writerIndex())
                .append(" capacity:").append(buffer.capacity())
                .append(NEWLINE);
        appendPrettyHexDump(buf,buffer);
        System.out.println(buf.toString());
    }
}

3.2 控制台结果

read index:0 write index:4 capacity:256
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 12 34 56 78                                     |.4Vx            |
+--------+-------------------------------------------------+----------------+
read index:0 write index:4 capacity:256
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 78 56 34 12                                     |xV4.            |
+--------+-------------------------------------------------+----------------+

控制台中,0,1,2,3,4,...,f,代表从低地址到高地址,第二行可以看到:

  • 大端写入时,高位字节位存放在内存的低地址端低位字节存放在内存的高地址端
  • 小端写入时,低位字节位存放在内存的低地址端高位字节存放在内存的高地址端