天天看點

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

大端小端模式

一、什麼是大小端模式

大端模式,是指資料的高位元組儲存在記憶體的低位址中,而資料的低位元組儲存在記憶體的高位址中,這樣的存儲模式有點兒類似于把資料當作字元串順序處理:位址由小向大增加,而資料從高位往低位放;這和我們的閱讀習慣一緻。

小端模式,是指資料的高位元組儲存在記憶體的高位址中,而資料的低位元組儲存在記憶體的低位址中。

舉個例子:

以 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));
    }

}