天天看点

大端小端模式大端小端模式

大端小端模式

一、什么是大小端模式

大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。

小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。

举个例子:

以 unsigned int value = 0x12345678来表示,unsigned char buf[4]存放。

Big-Endian: 低地址存放高位,如下:
   高地址
  ---------------
  buf[3] (0x78) -- 低位
  buf[2] (0x56)
  buf[1] (0x34)
  buf[0] (0x12) -- 高位
  ---------------
  低地址
  
Little-Endian: 低地址存放低位,如下:
   高地址
  ---------------
  buf[3] (0x12) -- 高位
  buf[2] (0x34)
  buf[1] (0x56)
  buf[0] (0x78) -- 低位
  --------------
低地址

           

举个例子:

java中的大小端转换

import java.util.Arrays;

class Test {

    public static void main(String[] args) {
        int a = 10;
        
        byte[] little = intToByteLittle(a);
        byte[] big = intToByteBig(a);
        
        System.out.println("little:"+ Arrays.toString(little)); // [10, 0, 0, 0]
        System.out.println("big:"+ Arrays.toString(big)); // [0, 0, 0, 10]
    }

    /**
     * 将int转为低字节在前,高字节在后的byte数组(小端)
     *
     * @param n int
     * @return byte[]
     */
    public static byte[] intToByteLittle(int n) {
        byte[] b = new byte[4];
        b[0] = (byte) (n & 0xff);
        b[1] = (byte) (n >> 8 & 0xff);
        b[2] = (byte) (n >> 16 & 0xff);
        b[3] = (byte) (n >> 24 & 0xff);
        return b;
    }

    /**
     * 将int转为高字节在前,低字节在后的byte数组(大端)
     *
     * @param n int
     * @return byte[]
     */
    public static byte[] intToByteBig(int n) {
        byte[] b = new byte[4];
        b[3] = (byte) (n & 0xff);
        b[2] = (byte) (n >> 8 & 0xff);
        b[1] = (byte) (n >> 16 & 0xff);
        b[0] = (byte) (n >> 24 & 0xff);
        return b;
    }
}

           

二、为什么要有大小端

这个问题没有定论,就像汽车的方向盘有在左边的,也有在右边的。

三、大小端与什么有关?

编程语言和大小端没有关系,影响大小端的是

编译器

/

CPU

Android 是大端还是小端?

上面讲过,CPU和编译器才是影响大端小端的关键,Android系统的碎片化,也说不好Android是大端还是小端。

有必要知道它是大端还是小端吗? 没有必要。

传一个字节会变吗? 不会。

因为在数据转换的过程中就已经指定了是以大端还是小端的规则,相应的,如果传输给其它硬件或者后台,只需要按此规则解析即可。

三、Java 转换大小端的工具类

package com.demo.my.ble_client.utils;

import java.util.Arrays;

public class ByteUtils {

    /**
     * 两个byte[]是否相同
     * @param data1
     * @param data2
     * @return
     */
    public static boolean arrayEquals(byte[] data1, byte[] data2) {
        return Arrays.equals(data1, data2);
    }

    /**
     * 截取byte[]
     * @param data
     * @param position
     * @param length
     * @return
     */
    public static byte[] subArray(byte[] data, int position, int length) {
        byte[] temp = new byte[length];
        System.arraycopy(data, position, temp, 0, length);
        return temp;
    }

    /**
     * 解决java中byte输出可能为负数的问题。
     * @param b
     * @return
     */
    public static Integer byteToInteger(Byte b) {
        return 0xff & b;
    }

    /**
     * 拼接byte[] 和 byte[]
     *
     * @param bytes1
     * @param bytes2
     * @return
     */
    public static byte[] byteMerger(byte[] bytes1, byte[] bytes2) {
        byte[] bytes3 = new byte[bytes1.length + bytes2.length];
        System.arraycopy(bytes1, 0, bytes3, 0, bytes1.length);
        System.arraycopy(bytes2, 0, bytes3, bytes1.length, bytes2.length);
        return bytes3;
    }

    /**
     * 拼接byte 和 byte[]
     *
     * @param byte1
     * @param bytes2
     * @return
     */
    public static byte[] byteMerger(byte byte1, byte[] bytes2) {
        byte[] bytes3 = new byte[1 + bytes2.length];
        bytes3[0] = byte1;
        System.arraycopy(bytes2, 0, bytes3, 1, bytes2.length);
        return bytes3;
    }

    /**
     * 拼接byte[] 和 byte
     *
     * @param bytes1
     * @param byte2
     * @return
     */
    public static byte[] byteMerger(byte[] bytes1, byte byte2) {
        byte[] bytes3 = new byte[1 + bytes1.length];
        System.arraycopy(bytes1, 0, bytes3, 0, bytes1.length);
        bytes3[bytes3.length - 1] = byte2;
        return bytes3;
    }

    /**
     * 拼接三个数组
     *
     * @param bt1
     * @param bt2
     * @param bt3
     * @return
     */
    public static byte[] byteMerger3(byte[] bt1, byte[] bt2, byte[] bt3) {
        byte[] data = new byte[bt1.length + bt2.length + bt3.length];
        System.arraycopy(bt1, 0, data, 0, bt1.length);
        System.arraycopy(bt2, 0, data, bt1.length, bt2.length);
        System.arraycopy(bt3, 0, data, bt1.length + bt2.length, bt3.length);
        return data;
    }


    /**
     * Byte[] 与 int 互转
     * =============================================================================================
     */

    /**
     * 将int转为高字节在前,低字节在后的byte数组(大端)
     *
     * @param n int
     * @return byte[]
     */
    public static byte[] intToByteBig(int n) {
        byte[] b = new byte[4];
        b[3] = (byte) (n & 0xff);
        b[2] = (byte) (n >> 8 & 0xff);
        b[1] = (byte) (n >> 16 & 0xff);
        b[0] = (byte) (n >> 24 & 0xff);
        return b;
    }

    /**
     * 将int转为低字节在前,高字节在后的byte数组(小端)
     *
     * @param n int
     * @return byte[]
     */
    public static byte[] intToByteLittle(int n) {
        byte[] b = new byte[4];
        b[0] = (byte) (n & 0xff);
        b[1] = (byte) (n >> 8 & 0xff);
        b[2] = (byte) (n >> 16 & 0xff);
        b[3] = (byte) (n >> 24 & 0xff);
        return b;
    }


    /**
     * byte数组到int的转换(小端)
     *
     * @param bytes
     * @return
     */
    public static int bytes2IntLittle(byte[] bytes) {
        int int1 = bytes[0] & 0xff;
        int int2 = (bytes[1] & 0xff) << 8;
        int int3 = (bytes[2] & 0xff) << 16;
        int int4 = (bytes[3] & 0xff) << 24;

        return int1 | int2 | int3 | int4;
    }

    /**
     * byte数组到int的转换(大端)
     *
     * @param bytes
     * @return
     */
    public static int bytes2IntBig(byte[] bytes) {
        int int1 = bytes[3] & 0xff;
        int int2 = (bytes[2] & 0xff) << 8;
        int int3 = (bytes[1] & 0xff) << 16;
        int int4 = (bytes[0] & 0xff) << 24;

        return int1 | int2 | int3 | int4;
    }


    /**
     * Byte[] 与 short 互转
     * =============================================================================================
     */

    /**
     * 将short转为高字节在前,低字节在后的byte数组(大端)
     *
     * @param n short
     * @return byte[]
     */
    public static byte[] shortToByteBig(short n) {
        byte[] b = new byte[2];
        b[1] = (byte) (n & 0xff);
        b[0] = (byte) (n >> 8 & 0xff);
        return b;
    }

    /**
     * 将short转为低字节在前,高字节在后的byte数组(小端)
     *
     * @param n short
     * @return byte[]
     */
    public static byte[] shortToByteLittle(short n) {
        byte[] b = new byte[2];
        b[0] = (byte) (n & 0xff);
        b[1] = (byte) (n >> 8 & 0xff);
        return b;
    }


    /**
     * 读取小端byte数组为short
     *
     * @param b
     * @return
     */
    public static short byteToShortLittle(byte[] b) {
        return (short) (((b[1] << 8) | b[0] & 0xff));
    }

    /**
     * 读取大端byte数组为short
     *
     * @param b
     * @return
     */
    public static short byteToShortBig(byte[] b) {
        return (short) (((b[0] << 8) | b[1] & 0xff));
    }

    /**
     * Byte[] 与 long 互转
     * =============================================================================================
     */

    /**
     * long类型转byte[] (大端)
     *
     * @param n
     * @return
     */
    public static byte[] longToBytesBig(long n) {
        byte[] b = new byte[8];
        b[7] = (byte) (n & 0xff);
        b[6] = (byte) (n >> 8 & 0xff);
        b[5] = (byte) (n >> 16 & 0xff);
        b[4] = (byte) (n >> 24 & 0xff);
        b[3] = (byte) (n >> 32 & 0xff);
        b[2] = (byte) (n >> 40 & 0xff);
        b[1] = (byte) (n >> 48 & 0xff);
        b[0] = (byte) (n >> 56 & 0xff);
        return b;
    }

    /**
     * long类型转byte[] (小端)
     *
     * @param n
     * @return
     */
    public static byte[] longToBytesLittle(long n) {
        byte[] b = new byte[8];
        b[0] = (byte) (n & 0xff);
        b[1] = (byte) (n >> 8 & 0xff);
        b[2] = (byte) (n >> 16 & 0xff);
        b[3] = (byte) (n >> 24 & 0xff);
        b[4] = (byte) (n >> 32 & 0xff);
        b[5] = (byte) (n >> 40 & 0xff);
        b[6] = (byte) (n >> 48 & 0xff);
        b[7] = (byte) (n >> 56 & 0xff);
        return b;
    }

    /**
     * byte[]转long类型(小端)
     *
     * @param array
     * @return
     */
    public static long bytesToLongLittle(byte[] array) {
        return ((((long) array[0] & 0xff) << 0)
                | (((long) array[1] & 0xff) << 8)
                | (((long) array[2] & 0xff) << 16)
                | (((long) array[3] & 0xff) << 24)
                | (((long) array[4] & 0xff) << 32)
                | (((long) array[5] & 0xff) << 40)
                | (((long) array[6] & 0xff) << 48)
                | (((long) array[7] & 0xff) << 56));
    }

    /**
     * byte[]转long类型(大端)
     *
     * @param array
     * @return
     */
    public static long bytesToLongBig(byte[] array) {
        return ((((long) array[0] & 0xff) << 56)
                | (((long) array[1] & 0xff) << 48)
                | (((long) array[2] & 0xff) << 40)
                | (((long) array[3] & 0xff) << 32)
                | (((long) array[4] & 0xff) << 24)
                | (((long) array[5] & 0xff) << 16)
                | (((long) array[6] & 0xff) << 8)
                | (((long) array[7] & 0xff) << 0));
    }

}