定义
要想搞懂大小端,首先得明白大小端的定义,以下是百度的定义
下面以unsigned int value = 0x12345678为例,分别看看在两种字节序下其存储情况,我们可以用unsigned char buf[4]来表示value
Big-Endian: 低地址存放高位,如下:
1 2 3 4 5 6
| 高地址 buf[3] (0x78) -- 低位 buf[2] (0x56) buf[1] (0x34) buf[0] (0x12) -- 高位 低地址
|
Little-Endian: 低地址存放低位,如下:
1 2 3 4
| buf[3] (0x12) -- 高位 buf[2] (0x34) buf[1] (0x56) buf[0] (0x78) -- 低位
|
所谓的大端模式(Big-endian),是指数据的高字节,保存在内存的低地址中,而数据的低字节,保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;
所谓的小端模式(Little-endian),是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。
工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
public static int byteArray2BigInt(byte[] b) { int intValue = 0; for (int i = 0; i < b.length; i++) { intValue += (b[i] & 0xFF) << (8 * (3 - i)); } return intValue; }
public static int byteArray2LittleInt(byte[] b){ int initValue = 0; for (int i = 0; i < b.length; i++){ initValue += (b[i] & 0xFF) << (8 * i); } return initValue; }
public static byte[] int2ByteArrayBig(int iValue){ byte[] b = new byte[4]; for (int i = 0; i < b.length; i++){ b[3-i] = (byte)((iValue >> (8 * i)) & 0xFF); } return b; }
public static byte[] int2ByteArrayLittle(int iValue){ byte[] b = new byte[4]; for (int i = 0; i < b.length; i++){ b[i] = (byte)((iValue >> (8 * i)) & 0xFF); } return b; }
|
断点调试
1 2 3 4 5 6 7
| int a = 257;
byte[] bytes = ParseUtils.int2ByteArrayBig(a); byte[] bytes1 = ParseUtils.int2ByteArrayLittle(a);
int i = ParseUtils.byteArray2BigInt(bytes); int i1 = ParseUtils.byteArray2LittleInt(bytes1);
|
工业报文
Java由于int 4个字节。很多工业数据都是16进制报文,用1个字节或者2个字节表示int。所以做此记录.
先上个工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| package com.ud.ruleengine.utils;
import java.math.BigInteger;
public class ParseUtils {
public static byte[] subBytes(byte[] src, int begin, int count) { byte[] bs = new byte[count]; System.arraycopy(src, begin, bs, 0, count); return bs; }
public static String binary(byte[] bytes, int radix){ return new BigInteger(1, bytes).toString(radix); } }
|
base64解析工具
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| package com.ud.ruleengine.utils;
import java.io.IOException; import java.util.Base64;
public class Base64Encrypt {
static Base64.Decoder decoder = Base64.getDecoder(); static Base64.Encoder encoder = Base64.getEncoder();
public static String encode(byte[] bstr) { return encoder.encodeToString(bstr); }
public static byte[] decode(String str) { byte[] bt = null; try { bt = decoder.decode(str); } catch (Exception e) { e.printStackTrace(); }
return bt; } }
|
假设6个字段分别是212212个字节,int值,那么我们的解析为:
1 2 3 4 5 6 7 8
| byte[] decode = Base64Encrypt.decode(data);
String a1 = ParseUtils.binary(ParseUtils.subBytes(decode, 0, 2), 10); String a2 = ParseUtils.binary(ParseUtils.subBytes(decode,2,1), 10); String a3 = ParseUtils.binary(ParseUtils.subBytes(decode,3,2), 10); String a4 = ParseUtils.binary(ParseUtils.subBytes(decode,5,2), 10); String a5 = ParseUtils.binary(ParseUtils.subBytes(decode,7,1), 10); String a6 = ParseUtils.binary(ParseUtils.subBytes(decode,8,2), 10);
|