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.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 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 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); } 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; } 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; } public static void main(String[] args) { String vin1 = "SAITER00000000001"; byte[] bytes = str2Asc(vin1); String s = ascii2Str(bytes); System.out.println(s); } public static byte[] str2AscLittle(String str) { return revert(str2Asc(str)); } 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; } }