|
|
@@ -0,0 +1,355 @@
|
|
|
+package org.dromara.common.core.utils;
|
|
|
+
|
|
|
+
|
|
|
+import javassist.bytecode.ByteArray;
|
|
|
+import org.apache.commons.lang3.ArrayUtils;
|
|
|
+
|
|
|
+import java.io.ByteArrayOutputStream;
|
|
|
+import java.io.DataOutputStream;
|
|
|
+import java.io.IOException;
|
|
|
+import java.nio.ByteBuffer;
|
|
|
+import java.util.UUID;
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * @author ZZK
|
|
|
+ *
|
|
|
+ */
|
|
|
+public class ByteArrayUtilByYC extends ByteArray {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 转为16位无符号正数
|
|
|
+ *
|
|
|
+ * @param code:字节数组
|
|
|
+ * @param index:从哪个位置开始
|
|
|
+ * @param isLittleEndian:是否是高低位互换(true:若bytes是低位在前,那么转为整型时,要恢复为高位在前的方式)
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static int readU16bit(byte[] code, int index, boolean isLittleEndian) {
|
|
|
+
|
|
|
+ if (isLittleEndian == true)
|
|
|
+ return (code[index] & 0xff) | ((code[index + 1] & 0xff) << 8);
|
|
|
+
|
|
|
+ return ((code[index] & 0xff) << 8) | (code[index + 1] & 0xff);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 转为32位无符号整数
|
|
|
+ *
|
|
|
+ * @param code:字节数组
|
|
|
+ * @param index:从哪个位置开始
|
|
|
+ * @param isLittleEndian:是否是高低位互换(true:若bytes是低位在前,那么转为整型时,要恢复为高位在前的方式)
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static long readU32bit(byte[] code, int index, boolean isLittleEndian) {
|
|
|
+
|
|
|
+ if (isLittleEndian == true)
|
|
|
+ return ((code[index] & 0xff) | ((code[index + 1] & 0xff) << 8) | ((code[index + 2] & 0xff) << 16)
|
|
|
+ | ((code[index + 3] & 0xff) << 24)) & 0x0FFFFFFFFL; // 转为无符号32位整型
|
|
|
+
|
|
|
+ return (code[index] << 24) | ((code[index + 1] & 0xff) << 16) | ((code[index + 2] & 0xff) << 8)
|
|
|
+ | (code[index + 3] & 0xff) & 0x0FFFFFFFFL; // 转为无符号32位整型
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 转为64位整数
|
|
|
+ *
|
|
|
+ * @param code:字节数组
|
|
|
+ * @param index:从哪个位置开始
|
|
|
+ * @param isLittleEndian:是否是高低位互换(true:若bytes是低位在前,那么转为整型时,要恢复为高位在前的方式)
|
|
|
+ */
|
|
|
+ public static long read64bit(byte[] code, int index, boolean isLittleEndian) {
|
|
|
+
|
|
|
+ if (code.length != 8)
|
|
|
+ throw new IllegalArgumentException("传入数据的长度不等于8个字节。");
|
|
|
+
|
|
|
+ ByteBuffer buffer = ByteBuffer.allocate(8);
|
|
|
+
|
|
|
+ if (isLittleEndian == true) {
|
|
|
+ for (int i = code.length - 1; i >= 0; i--)
|
|
|
+ buffer.put(code[i]);
|
|
|
+ buffer.flip();
|
|
|
+ } else {
|
|
|
+ buffer.put(code, 0, code.length);
|
|
|
+ buffer.flip();
|
|
|
+
|
|
|
+ }
|
|
|
+ return buffer.getLong();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将整型数据写入为16进制数据
|
|
|
+ *
|
|
|
+ * @param value:数据
|
|
|
+ * @param code:待写入的字节数组
|
|
|
+ * @param index:起始偏移位
|
|
|
+ * @param isLittleEndian:是否是高低位互换(true:低位在前)
|
|
|
+ */
|
|
|
+ public static void write16bit(int value, byte[] code, int index, boolean isLittleEndian) {
|
|
|
+ if (isLittleEndian == true) {
|
|
|
+ code[index] = (byte) value;
|
|
|
+ code[index + 1] = (byte) (value >>> 8);
|
|
|
+ } else {
|
|
|
+ code[index] = (byte) (value >>> 8);
|
|
|
+ code[index + 1] = (byte) value;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将整型数据写入为32进制数据
|
|
|
+ *
|
|
|
+ * @param value:数据
|
|
|
+ * @param code:待写入的字节数组
|
|
|
+ * @param index:起始偏移位
|
|
|
+ * @param isLittleEndian:是否是高低位互换(true:低位在前)
|
|
|
+ */
|
|
|
+ public static void write32bit(int value, byte[] code, int index, boolean isLittleEndian) {
|
|
|
+ if (isLittleEndian == true) {
|
|
|
+ code[index] = (byte) value;
|
|
|
+ code[index + 1] = (byte) (value >>> 8);
|
|
|
+ code[index + 2] = (byte) (value >>> 16);
|
|
|
+ code[index + 3] = (byte) (value >>> 24);
|
|
|
+ } else {
|
|
|
+ code[index] = (byte) (value >>> 24);
|
|
|
+ code[index + 1] = (byte) (value >>> 16);
|
|
|
+ code[index + 2] = (byte) (value >>> 8);
|
|
|
+ code[index + 3] = (byte) value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将整型数据写入为64进制数据
|
|
|
+ *
|
|
|
+ * @param value:数据
|
|
|
+ * @param code:待写入的字节数组
|
|
|
+ * @param index:起始偏移位
|
|
|
+ * @param isLittleEndian:是否是高低位互换(true为低位在前,高位在后)
|
|
|
+ */
|
|
|
+ public static void write64bit(long value, byte[] code, int index, boolean isLittleEndian) {
|
|
|
+ ByteBuffer buffer = ByteBuffer.allocate(8);
|
|
|
+ buffer.putLong(0, value);
|
|
|
+ byte[] b = buffer.array();
|
|
|
+ if (isLittleEndian == true) // 若为ture,则进行交互先后位置
|
|
|
+ ArrayUtils.reverse(b);
|
|
|
+ code[0] = b[0];
|
|
|
+ code[1] = b[1];
|
|
|
+ code[2] = b[2];
|
|
|
+ code[3] = b[3];
|
|
|
+ code[4] = b[4];
|
|
|
+ code[5] = b[5];
|
|
|
+ code[6] = b[6];
|
|
|
+ code[7] = b[7];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 拷贝一个字节数组
|
|
|
+ *
|
|
|
+ * @param src:源数组
|
|
|
+ * @param srcPos:源起点
|
|
|
+ * @param dest:目标数组
|
|
|
+ * @param destPos:目标起点
|
|
|
+ * @param length:拷贝字节长度
|
|
|
+ */
|
|
|
+ public static void copy(byte[] src, int srcPos, byte[] dest, int destPos, int length) {
|
|
|
+ System.arraycopy(src, srcPos, dest, destPos, length);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将二进制转换成16进制
|
|
|
+ *
|
|
|
+ * 字节码转换为16进制字符串
|
|
|
+ *
|
|
|
+ * @param bytes
|
|
|
+ * @param isPrefix:是否要加入前缀0x,当为false则不加
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static String parseByte2HexStr(byte bytes[], boolean isPrefix) {
|
|
|
+ StringBuffer sb = new StringBuffer();
|
|
|
+ if (isPrefix == true)
|
|
|
+ sb.append("0x");
|
|
|
+ for (int i = 0; i < bytes.length; i++) {
|
|
|
+ String hex = Integer.toHexString(bytes[i] & 0xFF);
|
|
|
+ if (hex.length() == 1) {
|
|
|
+ hex = '0' + hex;
|
|
|
+ }
|
|
|
+ sb.append(hex.toUpperCase());
|
|
|
+ }
|
|
|
+ return sb.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将二进制转换成16进制(指定长度)
|
|
|
+ *
|
|
|
+ * @param index:起始下标
|
|
|
+ * @param length:读取的字节长度
|
|
|
+ * @param bytes:源字节数组
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static String parseByte2HexStr(byte[] bytes, int index, int length) {
|
|
|
+ StringBuffer sb = new StringBuffer();
|
|
|
+ for (int i = index; i < index + length; i++) {
|
|
|
+ String hex = Integer.toHexString(bytes[i] & 0xFF);
|
|
|
+ if (hex.length() == 1) {
|
|
|
+ hex = '0' + hex;
|
|
|
+ }
|
|
|
+ sb.append(hex.toUpperCase());
|
|
|
+ }
|
|
|
+ return sb.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将字节数组倒叙转换为16进制字符串
|
|
|
+ *
|
|
|
+ * @param bytes
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static String parseByte2HexStrByDesc(byte bytes[]) {
|
|
|
+ StringBuffer sb = new StringBuffer();
|
|
|
+ for (int i = bytes.length; i > 0; i--) {
|
|
|
+ String hex = Integer.toHexString(bytes[i - 1] & 0xFF);
|
|
|
+ if (hex.length() == 1) {
|
|
|
+ hex = '0' + hex;
|
|
|
+ }
|
|
|
+ sb.append(hex.toUpperCase());
|
|
|
+ }
|
|
|
+ return sb.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将16进制转换为二进制
|
|
|
+ *
|
|
|
+ * @param hexStr
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static byte[] parseHexStr2Byte(String hexStr) {
|
|
|
+
|
|
|
+ if (hexStr.length() < 1) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ byte[] result = new byte[hexStr.length() / 2];
|
|
|
+ for (int i = 0; i < hexStr.length() / 2; i++) {
|
|
|
+ int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
|
|
|
+ int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
|
|
|
+ result[i] = (byte) (high * 16 + low);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将16进制字符串倒叙的转换为二进制
|
|
|
+ *
|
|
|
+ * @param hexStr
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static byte[] parseHexStr2ByteByDesc(String hexStr) {
|
|
|
+ if (hexStr.length() < 1) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ byte[] result = new byte[hexStr.length() / 2];
|
|
|
+ for (int i = hexStr.length() / 2, j = 0; i > 0; i--, j++) {
|
|
|
+ int high = Integer.parseInt(hexStr.substring((i - 1) * 2, (i - 1) * 2 + 1), 16);
|
|
|
+ int low = Integer.parseInt(hexStr.substring((i - 1) * 2 + 1, (i - 1) * 2 + 2), 16);
|
|
|
+ result[j] = (byte) (high * 16 + low);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取CRC校验码值(bytes中的最后一位CRC数据传00过来)
|
|
|
+ *
|
|
|
+ * @param bytes
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static int getCRC(byte[] bytes) {
|
|
|
+ int ucCRC = 0x00;
|
|
|
+
|
|
|
+ for (int i = 0; i < bytes.length - 1; i++) {
|
|
|
+ ucCRC ^= bytes[i] & 0x0FF; // 转为无符号的byte
|
|
|
+
|
|
|
+ for (int j = 0; j < 8; j++) {
|
|
|
+ if ((ucCRC & 0x01) != 0) {
|
|
|
+ ucCRC >>= 1;
|
|
|
+ ucCRC ^= 0x8c;
|
|
|
+ } else {
|
|
|
+ ucCRC >>= 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return ucCRC;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将bytes转为uuid
|
|
|
+ *
|
|
|
+ * @param bytes
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static String uuidFromByteArray(byte[] bytes) {
|
|
|
+ ByteBuffer bb = ByteBuffer.wrap(bytes);
|
|
|
+ long high = bb.getLong();
|
|
|
+ long low = bb.getLong();
|
|
|
+ UUID uuid = new UUID(high, low);
|
|
|
+ return uuid.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将uuid转回bytes
|
|
|
+ *
|
|
|
+ * @param str
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static byte[] byteArrayFromUuid(String str) {
|
|
|
+ UUID uuid = UUID.fromString(str);
|
|
|
+ ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
|
|
|
+ bb.putLong(uuid.getMostSignificantBits());
|
|
|
+ bb.putLong(uuid.getLeastSignificantBits());
|
|
|
+
|
|
|
+ return bb.array();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将UUID转为bytes
|
|
|
+ *
|
|
|
+ * @param uuid
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static byte[] uuidToByte(UUID uuid) {
|
|
|
+ ByteArrayOutputStream ba = new ByteArrayOutputStream(16);
|
|
|
+ DataOutputStream da = new DataOutputStream(ba);
|
|
|
+ try {
|
|
|
+ da.writeLong(uuid.getMostSignificantBits());
|
|
|
+ da.writeLong(uuid.getLeastSignificantBits());
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return ba.toByteArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将byte转为二进制
|
|
|
+ *
|
|
|
+ * @param b
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static String byteToBit(byte b, boolean revers) {
|
|
|
+ String str = Integer.toBinaryString(b);
|
|
|
+ if (str.length() < 8) {
|
|
|
+ str = StringUtilsByYC.addString(String.valueOf(str), "0", 8, "L");
|
|
|
+ }
|
|
|
+ if (revers == true) {
|
|
|
+ StringBuffer sb = new StringBuffer();
|
|
|
+ for (int i = str.length() - 1; i >= 0; i--) {
|
|
|
+ sb.append(str.charAt(i));
|
|
|
+ }
|
|
|
+ str = sb.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ return str;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|