Files
jsowell-charger-web/jsowell-common/src/main/java/com/jsowell/common/util/BytesUtil.java
2024-07-08 11:06:11 +08:00

754 lines
18 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.jsowell.common.util;
import com.google.common.primitives.Bytes;
import com.jsowell.common.constant.Constants;
import org.springframework.mail.MailMessage;
import javax.xml.bind.DatatypeConverter;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date;
import java.util.Stack;
public class BytesUtil {
static final long fx = 0xffl;
/**
* 将int数值转换为占两个字节的byte数组本方法适用于(高位在前,低位在后)的顺序。
*/
public static byte[] intToBytes(int value) {
//limit 传入2
return intToBytes(value, 2);
}
public static byte[] intToBytes(int value, int limit) {
byte[] src = new byte[limit];
for (int i = 0; i < limit; i++) {
int x = 8 * (limit - i - 1);
if (x == 0) {
src[i] = (byte) (value & 0xFF);
} else {
src[i] = (byte) ((value >> x) & 0xFF);
}
}
return src;
}
public static int bytesToInt(byte[] src) {
return bytesToInt(src, 0);
}
/**
* byte数组中取int数值本方法适用于(低位在后,高位在前)的顺序。
*/
public static int bytesToInt(byte[] src, int offset) {
if (src == null) {
return 0;
}
while (src.length > 0 && src[0] == 0x00) {
src = BytesUtil.copyBytes(src, 1, src.length - 1);
}
if (src.length == 0) {
return 0;
}
int len = src.length;
if (len == 0) {
return 0;
}
int value = 0;
for (int i = 0; i < len; i++) {
if (i == (len - 1)) {
value = value | ((src[i] & 0xFF));
}
value = value | ((src[i] & 0xFF) << (8 * (len - i - 1)));
}
return value;
}
/**
* long转字节大端模式
*
* @param number
* @return
*/
public static byte[] long2Byte(long number) {
long temp = number;
byte[] b = new byte[8];
for (int i = (b.length - 1); i >= 0; i--) {
b[i] = new Long(temp & 0xff).byteValue();//
//将最低位保存在最低位
temp = temp >> 8;// 向右移8位
}
return b;
}
/**
* 字节转long 大端模式
*
* @param b
* @return
*/
public static long byte2Long(byte[] b) {
long s = 0;
long s0 = b[7] & 0xff;
long s1 = b[6] & 0xff;
long s2 = b[5] & 0xff;
long s3 = b[4] & 0xff;
long s4 = b[3] & 0xff;
long s5 = b[2] & 0xff;
long s6 = b[1] & 0xff;
long s7 = b[0] & 0xff;
// s0不变
s1 <<= 8;
s2 <<= 16;
s3 <<= 24;
s4 <<= 8 * 4;
s5 <<= 8 * 5;
s6 <<= 8 * 6;
s7 <<= 8 * 7;
s = s0 | s1 | s2 | s3 | s4 | s5 | s6 | s7;
return s;
}
/**
* 从一个byte数组中拷贝一部分出来
*
* @param oriBytes
* @param startIndex
* @param length
* @return
*/
public static byte[] copyBytes(byte[] oriBytes, int startIndex, int length) {
int endIndex = startIndex + length;
byte[] bts = new byte[length];
int index = 0;
for (int i = 0; i < oriBytes.length; i++) {
if (i >= startIndex && i < endIndex) {
bts[index] = oriBytes[i];
index++;
}
}
return bts;
}
/**
* 将byte[]转为各种进制的字符串
*
* @param bytes byte[]
* @param radix 基数可以转换进制的范围从Character.MIN_RADIX到Character.MAX_RADIX超出范围后变为10进制
* @return 转换后的字符串
*/
public static String binary(byte[] bytes, int radix) {
return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数
}
/**
* 将byte[]转为十六进制的字符串
* @param bytes byte[]
* @return 转换后的字符串
*/
public static String printHexBinary(byte[] bytes) {
return DatatypeConverter.printHexBinary(bytes);
}
/**
* @函数功能: BCD码转为10进制串(阿拉伯数据)
* @输入参数: BCD码
* @输出结果: 10进制串
*/
public static String bcd2Str(byte[] bytes) {
StringBuffer temp = new StringBuffer(bytes.length * 2);
for (int i = 0; i < bytes.length; i++) {
temp.append((byte) ((bytes[i] & 0xf0) >>> 4));
temp.append((byte) (bytes[i] & 0x0f));
}
return temp.toString();
}
public static String bcd2StrContainA(byte[] bytes) {
char temp[] = new char[bytes.length * 2], val;
for (int i = 0; i < bytes.length; i++) {
val = (char) (((bytes[i] & 0xf0) >> 4) & 0x0f);
temp[i * 2] = (char) (val > 9 ? val + 'A' - 10 : val + '0');
val = (char) (bytes[i] & 0x0f);
temp[i * 2 + 1] = (char) (val > 9 ? val + 'A' - 10 : val + '0');
}
return new String(temp);
}
/**
* @函数功能: BCD码转为10进制串(阿拉伯数据) 小端模式
* @输入参数: BCD码
* @输出结果: 10进制串
*/
public static String bcd2StrLittle(byte[] bytes) {
Stack<String> strings = new Stack<>();
String temp = bcd2Str(bytes);
for (int i = 0; i < temp.length(); i = i + 2) {
strings.push(temp.substring(i, i + 2));
}
StringBuilder stringBuilder = new StringBuilder();
while (!strings.isEmpty()) {
stringBuilder.append(strings.pop());
}
return stringBuilder.toString();
}
/**
* @函数功能: BCD码转为10进制串(阿拉伯数据) 小端模式
* @输入参数: BCD码
* @输出结果: 10进制串
*/
public static String bcd2StrLittleContainA(byte[] bytes) {
Stack<String> strings = new Stack<>();
String temp = bcd2StrContainA(bytes);
for (int i = 0; i < temp.length(); i = i + 2) {
strings.push(temp.substring(i, i + 2));
}
StringBuilder stringBuilder = new StringBuilder();
while (!strings.isEmpty()) {
stringBuilder.append(strings.pop());
}
return stringBuilder.toString();
}
/**
* @函数功能: 10进制串转为BCD码
* @输入参数: 10进制串
* @输出结果: BCD码
*/
public static byte[] str2Bcd(String asc) {
if (asc == null) {
asc = "";
}
int len = asc.length();
int mod = len % 2;
if (mod != 0) {
asc = "0" + asc;
len = asc.length();
}
byte abt[] = new byte[len];
if (len >= 2) {
len = len / 2;
}
byte bbt[] = new byte[len];
abt = asc.getBytes();
int j, k;
for (int p = 0; p < asc.length() / 2; p++) {
if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {
j = abt[2 * p] - '0';
} else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {
j = abt[2 * p] - 'a' + 0x0a;
} else {
j = abt[2 * p] - 'A' + 0x0a;
}
if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {
k = abt[2 * p + 1] - '0';
} else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {
k = abt[2 * p + 1] - 'a' + 0x0a;
} else {
k = abt[2 * p + 1] - 'A' + 0x0a;
}
int a = (j << 4) + k;
byte b = (byte) a;
bbt[p] = b;
}
return bbt;
}
/**
* @函数功能: 10进制串转为BCD码
* @输入参数: 10进制串
* @输出结果: BCD码
*/
public static byte[] str2BcdLittle(String asc) {
byte[] temp = str2Bcd(asc);
return revert(temp);
}
/**
* 将int转为byte 小端模式
*
* @param value int值
* @return
*/
public static byte[] intToBytesLittle(int value) {
//limit 传入2
return intToBytes(value, 2);
}
/**
* 将int转换byte 小端模式
*
* @param value int值
* @param limit 保留长度
* @return
*/
public static byte[] intToBytesLittle(int value, int limit) {
byte[] src = new byte[limit];
for (int i = 0; i < limit; i++) {
int x = 8 * i;
if (x == 0) {
src[i] = (byte) (value & 0xFF);
} else {
src[i] = (byte) ((value >> x) & 0xFF);
}
}
return src;
}
/**
* byte数组中取int数值本方法适用于(低位在前,高位在后 )的顺序。小端模式
*/
public static int bytesToIntLittle(byte[] src) {
if (src == null) {
return 0;
}
int len = src.length;
if (len == 0) {
return 0;
}
int value = 0;
for (int i = 0; i < len; i++) {
value = value | ((src[i] & 0xFF) << (8 * i));
}
return value;
}
/**
* long转字节小端模式
*
* @param number
* @param limit 保留字节位
* @return
*/
public static byte[] long2ByteLittle(long number, int limit) {
long temp = number;
byte[] b = new byte[limit];
for (int i = 0; i < b.length; i++) {
b[i] = new Long(temp & 0xff).byteValue();//
//将最低位保存在最前面
temp = temp >> 8;// 向右移8位
}
return b;
}
/**
* 字节转long 小端模式
*
* @param src
* @return
*/
public static long byte2LongLittle(byte[] src) {
long s = 0;
for (int i = 0; i < src.length; i++) {
//防止转为int
long si = src[i] & 0xFF;
si = si << (8 * i);
s = s | si;
}
return s;
}
/**
* 使用字节数组替换目标数组从指定位置开始替换字节
*
* @param target 被替换的数组
* @param startIndex 开始位置
* @param replace 用于替换的数组
*/
public static void replaceBytes(byte[] target, int startIndex, byte[] replace) {
// 暂时由外界保证不会出数组越界的异常
for (int i = 0; i < replace.length; i++) {
int targetIndex = startIndex + i;
target[targetIndex] = replace[i];
}
}
/**
* 创建数组
*
* @param bytes 用于替换的数组
*/
public static byte[] createByteArray(byte... bytes) {
byte[] temp = new byte[bytes.length];
for (int i = 0; i < bytes.length; i++) {
temp[i] = bytes[i];
}
return temp;
}
public static byte[] rightPadBytes(byte[] target, int len, byte b) {
int length = target.length;
if (len <= length) {
return target;
}
int addedLen = len - length;
byte[] added = new byte[addedLen];
for (int i = 0; i < addedLen; i++) {
added[i] = b;
}
return Bytes.concat(target, added);
}
public static byte[] rightPadBytes(String targetStr, int len, byte b) {
if (targetStr == null) {
targetStr = "";
}
byte[] target = targetStr.getBytes();
return rightPadBytes(target, len, b);
}
/**
* ASCII转字符串 小端模式
* @param ascs
* @return
*/
public static String ascii2StrLittle(byte[] ascs) {
byte[] data = revert(ascs);
String asciiStr = null;
try {
asciiStr = new String(data, "ISO8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return asciiStr;
}
/**
* ASCII转字符串
* @param ascs
* @return
*/
public static String ascii2Str(byte[] ascs) {
byte[] data = ascs;
String asciiStr = null;
try {
asciiStr = new String(data, "ISO8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return asciiStr;
}
/**
* 字符串转ASCII 小端模式
* @param str
* @return
*/
public static byte[] str2AscLittle(String str) {
return revert(str2Asc(str));
}
/**
* 字符串转ASCII
* @param str
* @return
*/
public static byte[] str2Asc(String str) {
byte[] bytes = null;
try {
bytes = str.getBytes("ISO8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return bytes;
}
/**
* 反转byte数组
*
* @param temp
* @return
*/
public static byte[] revert(byte[] temp) {
byte[] ret = new byte[temp.length];
for (int i = 0; i < temp.length; i++) {
ret[temp.length - i - 1] = temp[i];
}
return ret;
}
/**
* cp56time2a 格式转date格式
*/
public static Date byteCp2Date(byte[] bytes) {
if (bytes == null || bytes.length != 7) {
return null;
}
int ms = bytesToIntLittle(copyBytes(bytes, 0, 2));
int min = bytesToIntLittle(copyBytes(bytes, 2, 1));
int hour = bytesToIntLittle(copyBytes(bytes, 3, 1));
int day = bytesToIntLittle(copyBytes(bytes, 4, 1));
int month = bytesToIntLittle(copyBytes(bytes, 5, 1));
int year = bytesToIntLittle(copyBytes(bytes, 6, 1));
if (month == 0 || day == 0 || year == 0) {
return null;
}
LocalDateTime localDateTime = LocalDateTime.of(year + 2000, month, day, hour, min, ms / 1000);
Date date = DateUtils.localDateTime2Date(localDateTime);
return date;
}
private static String hexStr = "0123456789ABCDEF";
private static String[] binaryArray = {
"0000", "0001", "0010", "0011",
"0100", "0101", "0110", "0111",
"1000", "1001", "1010", "1011",
"1100", "1101", "1110", "1111"
};
/**
* @param bArray
* @return 二进制数组转换为二进制字符串 2-2
*/
public static String bytes2BinStr(byte[] bArray) {
String outStr = "";
int pos = 0;
for (byte b : bArray) {
//高四位
pos = (b & 0xF0) >> 4;
outStr += binaryArray[pos];
//低四位
pos = b & 0x0F;
outStr += binaryArray[pos];
}
return outStr;
}
/**
* @param bytes
* @return 将二进制数组转换为十六进制字符串 2-16
*/
public static String bin2HexStr(byte[] bytes) {
String result = "";
String hex = "";
for (byte aByte : bytes) {
//字节高4位
hex = String.valueOf(hexStr.charAt((aByte & 0xF0) >> 4));
//字节低4位
hex += String.valueOf(hexStr.charAt(aByte & 0x0F));
result += hex; //+" "
}
return result;
}
/**
* @param hexString
* @return 将十六进制转换为二进制字节数组 16-2
*/
public static byte[] hexStr2BinArr(String hexString) {
//hexString的长度对2取整作为bytes的长度
int len = hexString.length() / 2;
byte[] bytes = new byte[len];
byte high = 0;//字节高四位
byte low = 0;//字节低四位
for (int i = 0; i < len; i++) {
//右移四位得到高位
high = (byte) ((hexStr.indexOf(hexString.charAt(2 * i))) << 4);
low = (byte) hexStr.indexOf(hexString.charAt(2 * i + 1));
bytes[i] = (byte) (high | low);//高地位做或运算
}
return bytes;
}
/**
* 十六进制字符串 转 bytes数组
* @param src 16进制字符串
* @return 字节数组
* @Title hexString2Bytes
* @Description 16进制字符串转字节数组
*/
public static byte[] hexString2Bytes(String src) {
if (src.startsWith(Constants.HEX_PREFIX)) {
src = StringUtils.replace(src, Constants.HEX_PREFIX, "");
}
int l = src.length() / 2;
byte[] ret = new byte[l];
for (int i = 0; i < l; i++) {
ret[i] = (byte) Integer.valueOf(src.substring(i * 2, i * 2 + 2), 16).byteValue();
}
return ret;
}
/**
* @param hexString
* @return 将十六进制转换为二进制字符串 16-2
*/
public static String hexStr2BinStr(String hexString) {
return bytes2BinStr(hexStr2BinArr(hexString));
}
/**
* 校验数据长度是否达到要求,如果够长,就直接返回,如果不够,则在数据 后补0 直至到达该长度
*
* @param msg byte类型数组
* @parm length 需要检验的数据长度(为实际字节数)
*/
public static byte[] checkLengthAndBehindAppendZero(byte[] msg, int length) {
String s = BytesUtil.binary(msg, 16);
int msgLen = s.length();
if (msgLen < length) {
while (msgLen < length) {
StringBuffer sb = new StringBuffer();
// 后补零
sb.append(s).append("0");
s = sb.toString();
msgLen = s.length();
}
} else {
return msg;
}
return BytesUtil.str2Bcd(s);
}
/**
* 校验数据长度是否达到要求,如果够长,就直接返回,如果不够,则在数据 前补0 直至到达该长度
*
* @param msg byte类型数组
* @parm length 需要检验的数据长度(为实际字节数)
*/
public static byte[] checkLengthAndFrontAppendZero(byte[] msg, int length) {
String s = BytesUtil.binary(msg, 16);
int msgLen = msg.length;
if (msgLen < length) {
while (msgLen < length) {
StringBuffer sb = new StringBuffer();
// 前补零
sb.append("0").append(s);
s = sb.toString();
msgLen = s.length();
}
} else {
return msg;
}
return BytesUtil.str2Bcd(s);
}
/**
* 确保byte数组长度至少为指定长度不足则在末尾补充0。
*
* @param bytes 原始byte数组
* @param length 指定的最小长度
* @return 补充0后确保长度至少为指定长度的byte数组
*/
public static byte[] ensureLength(byte[] bytes, int length) {
if (bytes.length < length) {
// 创建一个新的byte数组长度为指定长度前面填充原数组的元素后面补充0
byte[] newArray = new byte[length];
System.arraycopy(bytes, 0, newArray, 0, bytes.length);
return newArray;
}
// 如果原数组长度已经达到或超过指定长度,则直接返回原数组
return bytes;
}
/**
* 确保byte数组长度至少为指定长度不足则在前面补充0。
*
* @param bytes 原始byte数组
* @param length 指定的最小长度
* @return 补充0后确保长度至少为指定长度的byte数组不足部分在前面补充
*/
public static byte[] ensureLengthPrependZero(byte[] bytes, int length) {
if (bytes.length < length) {
// 创建一个新的byte数组长度为指定长度前面补充0后面放置原数组的元素
byte[] newArray = new byte[length];
System.arraycopy(bytes, 0, newArray, length - bytes.length, bytes.length);
return newArray;
}
// 如果原数组长度已经达到或超过指定长度,则直接返回原数组
return bytes;
}
/**
* 将金额转换成BCD数组
*
* @param bigDecimal
* @return
*/
// public static byte[] bigDecimal2Bcd(BigDecimal bigDecimal) {
// int i = Float.floatToIntBits(bigDecimal.floatValue());
// String hexString = Integer.toHexString(i);
// return hexString2Bytes(hexString);
//
// }
/**
* int 转 byte[]
* 小端
*
* @param data
* @return
*/
public static byte[] getIntBytes(int data) {
int length = 4;
byte[] bytes = new byte[length];
for (int i = 0; i < length; i++) {
bytes[i] = (byte) ((data >> (i * 8)) & fx);
}
return bytes;
}
/**
* float 转 byte[]
* 小端
*
* @param data
* @return
*/
public static byte[] getFloatBytes(float data) {
int intBits = Float.floatToIntBits(data);
byte[] bytes = getIntBytes(intBits);
return bytes;
}
/**
* byte[] 转 int
*
* @param bytes
* @return
*/
public static int getInt(byte[] bytes) {
int result = (int) ((fx & bytes[0])
| ((fx & bytes[1]) << 8)
| ((fx & bytes[2]) << 16)
| ((fx & bytes[3]) << 24));
return result;
}
/**
* byte[] 转 float
*
* @param b
* @return
*/
public static float getFloat(byte[] b) {
int l = getInt(b);
return Float.intBitsToFloat(l);
}
/**
* 将String转换为byte[]
*
* @param s String
* @return byte[]
*/
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
}
return data;
}
}