package org.ts.ddcs.tool; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.security.MessageDigest; import java.util.Calendar; public class BytesHelp { /** * bcd码转int * * @param bs cbcd16进制数组 * @param off 起始位置 * @param len 长度 * @return int */ public static int cbcd2int(byte[] bs, int off, int len) { int v = 0; for (int i = off; i < (off + len); i++) { v = (v * 100) + (((bs[i] & 0xFF) >> 4) * 10) + (bs[i] & 0x0F); } return v; } /** * int转bcd码 * * @param i int数值 * @param len (bcd长度) * @return byte[] cbcd16进制数组 */ public static byte[] int2cbcd(int i, int len) { byte[] bs = new byte[len]; int temp; for (int j = len - 1; j >= 0; j--) { temp = i % 100; bs[j] = (byte) (((temp / 10) << 4) + ((temp % 10) & 0x0F)); i /= 100; } return bs; } /** * 数值类型转byte数组(long(8),int(4),short(2)) * * @param num (long,int,short) * @param len (8, 4, 2) * @return */ public static byte[] number2bytes(long num, int len) { byte[] bs = new byte[len]; for (int j = 0; j < len; j++) { bs[len - j - 1] = (byte) (num >> (j * 8)); } return bs; } /** * byte数组转short * * @param bs * @return */ public static short bytes2short(byte[] bs) { short s = (short) (bs[1] & 0xFF); s |= (bs[0] << 8) & 0xFF00; return s; } /** * short转byte数组 * * @param s * @return */ public static byte[] short2bytes(short s) { byte[] bs = new byte[2]; for (int i = 1; i >= 0; i--) { bs[i] = (byte) (s % 256); s >>= 8; } return bs; } /** * String转bcd byte数组 * * @param s * @return */ public static byte[] string2cbcd(String s) { if (s.length() % 2 != 0) { s = "0" + s; } ByteArrayOutputStream baos = new ByteArrayOutputStream(); char[] cs = s.toCharArray(); for (int i = 0; i < cs.length; i += 2) { int high = cs[i] - 48; int low = cs[i + 1] - 48; baos.write(high << 4 | low); } return baos.toByteArray(); } /** * 转数据为字符串 * @param bs * @param off * @param len * @return */ public static String getHexString(byte[] bs, int off, int len) { StringBuffer sb = new StringBuffer(); for (int i = off; i < (off + len); i++) { String hex = Integer.toHexString(bs[i] & 0xFF); if (hex.length() == 1) { sb.append('0').append(hex); } else { sb.append(hex); } // sb.append(' '); } return sb.toString(); } /** * byte数组转String * * @param bs * @param off * @param len * @return */ public static String bytes2String(byte[] bs, int off, int len) { return new String(bs, off, len).trim(); } /** * String 转 byte[] * * @param str * @param len * @return */ public static byte[] string2bytes(String str, int len) { byte[] bs; if (str != null) { bs = str.getBytes(); } else { bs = new byte[len]; } return bs; } /** * int 转 byte数组 * * @param i * @return */ public static byte[] int2Bytes(int i) { return int2Bytes(i, 4); } /** * int 转 byte数组 * * @param i * @return */ public static byte[] intToBytes(int i,int length) { return int2Bytes(i, length); } /** * int 转 byte数组 * * @param i * @param len * @return */ public static byte[] int2Bytes(int i, int len) { byte[] bs = new byte[len]; for (int j = 0; j < len; j++) { bs[len - j - 1] = (byte) (i >> (j * 8)); } return bs; } public static int byteslowbitToInt(byte[] bytes,int off){ byte[] tmpbuf = new byte[4]; tmpbuf[2] = (byte) (bytes[off] & 0x0f); tmpbuf[3] = bytes[off+1]; int v = 0; for (int ii = 0; ii < 4; ii++) { int shi = (4 - 1 - ii) * 8; v += (tmpbuf[ii] & 0x000000FF) << shi; } return v; } /** * byte数组转int(命令字专用) * * @param bytes * @return */ public static int bytes2Int(byte[] bytes, int off, int len) { int v = 0; int pos = off + len - 1; if (pos >= 0) { v |= (bytes[pos] & 0xFF); } pos--; if (pos >= 0) { v |= ((bytes[pos] << 8) & 0xFF00); } pos--; if (pos >= 0) { v |= ((bytes[pos] << 16) & 0xFF0000); } pos--; if (pos >= 0) { v |= ((bytes[pos] << 24) & 0xFF000000); } return v; } // bytes补位用 public static byte[] string2Bytes(String src, int len, int max) { byte[] dest = new byte[max]; if (src == null) { return dest; } while (src.length() < len) { src += " "; } byte[] temp = src.getBytes(); System.arraycopy(temp, 0, dest, 0, temp.length >= len ? len : temp.length); return dest; } public static byte[] getBytesFromFile(File file) { byte[] ret = null; try { if (file == null) { return null; } FileInputStream in = new FileInputStream(file); ByteArrayOutputStream out = new ByteArrayOutputStream(4096); byte[] b = new byte[4096]; int n; while ((n = in.read(b)) != -1) { out.write(b, 0, n); } in.close(); out.close(); ret = out.toByteArray(); } catch (Exception e) { return null; } return ret; } public static String getMD5Digest(String str) { return getMD5Digest(str.getBytes()); } public static String getMD5Digest(byte[] bytes) { MessageDigest messageDigest = null; try { messageDigest = MessageDigest.getInstance("MD5"); messageDigest.reset(); messageDigest.update(bytes); } catch (Exception e) { e.printStackTrace(); } byte[] byteArray = messageDigest.digest(); StringBuffer md5StrBuff = new StringBuffer(); for (int i = 0; i < byteArray.length; i++) { if (Integer.toHexString(0xFF & byteArray[i]).length() == 1) md5StrBuff.append("0").append( Integer.toHexString(0xFF & byteArray[i])); else md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i])); } return md5StrBuff.toString(); } public static String leftFill(String src, int len, char fillChar) { int length = src.length(); if (src == null || len < length) return src; String result = src; for (int i = length; i < len; i++) { result = String.valueOf(fillChar) + result; } return result; } /** * 将字符串拼接成指定长度的字符串,不足的补空格 * * @param str 字符串 * @param length * @return */ public static String spliceSpaces(String str, int length) { int strLen = str.length(); if (strLen > length) { str = ""; for (int i = 0; i < length; i++) { str += " "; } } else { for (int i = 0; i < (length - strLen); i++) { str += " "; } } return str; } /** * 将字符串拼接成指定长度的字符串,不足的补0 * * @param str 字符串 * @param length * @return */ public static String spliceZero(String str, int length) { int strLen = str.length(); if (strLen > length) { str = ""; for (int i = 0; i < length; i++) { str += "0"; } } else { for (int i = 0; i < (length - strLen); i++) { str = "0" + str; } } return str; } public static byte[] arrayApend(byte[] a, byte[] b) { int a_len = (a == null ? 0 : a.length); int b_len = (b == null ? 0 : b.length); byte[] c = new byte[a_len + b_len]; if (a_len == 0 && b_len == 0) { return null; } else if (a_len == 0) { System.arraycopy(b, 0, c, 0, b.length); } else if (b_len == 0) { System.arraycopy(a, 0, c, 0, a.length); } else { System.arraycopy(a, 0, c, 0, a.length); System.arraycopy(b, 0, c, a.length, b.length); } return c; } public static byte[] arrayApendbyte(byte[] a, byte b) { int a_len = (a == null ? 0 : a.length); byte[] c = new byte[a_len + 1]; if (a_len == 0) { return null; } else { System.arraycopy(a, 0, c, 0, a.length); System.arraycopy(b, 0, c, a.length, 1); } return c; } /** * 获取字符Ascii值 * * @param str * @return */ public static int getAsciiValue(String str) { if (str.length() != 1) { return 0; } char[] ch = str.toCharArray(); return ch[0]; } /** * 获取字符Ascii值 16 * * @param str * @return */ public static String getAsciiHexValueS(String str) { char[] ch = str.toCharArray(); StringBuffer retStr = new StringBuffer(); for (int i = 0; i < ch.length; i++) { retStr.append(Integer.toHexString(ch[i])); } return retStr.toString(); } /** * 获取字符Ascii值 * * @param str * @return */ public static String getAsciiValueS(String str) { char[] ch = str.toCharArray(); StringBuffer retStr = new StringBuffer(); for (int i = 0; i < ch.length; i++) { retStr.append((int) ch[i]); } return retStr.toString(); } public static String getAsciiStr(int d) { char e = (char) d; return e + ""; } public static String byte2HexStr(byte[] b) { String stmp = ""; StringBuilder sb = new StringBuilder(""); for (int n = 0; n < b.length; n++) { stmp = Integer.toHexString(b[n] & 0xFF); sb.append((stmp.length() == 1) ? "0" + stmp : stmp); //sb.append(" "); } return sb.toString().toUpperCase().trim(); } public static String byte2HexStr(byte[] b, int pos, int length) { String stmp = ""; StringBuilder sb = new StringBuilder(""); for (int n = 0; n < length; n++) { stmp = Integer.toHexString(b[n + pos] & 0xFF); sb.append((stmp.length() == 1) ? "0" + stmp : stmp); } return sb.toString().toUpperCase().trim(); } public static byte[] hexStr2Bytes(String hexString) { hexString = hexString.toLowerCase(); int remainder = hexString.length() % 2; if(remainder>0){ hexString ="0"+hexString; } final byte[] byteArray = new byte[hexString.length()/2]; int k = 0; for (int i = 0; i < byteArray.length; i++) { //因为是16进制,最多只会占用4位,转换成字节需要两个16进制的字符,高位在先 //将hex 转换成byte "&" 操作为了防止负数的自动扩展 // hex转换成byte 其实只占用了4位,然后把高位进行右移四位 // 然后“|”操作 低四位 就能得到 两个 16进制数转换成一个byte. // byte high = (byte) (Character.digit(hexString.charAt(k), 16) & 0xff); byte low = (byte) (Character.digit(hexString.charAt(k + 1), 16) & 0xff); byteArray[i] = (byte) (high << 4 | low); k += 2; } return byteArray; } public static byte[] subBytes(byte[] src, int begin, int count) { byte[] bs = new byte[count]; for (int i = begin; i < begin + count; i++) bs[i - begin] = src[i]; return bs; } //CRC校验运算 public static byte GetCRCByte(byte[] data) { int crc = 0x0; // 初始值为0 for (byte bt : data) { crc = crc ^ bt; for (int j = 1; j <= 8; j++) { if ((crc & 0x80) == 0x80) crc = (crc << 1) ^ 0xE5;// 多项式值为E5,被校验值左移 else crc = crc << 1; } } return (byte) crc; } //将16进制字符串转换为16进制byte数组 public static byte[] HexString2Bytes(String src) { byte[] ret = new byte[8]; byte[] tmp = src.getBytes(); for (int i = 0; i < 8; i++) { ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]); } return ret; } public static byte uniteBytes(byte src0, byte src1) { byte _b0 = Byte.decode("0x" + new String(new byte[]{src0})).byteValue(); _b0 = (byte) (_b0 << 4); byte _b1 = Byte.decode("0x" + new String(new byte[]{src1})).byteValue(); byte ret = (byte) (_b0 ^ _b1); return ret; } //16进制字符串转换为2进制字符串 public static String hexString2binaryString(String hexString) { if (hexString == null || hexString.length() % 2 != 0) return null; String bString = "", tmp; for (int i = 0; i < hexString.length(); i++) { tmp = "0000" + Integer.toBinaryString(Integer.parseInt( hexString.substring(i, i + 1), 16)); bString += tmp.substring(tmp.length() - 4); } return bString; } /** * 获取时间戳位 * * @return */ public static byte[] getTPByte() { Calendar now = Calendar.getInstance(); //String year = now.get(Calendar.YEAR)+""; String second = now.get(Calendar.SECOND) + ""; String minute = now.get(Calendar.MINUTE) + ""; String hour = now.get(Calendar.HOUR_OF_DAY) + ""; String day = now.get(Calendar.DATE) + ""; byte[] tpArea; if (second.length() == 1) { tpArea = BytesHelp.hexStr2Bytes("0" + second); } else { tpArea = BytesHelp.hexStr2Bytes(second); } if (minute.length() == 1) { tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes("0" + minute)); } else { tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes(minute)); } if (hour.length() == 1) { tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes("0" + hour)); } else { tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes(hour)); } if (day.length() == 1) { tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes("0" + day)); } else { tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes(day)); } tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes("00")); return tpArea; } /** * 单一字节中选择指定位bcd码转换为整数 * * @param b * @param highBit 高位,最大7 * @param lowBit 低位,从0开始 * @return */ public static int bcdToInt(byte b, int highBit, int lowBit) { int g = highBit - lowBit + 1; int a = ((int) Math.pow(2, g) - 1) << lowBit; int b2 = (b & a) >> lowBit; return b2; } public static byte[] crcFun2014(byte[] packet, int pos, int length) { int n = length; int crc = 0xFFFF; for (int b = 0; b < n; b++) { crc = byteToInteger(packet[pos + b]) ^ crc; for (int c = 0; c < 8; c++) { int dd = crc & 0x0001; if (dd == 1) { crc = crc >> 1; crc ^= 0xA001; } else { crc = crc >> 1; } } } return BytesHelp.int2Bytes(crc, 2); } public static byte[] crcFun2014(byte[] packet) { int n = packet.length; int crc = 0xFFFF; for (int b = 0; b < n; b++) { crc = byteToInteger(packet[b]) ^ crc; for (int c = 0; c < 8; c++) { int dd = crc & 0x0001; if (dd == 1) { crc = crc >> 1; crc ^= 0xA001; } else { crc = crc >> 1; } } } return BytesHelp.int2Bytes(crc, 2); } public static int byteToInteger(byte b) { int value; value = b & 0xff; return value; } /** * 获取发报时间 * * @return */ public static byte[] getFBTm() { Calendar now = Calendar.getInstance(); String year = now.get(Calendar.YEAR) + ""; String month = now.get(Calendar.MONTH) + 1 + ""; String day = now.get(Calendar.DATE) + ""; String hour = now.get(Calendar.HOUR_OF_DAY) + ""; String minute = now.get(Calendar.MINUTE) + ""; String second = now.get(Calendar.SECOND) + ""; byte[] tpArea; tpArea = BytesHelp.hexStr2Bytes(year.substring(2, year.length())); if (month.length() == 1) { tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes("0" + month)); } else { tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes(month)); } if (day.length() == 1) { tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes("0" + day)); } else { tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes(day)); } if (hour.length() == 1) { tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes("0" + hour)); } else { tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes(hour)); } if (minute.length() == 1) { tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes("0" + minute)); } else { tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes(minute)); } if (second.length() == 1) { tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes("0" + second)); } else { tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes(second)); } return tpArea; } //将16进制RTU编码改成10进制 public static String byte2HexMpCdStr(byte[] b) { String stmp = ""; StringBuilder sb = new StringBuilder(""); for (int n = 0; n < 3; n++) { stmp = Integer.toHexString(b[n] & 0xFF); sb.append((stmp.length() == 1) ? "0" + stmp : stmp); } int mpcd = 0; if (sb.toString().startsWith("00")) {//00开头的站点编号按照10进制处理,99的按照16进制处理,为了满足威控的编码格式 String str4 = Integer.toHexString(b[4] & 0xFF); String mpcdStr = Integer.toHexString(b[3] & 0xFF); if(str4.length()==1){ mpcdStr += "0"+str4; }else{ mpcdStr +=str4; } //String mpcdStr = Integer.toHexString(b[3] & 0xFF)+Integer.toHexString(b[4] & 0xFF); mpcd = Integer.parseInt(mpcdStr); } else { mpcd = bytes2Int(BytesHelp.subBytes(b, 3, 2), 0, 2) % 10000; } sb.append(StringUtil.leftFill(mpcd + "", 4, '0')); return sb.toString().toUpperCase().trim(); } //将16进制RTU编码改成10进制(东深厂商专用),编号最后俩个字节颠倒 public static String byte2HexMpCdStrDS(byte[] b) { String stmp = ""; StringBuilder sb = new StringBuilder(""); for (int n = 0; n < 3; n++) { stmp = Integer.toHexString(b[n] & 0xFF); sb.append((stmp.length() == 1) ? "0" + stmp : stmp); } int mpcd = 0; if (sb.toString().startsWith("00")) {//00开头的站点编号按照10进制处理,99的按照16进制处理,为了满足威控的编码格式 String mpcdStr = Integer.toHexString(b[3] & 0xFF) + Integer.toHexString(b[4] & 0xFF); mpcd = Integer.parseInt(mpcdStr); } else { byte[] mpCdTail = new byte[2]; mpCdTail[0] = b[4]; mpCdTail[1] = b[3]; //mpcd = bytes2Int( BytesHelp.subBytes(b, 3, 2),0,2) %10000; mpcd = bytes2Int(mpCdTail, 0, 2) % 10000; } sb.append(StringUtil.leftFill(mpcd + "", 4, '0')); return sb.toString().toUpperCase().trim(); } //bdcd十六进字符串转成字节数组 public static byte[] hstrToBytes(String str) { char[] ca = str.toCharArray(); byte[] databuff = new byte[ca.length / 2]; for (int j = 0; j < ca.length; j += 2) { byte bb = (byte) (charToByte(ca[j]) << 4 | charToByte(ca[j + 1])); databuff[j == 0 ? 0 : (j / 2)] = bb; } return databuff; } public static byte charToByte(char c) { return (byte) "0123456789ABCDEF".indexOf(c); } }