Newer
Older
casic-robot-inspection / casic-server / src / main / java / com / casic / missiles / netty / ByteUtil.java
casic_zt on 10 Nov 2023 14 KB 中子源协议设备调试修改
package com.casic.missiles.netty;

import org.springframework.stereotype.Component;

@Component
public class ByteUtil {

    /* BCD码转换为数值或字符 */

    /**
     * 单一字节中选择指定位bcd码转换为整数
     * 如ByteUtil.bcdToInt((byte) 0x33, 5, 4) = 3
     *
     * @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;
        if (b2 < 0 || b2 >= 10) {
            return -1;
        }
        return b2;
    }

    /**
     * bcd码转换为整数 错误则返回-1
     * 如ByteUtil.bcdToInt((byte) 0x73) = 73
     *
     * @param b 输入字节,默认4位一组,先高后低
     * @return
     */
    public static int bcdToInt(byte b) {
        int pl = 0x0f;
        int ph = 0xf0;

        int h = (ph & b) >> 4;
        int l = (pl & b);

        if (h >= 10 || l >= 10) {
            return -1;
        }
        return h * 10 + l;
    }

    /**
     * bcd码转换为long型整数
     * 如字节数组{0x25, 0x23}转换为2523
     *
     * @param
     * @return
     */
    public static long bcdToLong(byte[] bytes) {
        if (ByteUtil.bcdToString(bytes).equals("") == false)
            return Long.valueOf(ByteUtil.bcdToString(bytes)).longValue();
        else
            return -1;
    }


    /**
     * bcd码转换为字符串 按字节顺序 高位在前低位在后
     * 如字节数组{0x01, 0x02, 0x03}转换为"010203"
     *
     * @param bytes
     * @return
     */
    public static String bcdToString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < bytes.length; i++) {
            if (ByteUtil.bcdToInt(bytes[i], 7, 4) != -1 && ByteUtil.bcdToInt(bytes[i], 3, 0) != -1) {
                sb.append(ByteUtil.bcdToInt(bytes[i], 7, 4));
                sb.append(ByteUtil.bcdToInt(bytes[i], 3, 0));
            }
        }

        return sb.toString();
    }


    /* BIN码转换为数值或字符 */

    /**
     * 单一字节中选择指定位bin码转换为整数
     * 如ByteUtil.binToInt((byte) 0xA3, 7, 7) = 1
     *
     * @param b
     * @param highBit 高位,最大7
     * @param lowBit  低位,从0开始
     * @return
     */
    public static int binToInt(byte b, int highBit, int lowBit) throws RuntimeException {
        int g = highBit - lowBit + 1;
        int a = ((int) Math.pow(2, g) - 1) << lowBit;
        int b2 = (b & a) >> lowBit;
        if (b2 < 0 || b2 >= 16) {
            throw new RuntimeException();
        }
        return b2;
    }

    /**
     * BIN字节转换为整数
     * 如ByteUtil.bcdToInt((byte) 0x7B) = 123
     *
     * @param b
     * @return
     */
    public static int binToInt(byte b) {
        int i1 = 0x80 & b;
        if (i1 == 0x80) {
            int i2 = 0x7f & b;
            return 128 + i2;
        } else {
            return b;
        }
    }

    /**
     * BIN码转换为整数 高位在前低位在后
     * 如ByteUtil.bcdToInt(new byte[] {(byte) 0x7B, 0x22}) = 31522
     *
     * @param bytes
     * @return
     */
    public static int binToInt(byte[] bytes) {
        int i10 = 0;
        if (null != bytes && bytes.length != 0) {
            for (int i = 0; i < bytes.length; i++) {
                i10 = i10 + new Double(Math.pow(16, (bytes.length - i - 1) * 2)).intValue() * ByteUtil.binToInt(bytes[i]);
            }
        }
        return i10;
    }

    /**
     * BIN码转换为LONG型整数 高位在前低位在后
     * 如ByteUtil.bcdToLong(new byte[] {(byte) 0x7B, 0x22, 0x32, 0x9A}) = 2065838746
     *
     * @param bytes
     * @return
     */
    public static int binToLong(byte[] bytes) {
        int l10 = 0;
        if (null != bytes && bytes.length != 0) {
            for (int i = 0; i < bytes.length; i++) {
                l10 = l10 + new Double(Math.pow(16, (bytes.length - i - 1) * 2)).intValue() * ByteUtil.binToInt(bytes[i]);
            }
        }
        return l10;
    }

    /**
     * 字节数组转换为16进制字符串 按字节数组顺序转换
     * 如字节数组{0x21, 0x06, 0x01, 0x04, 0x40, (byte) 0xE2, 0x01}转换为"2106010440E201"
     *
     * @param bytes
     * @return
     */
    public static String binToHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < bytes.length; i++) {
            sb.append(Integer.toHexString(binToInt((byte) ((bytes[i] & 0xf0) >> 4))).toUpperCase());
            sb.append(Integer.toHexString(binToInt((byte) (bytes[i] & 0x0f))).toUpperCase());
        }

        return sb.toString();
    }


    /**
     * BIN输出为二进制字符串
     * 如字节数组{0x01, 0x38}转换为字符串"0000000100111000"
     *
     * @param bytes
     * @return
     */
    public static String binToBinString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < bytes.length; i++) {
            String s = Integer.toBinaryString(binToInt(bytes[i]));
            while (s.length() < 8) {
                s = "0" + s;
            }
            sb.append(s);
        }

        return sb.toString();
    }


    /* int转换为BCD码或BIN码 */

    /**
     * 两位整数转换成一个字节的BCD码
     * 大于100的整数取其十位和个位 十位在前个位在后
     * 如79转换为0x79
     *
     * @param i
     * @return
     */
    public static byte intToBcd(int i) {
        byte b = 0x00;
        while (i > 99) {
            i = i % 100;
        }

        int l = i % 10;
        int h = i / 10;

        b = (byte) (h << 4 | l);

        return b;
    }

    /**
     * 整数转换为字节数组 高位在前低位在后
     * 如 2379转换为0x23, 0x79
     *
     * @param i
     * @return
     */
    public static byte[] intToBcds(long l) {
        String str = String.valueOf(l);
        Bytes bytes = new Bytes();

        if (str.length() % 2 == 1) {
            str = "0" + str;
        }

        for (int i = 0; i < str.length() - 1; i = i + 2) {
            String s = str.substring(i, i + 2);
            bytes.append(ByteUtil.intToBcd(Integer.parseInt(s)));
        }

        return bytes.toBytes();
    }

    /**
     * 整数转换为指定字节数的BCD码数组 高位在前低位在后 从低位开始计算长度 超出部分忽略 不足部分在高位补0
     * 如 3013479指定2字节转换为0x34, 0x79, 指定6字节转换为0x00, 0x00, 0x03, 0x01, 0x34, 0x79
     *
     * @param i
     * @param length
     * @return
     */
    public static byte[] intToBcds(long l, int length) {
        byte[] bts = intToBcds(l);
        if (bts.length == length) {
            return bts;
        } else {
            byte[] bytes = new byte[length];
            for (int j = length - 1; j >= 0; j--) {
                if (j + bts.length - length >= 0) {
                    bytes[j] = bts[j + bts.length - length];
                } else {
                    bytes[j] = 0x00;
                }
            }

            return bytes;
        }
    }

    /**
     * 整数转换为指定字节数的BCD码数组 低位在前高位在后 从低位开始计算长度 超出部分忽略 不足部分在高位补0
     * 如 3013479指定2字节转换为0x79, 0x34, 指定6字节转换为0x79, 0x34, 0x01, 0x03, 0x00, 0x00
     *
     * @param i
     * @param length
     * @return
     */
    public static byte[] intToBcdsHL(long l, int length) {
        Bytes bs = new Bytes();

        for (int i = 0; i < length; i++) {
            int low = (int) (l % 100);
            bs.append(ByteUtil.intToBcd(low));
            l = l / 100;
        }

        return bs.toBytes();
    }

    /**
     * 整数转换为BIN码字节数组 高位在前低位在后
     * 如113479转换为0x01, 0xBB, 0x47
     *
     * @param l
     * @return
     */
    public static byte[] intToBins(long l) {
        String str = Long.toHexString(l);
        if (str.length() % 2 == 1) {
            str = "0" + str;
        }

        Bytes bytes = new Bytes();
        for (int i = 0; i < str.length() - 1; i = i + 2) {
            String s = str.substring(i, i + 2);
            bytes.append((byte) Integer.parseInt(s, 16));
        }

        return bytes.toBytes();
    }

    /**
     * 整数转换为指定字节数的BIN码数组 高位在前低位在后 从低位开始计算长度 超出部分忽略 不足部分在高位补0
     * 如 3013479指定2字节转换为0xFB, 0x67, 指定6字节转换为0x00, 0x00, 0x00, 0x2D, 0xFB, 0x67
     *
     * @param l
     * @param length
     * @return
     */
    public static byte[] intToBins(long l, int length) {
        byte[] bts = intToBins(l);
        if (bts.length == length) {
            return bts;
        } else {
            byte[] bytes = new byte[length];
            for (int j = length - 1; j >= 0; j--) {
                if (j + bts.length - length >= 0) {
                    bytes[j] = bts[j + bts.length - length];
                } else {
                    bytes[j] = 0x00;
                }
            }

            return bytes;
        }
    }


    /* 16进制字符串转换为字节数组 */

    /**
     * 16进制字符串顺序转换为字节数组
     * 如字符串"13810411703"转换为字节数组{0x01, 0x38, 0x10, 0x41, 0x17, 0x03}
     *
     * @param str
     * @return
     */
    public static byte[] hexStringToBytes(String str) {
        if (str.length() % 2 == 1) {
            str = "0" + str;
        }

        Bytes bytes = new Bytes();
        for (int i = 0; i < str.length() - 1; i = i + 2) {
            String s = str.substring(i, i + 2);
            bytes.append((byte) Integer.parseInt(s, 16));
        }

        return bytes.toBytes();
    }

    /**
     * 16进制字符串顺序转换为指定字节数的BIN码数组 从低位开始计算长度 超出部分忽略 不足部分在高位补0
     * 如字符串"13810411703"转换为3字节数组{0x41, 0x17, 0x03}, 指定8字节转换为{0x00, 0x00, 0x01, 0x38, 0x10, 0x41, 0x17, 0x03}
     *
     * @param str
     * @param length
     * @return
     */
    public static byte[] hexStringToBytes(String str, int length) {
        byte[] bts = hexStringToBytes(str);
        if (bts.length == length) {
            return bts;
        } else {
            byte[] bytes = new byte[length];
            for (int j = length - 1; j >= 0; j--) {
                if (j + bts.length - length >= 0) {
                    bytes[j] = bts[j + bts.length - length];
                } else {
                    bytes[j] = 0x00;
                }
            }

            return bytes;
        }
    }


    /* 十进制BCD码字符串转换为字节数组 */

    /**
     * 十进制BCD码字符串顺序转换为字节数组
     * 如字符串"13810411703"转换为字节数组{0x01, 0x38, 0x10, 0x41, 0x17, 0x03}
     *
     * @param str
     * @return
     */
    public static byte[] bcdStringToBytes(String str) {
        if (str.length() % 2 == 1) {
            str = "0" + str;
        }

        Bytes bytes = new Bytes();
        for (int i = 0; i < str.length() - 1; i = i + 2) {
            String s = str.substring(i, i + 2);
            bytes.append(ByteUtil.intToBcd(Integer.parseInt(s)));
        }

        return bytes.toBytes();
    }

    /**
     * 十进制BCD码字符串顺序转换为指定字节数的BCD码数组 从低位开始计算长度 超出部分忽略 不足部分在高位补0
     * 如字符串"13810411703"转换为3字节数组{0x41, 0x17, 0x03}, 指定8字节转换为{0x00, 0x00, 0x01, 0x38, 0x10, 0x41, 0x17, 0x03}
     *
     * @param str
     * @param length
     * @return
     */
    public static byte[] bcdStringToBytes(String str, int length) {
        byte[] bts = bcdStringToBytes(str);
        if (bts.length == length) {
            return bts;
        } else {
            byte[] bytes = new byte[length];
            for (int j = length - 1; j >= 0; j--) {
                if (j + bts.length - length >= 0) {
                    bytes[j] = bts[j + bts.length - length];
                } else {
                    bytes[j] = 0x00;
                }
            }

            return bytes;
        }
    }

    public static String buildCRC16(byte[] data) {
        byte[] buf = new byte[data.length];// 存储需要产生校验码的数据
        for (int i = 0; i < data.length; i++) {
            buf[i] = data[i];
        }
        int len = buf.length;
        int crc = 0xFFFF;//16位
        for (int pos = 0; pos < len; pos++) {
            if (buf[pos] < 0) {
                crc ^= (int) buf[pos] + 256; // XOR byte into least sig. byte of
                // crc
            } else {
                crc ^= (int) buf[pos]; // XOR byte into least sig. byte of crc
            }
            for (int i = 8; i != 0; i--) { // Loop over each bit
                if ((crc & 0x0001) != 0) { // If the LSB is set
                    crc >>= 1; // Shift right and XOR 0xA001
                    crc ^= 0xA001;
                } else
                    // Else LSB is not set
                    crc >>= 1; // Just shift right
            }
        }
        String c = Integer.toHexString(crc);
        if (c.length() == 4) {
            c = c.substring(2, 4) + c.substring(0, 2);
        } else if (c.length() == 3) {
            c = "0" + c;
            c = c.substring(2, 4) + c.substring(0, 2);
        } else if (c.length() == 2) {
            c = "0" + c.substring(1, 2) + "0" + c.substring(0, 1);
        }
        return c;
    }


    public static byte[] byteMergerAll(byte[]... values) {
        int length_byte = 0;
        for (int i = 0; i < values.length; i++) {
            length_byte += values[i].length;
        }
        byte[] all_byte = new byte[length_byte];
        int countLength = 0;
        for (int i = 0; i < values.length; i++) {
            byte[] b = values[i];
            System.arraycopy(b, 0, all_byte, countLength, b.length);
            countLength += b.length;
        }
        return all_byte;
    }

    public static String convertToHex(String str) {
        char[] charArray = str.toCharArray();
        String hexString = "";
        for (char c : charArray) {
            hexString += Integer.toHexString((int) c);
        }
        return hexString;
    }

    public static String reverseHex(String hex) {
        char[] charArray = hex.toCharArray();
        int length = charArray.length;
        int times = length / 2;
        for (int c1i = 0; c1i < times; c1i += 2) {
            int c2i = c1i + 1;
            char c1 = charArray[c1i];
            char c2 = charArray[c2i];
            int c3i = length - c1i - 2;
            int c4i = length - c1i - 1;
            charArray[c1i] = charArray[c3i];
            charArray[c2i] = charArray[c4i];
            charArray[c3i] = c1;
            charArray[c4i] = c2;
        }
        return new String(charArray);
    }

}