package com.yanzuoguang.util.helper; import com.yanzuoguang.util.exception.CodeException; /** * 通信格式转换 * <p> * Java和一些windows编程语言如c、c++、delphi所写的网络程序进行通讯时,需要进行相应的转换 高、低字节之间的转换 * windows的字节序为低字节开头 linux,unix的字节序为高字节开头 java则无论平台变化,都是高字节开头 * @author 颜佐光 */ public class ByteHelper { /** * 每个字节所占用的字符串的长度 */ public static final int BYTE_STRING_SIZE = 2; /** * 16进制转换标识 */ public static final int BYTE_HEX_UNIT = 16; /** * 10进制转换单位 */ public static final int BYTE_TEN_UNIT = 10; /** * BCD标识 */ public static final int BCD_MAX_FLAG = 100; // --------------------------------------- toLH ------------------------------------- /** * 将 long 值转成低字节在前,高字节在后的byte数组 * * @param n 需要转换的值 * @param max 字节最大长度 * @return 转换后的数据 */ public static byte[] toLH(long n, int max) { byte[] b = new byte[max]; for (int i = 0; i < max; i++) { int offset = i * 8; b[i] = (byte) (n >> offset & 0xff); } return b; } /** * 将 long 值转成低字节在前,高字节在后的byte数组 * * @param n 需要转换的值 * @return 转换后的数据 */ public static byte[] toLH(long n) { return toLH(n, 8); } /** * 将int转为低字节在前,高字节在后的byte数组 * * @param n 需要转换的数据 * @return 转换后的数据 */ public static byte[] toLH(int n) { return toLH(n, 4); } /** * 将short转为低字节在前,高字节在后的byte数组 * * @param n 需要转换的数据 * @return 转换后的数据 */ public static byte[] toLH(short n) { return toLH(n, 2); } /** * 将float转为低字节在前,高字节在后的byte数组 * * @param f 需要转换的数据 * @return 转换后的数据 */ public static byte[] toLH(float f) { return toLH(Float.floatToRawIntBits(f)); } // --------------------------------------- toHL ------------------------------------- /** * 将 long 值转成高字节在前,低字节在后的byte数组 * * @param n 需要转换的值 * @param max 字节最大长度 * @return 转换后的数据 */ public static byte[] toHL(long n, int max) { byte[] b = new byte[max]; for (int i = 0; i < max; i++) { int offset = (max - 1 - i) * 8; b[i] = (byte) (n >> offset & 0xff); } return b; } /** * 将 long 值转成高字节在前,低字节在后的byte数组 * * @param n 需要转换的值 * @return 转换后的数据 */ public static byte[] toHL(long n) { return toHL(n, 8); } /** * 将int转为高字节在前,低字节在后的byte数组 * * @param n 需要转换的值 * @return 转换后的数据 */ public static byte[] toHL(int n) { return toHL(n, 4); } /** * 将short转为高字节在前,低字节在后的byte数组 * * @param n 需要转换的值 * @return 转换后的数据 */ public static byte[] toHL(short n) { return toHL(n, 2); } /** * 将float转为高字节在前,低字节在后的byte数组 * * @param f 需要转换的值 * @return 转换后的数据 */ public static byte[] toHL(float f) { return toHL(Float.floatToRawIntBits(f)); } // --------------------------------------- byLH ------------------------------------- /** * 将低字节转换为长整形 * * @param bytes 字节 * @param off 开始位置 * @param max 最大位置 * @return 转换后的结果 */ public static long toLongByLH(byte[] bytes, int off, int max) { long ret = 0; for (int i = 0; i < max; i++) { int b = bytes[off + i] & 0xFF; int offset = i * 8; ret |= (b << offset); } return ret; } /** * 将低字节数组转换为long * * @param b 需要转换的值 * @return 转换后的数据 */ public static long toLongByLH(byte[] b) { return toLongByLH(b, 0); } /** * 将低字节数组转换为long * * @param b 需要转换的值 * @param off 偏移位置 * @return 转换后的数据 */ public static long toLongByLH(byte[] b, int off) { return toLongByLH(b, off, 8); } /** * 将低字节数组转换为int * * @param b 需要转换的值 * @return 转换后的数据 */ public static int toIntByLH(byte[] b) { return toIntByLH(b, 0); } /** * 将低字节数组转换为int * * @param b 需要转换的值 * @param off 偏移位置 * @return 转换后的数据 */ public static int toIntByLH(byte[] b, int off) { return (int) toLongByLH(b, off, 4); } /** * 低字节数组到short的转换 * * @param b 需要转换的值 * @return 转换后的数据 */ public static short toShortByLH(byte[] b) { return toShortByLH(b, 0); } /** * 低字节数组到short的转换 * * @param b 需要转换的值 * @param off 偏移位置 * @return 转换后的数据 */ public static short toShortByLH(byte[] b, int off) { return (short) toLongByLH(b, off, 2); } /** * 低字节数组转换为float * * @param b 需要转换的值 * @return 转换后的数据 */ public static float toFloatByLH(byte[] b) { return Float.intBitsToFloat(toIntByLH(b)); } // --------------------------------------- byHL ------------------------------------- /** * 将高字节转换为长整型 * * @param bytes 字节 * @param off 开始位置 * @param max 最大位置 * @return 转换后的数据 */ public static long toLongByHL(byte[] bytes, int off, int max) { long ret = 0; for (int i = 0; i < max; i++) { int b = bytes[off + i] & 0xFF; int offset = (max - 1 - i) * 8; ret |= (b << offset); } return ret; } /** * 将高字节数组转换为long * * @param b 需要转换的值 * @return 转换后的数据 */ public static long toLongByHL(byte[] b) { return toLongByHL(b, 0); } /** * 将高字节数组转换为long * * @param b 字节 * @param off 开始位置 * @return 转换后的数据 */ public static long toLongByHL(byte[] b, int off) { return toLongByHL(b, off, 8); } /** * 将高字节数组转换为int * * @param b 字节 * @return 转换后的数据 */ public static int toIntByHL(byte[] b) { return toIntByHL(b, 0); } /** * 将高字节数组转换为int * * @param b 字节 * @param off 开始位置 * @return 转换后的数据 */ public static int toIntByHL(byte[] b, int off) { return (int) toLongByHL(b, off, 4); } /** * 高字节数组到short的转换 * * @param b 字节 * @return 转换后的数据 */ public static short toShortByHL(byte[] b) { return toShortByHL(b, 0); } /** * 高字节数组到short的转换 * * @param b 字节 * @param off 开始位置 * @return 转换后的数据 */ public static short toShortByHL(byte[] b, int off) { return (short) toLongByHL(b, off, 2); } /** * 高字节数组转换为float * * @param b 字节 * @return 转换后的数据 */ public static float toFloatByHL(byte[] b) { int i = toIntByHL(b); return Float.intBitsToFloat(i); } /** * 获取短整形的字节,高字节在前,低字节在后的byte数组 * * @param value 需要转换的数据 * @return 转换后的数据 */ public static byte[] getBytes(short value) { return toHL(value); } /** * 获取短整形的字节,高字节在前,低字节在后的byte数组 * * @param value 需要转换的数据 * @return 转换后的数据 */ public static byte[] getBytes(int value) { return toHL(value); } /** * 获取短整形的字节,高字节在前,低字节在后的byte数组 * * @param value 需要转换的数据 * @return 转换后的数据 */ public static byte[] getBytes(long value) { return toHL(value); } /** * 将byte数组中的元素倒序排列 * * @param b 需要转换的数据 * @return 转换后的数据 */ public static byte[] bytesReverseOrder(byte[] b) { int length = b.length; byte[] result = new byte[length]; for (int i = 0; i < length; i++) { result[length - i - 1] = b[i]; } return result; } /** * 将本机的 short 转换成网络上传输支持的 short ,用于多语言通讯时处理, 将 short 类型的值转换为字节序颠倒过来对应的 short 值 * * @param from 需要转换的数据 * @return 转换后的数据 */ public static short reverse(short from) { return toShortByHL(toLH(from)); } /** * 将本机的 int 转换成网络上传输支持的 int ,用于多语言通讯时处理, 将 int 类型的值转换为字节序颠倒过来对应的 int 值 * * @param from 需要转换的数据 * @return 转换后的数据 */ public static int reverse(int from) { return toIntByHL(toLH(from)); } /** * 将本机的 long 转换成网络上传输支持的 long ,用于多语言通讯时处理, 将 long 类型的值转换为字节序颠倒过来对应的 long 值 * * @param from 需要转换的数据 * @return 转换后的数据 */ public static long reverse(long from) { return toLongByHL(toLH(from)); } /** * 将本机的 float 转换成网络上传输支持的 float ,用于多语言通讯时处理, 将 float 类型的值转换为字节序颠倒过来对应的 float 值 * * @param from 需要转换的数据 * @return 转换后的数据 */ public static float reverse(float from) { return toFloatByHL(toLH(from)); } /** * 将字节数组转换为String * * @param bytes 需要转换的字节,如 [0x00,0x01] * @return 返回转换成功的字符串 如: 0001 */ public static String toHexString(byte[] bytes) { StringBuilder result = new StringBuilder(); for (byte b : bytes) { String hv = Integer.toHexString(b & 0xff); if (hv.length() < 2) { result.append(0); } result.append(hv); } return result.toString(); } /** * 将字节数组转换为String * * @param bytes 需要转换的字节,如 [0x00,0x01] * @return 返回转换成功的字符串 如: 0001 */ public static String toHexString1(byte[] bytes) { return toHexString1(bytes, 0, 0); } /** * 将字节数组转换为String * * @param bytes 需要转换的字节,如 [0x00,0x01] * @param offset 偏移量 * @param len 需要转换的长度,当为0时,则默认为整个字符串的长度 * @return 返回转换成功的字符串 如: 0001 */ public static String toHexString1(byte[] bytes, int offset, int len) { if (len == 0) { len = bytes.length; } StringBuilder sb = new StringBuilder(); for (int i = offset; i < len; i++) { byte by = bytes[i]; sb.append(String.format("%02X", by)); } return sb.toString(); } /** * 将字节数组转换为String * * @param from 需要转换的字节,如 0001 * @return 返回转换成功的字符串 如: [0x00,0x01] */ public static byte[] fromHexString(String from) { if (from == null || from.length() < 1) { return new byte[0]; } from = from.toUpperCase().replaceAll(" ", ""); int length = from.length() / 2; char[] hexChars = from.toCharArray(); byte[] d = new byte[length]; for (int i = 0; i < length; i++) { int pos = i * 2; d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); } return d; } /** * convert char to byte * * @param c char * @return byte */ private static byte charToByte(char c) { return (byte) "0123456789ABCDEF".indexOf(c); } /** * 将字节数组转换为String * * @param from 需要转换的字节,如 0001 * @return 返回转换成功的字符串 如: [0x00,0x01] */ public static byte[] fromHexString1(String from) { byte[] bytes = new byte[from.length() / BYTE_STRING_SIZE]; for (int i = 0; i < from.length() / BYTE_STRING_SIZE; i++) { int b = Integer.parseInt(from.substring(i * BYTE_STRING_SIZE, i * BYTE_STRING_SIZE + BYTE_STRING_SIZE), BYTE_HEX_UNIT); bytes[i] = (byte) b; } return bytes; } /** * 将字节转换为字节字符串。如 [0x00,0x01]转成成 00 01 * * @param bytes 需要转化的数据 * @return 转换后的数据 */ public static String logBytes(byte[] bytes) { int length = bytes.length; StringBuilder sb = new StringBuilder(length); for (byte b : bytes) { sb.append(b); sb.append(" "); } return sb.toString(); } /** * 将整形转换为BCD值 * * @param from 需要转换的整形 * @return 转换之后的值 */ public static byte toBCD(int from) { if (from >= BCD_MAX_FLAG) { throw new CodeException("整形转换成字节的PCD码必须小于100"); } byte bt = (byte) ((from / BYTE_TEN_UNIT * BYTE_HEX_UNIT) + from % BYTE_TEN_UNIT); return bt; } /** * 将BCD值转换为整形 * * @param from 需要转换的BCD值 * @return 转换之后的值 */ public static int fromBCD(byte from) { return (from / BYTE_HEX_UNIT) * BYTE_TEN_UNIT + from % BYTE_HEX_UNIT; } }