[Java SE] 字节操作工具类:ByteUtils

0 引言

  • 与嵌入式软件数据交互过程中,必然涉及各种的、大量的字节操作场景。如:16进制与10进制、2进制间的转换,字符串、byte数组与int之间的转换等。故此有此核心工具类的沉淀。

1 ByteUtils

依赖

<properties>
	<!-- 编程提效工具 -->
	<lombok.version>1.18.22</lombok.version>

	<!-- 日志 -->
	<slf4j.version>1.7.25</slf4j.version>
	<log4j.version>2.20.0</log4j.version>

	<!-- 其他依赖 -->
	<commons.lang3.version>3.9</commons.lang3.version>
	<commons.io.version>2.11.0</commons.io.version>
	<commons.codec.version>1.13</commons.codec.version>
</properties>	

<dependencies>
	<!-- language enhance / 语言增强 | start -->
	<dependency>
		<groupId>org.projectlombok</groupId>
		<artifactId>lombok</artifactId>
		<version>${lombok.version}</version>
		<scope>provided</scope>
	</dependency>

	<dependency>
		<groupId>org.apache.commons</groupId>
		<artifactId>commons-lang3</artifactId>
		<version>${commons.lang3.version}</version>
		<scope>provided</scope>
	</dependency>

	<dependency>
		<groupId>commons-io</groupId>
		<artifactId>commons-io</artifactId>
		<version>${commons.io.version}</version>
		<scope>compile</scope>
	</dependency>

	<dependency>
		<groupId>commons-codec</groupId>
		<artifactId>commons-codec</artifactId>
		<version>${commons.codec.version}</version>
		<scope>provided</scope>
	</dependency>
	<!-- language enhance / 语言增强 | end -->


	<!-- log | start -->
	<dependency>
		<groupId>org.slf4j</groupId>
		<artifactId>slf4j-api</artifactId>
		<version>${slf4j.version}</version>
		<scope>provided</scope>
	</dependency>
	<dependency>
		<groupId>org.apache.logging.log4j</groupId>
		<artifactId>log4j-api</artifactId>
		<version>${log4j.version}</version>
		<scope>provided</scope>
	</dependency>
	<dependency>
		<groupId>org.apache.logging.log4j</groupId>
		<artifactId>log4j-core</artifactId>
		<version>${log4j.version}</version>
		<scope>provided</scope>
	</dependency>
	<!-- this dependency is required for data desensitization -->
	<dependency>
		<groupId>org.apache.logging.log4j</groupId>
		<artifactId>log4j-slf4j-impl</artifactId>
		<version>${log4j.version}</version>
		<scope>provided</scope>
	</dependency>
	<!-- log | end -->
</dependencies>

ByteUtils

package com.xxx.bigdata.poc.utils.bytes;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.bind.DatatypeConverter;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * 字节操作工具类
 # @description 与嵌入式软件数据交互过程中,必然涉及各种的、大量的字节操作场景。如:16进制与10进制、2进制间的转换,字符串、byte数组与int之间的转换等,故此有此核心工具类的沉淀。
 * @version v1.0
 * @create-time 2022/12/23 18:18
 * @description ...
 */
@Slf4j
public class BytesUtils {
    private static final Logger logger = LoggerFactory.getLogger(BytesUtils.class);

    /**
     * 单个字节的位长
     * 1byte = 8 bit
     * 1个16进制位 占 4 bit => 1个字节可代表 2 个 16进制位, 1 个16进制位 = 0.5 个字节
     **/
    public final static int BYTE_BIT_LENGTH = 8;

    /**
     * 字节转二进制字符串
     * @note
     *  单个字节 : 'a' => 97 => 0x61 => 01100001 (二进制) | 兼容 : 无符号数、有符号数
     *      byteToBit( (byte) 0x61 ) = "01100001"
     *  单个字节 : 250 => 0xFA = 11111010 (二进制) | 无符号数
     *      byteToBit( (byte) 0xFA ) = "11111010"
     * @param b
     * @return
     */
    public static String byteToBinaryString(byte b) {
        return "" +
                (byte) ((b >> 7) & 0x1) +
                (byte) ((b >> 6) & 0x1) +
                (byte) ((b >> 5) & 0x1) +
                (byte) ((b >> 4) & 0x1) +
                (byte) ((b >> 3) & 0x1) +
                (byte) ((b >> 2) & 0x1) +
                (byte) ((b >> 1) & 0x1) +
                (byte) ((b >> 0) & 0x1);
    }

    /**
     * 十六进制字符串 转 二进制字符串
     * @note
     *  hexStringToBinaryString( "61" ) = "01100001" | 'a' => 97 => 0x61 => "01100001"
     *  hexStringToBinaryString( "FA" ) = "11111010"
     *  hexStringToBinaryString( "48656c6c6f" ) = "0100100001100101011011000110110001101111"
     *      即 "01001000 01100101 01101100 01101100 01101111"
     * @param hexString
     * @return
     */
    public static String hexStringToBinaryString(String hexString) {
        byte[] bytes = hexStringToBytes(hexString);
        StringBuilder s = new StringBuilder(64);
        for (byte aByte : bytes) {
            s.append(BytesUtils.byteToBinaryString(aByte));
        }
        return s.toString();
    }
    /**
    public static String hexStringToBinaryString(String hexString){
        if(ObjectUtils.isEmpty(hexString) || hexString.length()%2 != 0){
            return "";
        }
        StringBuilder binaryString = new StringBuilder();
        String tmp;
        for(int i=0;i<hexString.length(); i++){
            tmp = "0000" + Integer.toBinaryString( Integer.parseInt(hexString.substring(i, i+1), 16) );
            binaryString.append( tmp.substring( tmp.length() -4 ) );

            //String binary = Integer.toBinaryString(Integer.parseInt(hexString.charAt(i) + "", 16));
            //binaryBuilder.append(String.format("%4s", binary).replace(' ', '0')); // 格式化为4位二进制数
        }

        logger.info("hexString : {}, binaryString : {}", hexString, binaryString);
        return binaryString.toString();
    }
    **/

    /**
     * 字节数组转十六进制表示的字符串
     * @note
     *  'H' => 72 => 0x48 ; 'e' => 101 => 0x65
     *  bytesToString(new byte[] { 0x48, 0x65 }) = "4865"
     * @param byteArray
     * @return
     */
    public static String bytesToHexString(byte[] byteArray) {
        StringBuilder builder = new StringBuilder();
        if (byteArray == null || byteArray.length <= 0) {
            return null;
        }
        String hv;
        for (int i = 0; i < byteArray.length; i++) {
            // 以十六进制(基数 16)无符号整数形式返回一个整数参数的字符串表示形式,并转换为大写
            hv = Integer.toHexString(byteArray[i] & 0xFF);
            if (hv.length() < 2) {
                builder.append(0);
            }
            builder.append(hv);
        }
        return builder.toString();
    }
    /**
    public static String bytesToHexString(byte[] byteArray) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (byteArray != null) {
            for (int i = 0; i < byteArray.length; ++i) {
                stringBuilder.append( byteToHexString(byteArray[i]) );
            }
        }
        return stringBuilder.toString();
    }
    **/

    /**
     * 字符串转字节数组
     * @note
     *  stringToBytes("Hello World", Charset.forName("UTF-8")) => [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
     *  stringToBytes("娃哈哈", Charset.forName("UTF-8")) => [-27, -88, -125, -27, -109, -120, -27, -109, -120]
     * @param text
     * @return
     */
    public static byte [] stringToBytes(String text, Charset charset){
        if(ObjectUtils.isEmpty(text)){
            throw new RuntimeException("text is empty! text : " + text);
        }
        return charset==null?text.getBytes():text.getBytes(charset);
    }

    /**
     * (多字节的)二进制字符串转二进制数组
     * @note <p>需了解本方法的局限性</p>
     *  <p>单个字节的二进制字符串 必须满足 java byte(8bit、有符号数) 的取值范围 [-128, 127]</p>
     *  <p>正确示例: binaryStringToBytes("01001000") => out: [72]</p>
     *  <p>错误示例: binaryStringToBytes("11111010") => 0xFA = 250 = 0b1111 0b00001010" => out: [-6] (错误结果,因:超出有符号数byte取值范围)</p>
     * @param binaryString
     * @return
     */
    public static byte[] binaryStringToBytes(String binaryString) {
        if(ObjectUtils.isEmpty(binaryString)){
            throw new RuntimeException("Fail to convert binary array cause by the empty binary string! binaryString : " + binaryString);
        }
        if(binaryString.length() %BYTE_BIT_LENGTH != 0){//不是4的倍数
            throw new RuntimeException("Fail to convert binary array cause that the binary string is not a multiple of " + BYTE_BIT_LENGTH + "! binaryString : " + binaryString);
        }

//        char [] charArray =  binaryString.toCharArray() // string 内部由 2个字节的char组成的 char 数组 , 故: 这种转换做法有风险
//        byte [] binaryArray = new byte [ binaryString.length() ];
//        for (int i = 0; i < charArray.length; i ++) {
//            //binaryArray[i] = (byte)charArray[i]; // java char 占用 : 2个字节 ; java byte 占用 1个字节 => 这种做法不正确
//            binaryArray[i]
//        }

        int byteSize = binaryString.length()/BYTE_BIT_LENGTH;
        byte[] binaryArray = new byte[byteSize];
        for (int i = 0; i < byteSize; i ++) {
            String byteBinaryStr = binaryString.substring(i*BYTE_BIT_LENGTH, i*BYTE_BIT_LENGTH + BYTE_BIT_LENGTH);//sample "01001000"
            binaryArray[i] = binaryStringToByte(byteBinaryStr);
        }
        return binaryArray;
    }

    /**
     * (多字节的)二进制字符串转 ByteBuffer
     * @note 解决 java byte 类型仅支持有符号数 的 取值范围 [-128, 127] 的局限性 (ByteBuffer : 支持无符号数)
     * 在Java中,如果你想要处理无符号的byte数组,你可以使用ByteBuffer类,它可以以大端或小端格式读写字节。
     * 由于Java中的byte类型是有符号的,范围为-128到127,所以无符号的byte数组需要特别处理。
     * 例如:
     *      ByteBuffer buffer = ByteBuffer.allocate(5);// 创建一个包含无符号byte的ByteBuffer
     *      buffer.put((byte) 0x80); // 256的二进制补码表示为1000 0000,是一个负数 | 注意,put 方法 传入的是 byte 值,它们会以其补码形式存储。
     *      buffer.put((byte) 0xFF); // 255的二进制补码表示为1111 1111
     *      buffer.flip(); // 翻转Buffer,准备读取
     *      // 读取无符号 byte
     *      int unsignedByte1 = buffer.get() & 0xFF; // 将有符号byte转换为无符号 : 256
     *      int unsignedByte2 = buffer.get() & 0xFF; // 将有符号byte转换为无符号 : 255
     * 当我们想要读取这些值时,我们使用 get() 方法,并将得到的值与255进行"与"操作(0xFF),这样可以确保我们得到无符号的值。
     * 这种方法适用于处理单个 byte 值,如果你需要处理更大的无符号数,你可能需要多次调用get()方法,并进行适当的位操作来组成一个无符号整数。
     * @usage
     *   ByteBuffer byteBuffer = binaryStringToByteBuffer("1111101011111011");//0xFA , 0xFB
     *   byteBuffer.flip();
     *   int value1 = byteBuffer.get(0) & 0xFF;//250
     *   int value2 = byteBuffer.get(1) & 0xFF;//251
     * @param binaryString
     * @return
     */
    public static ByteBuffer binaryStringToByteBuffer(String binaryString) {
        int byteSize = binaryString.length()/BYTE_BIT_LENGTH;
        if(binaryString.length() % BYTE_BIT_LENGTH != 0){
            throw new RuntimeException("the binary string must be `" + "`'s times!");
        }

        // 创建一个包含 无符号 byte 的 ByteBuffer
        ByteBuffer buffer = ByteBuffer.allocate(byteSize);
        for(int i=0;i<byteSize;i++){
            String oneByteBinaryString =  binaryString.substring(i*BYTE_BIT_LENGTH, i*BYTE_BIT_LENGTH + BYTE_BIT_LENGTH);//sample "01001000"
            int value = oneByteBinaryStringToInt(oneByteBinaryString);
            buffer.put( (byte) value );
        }
        return buffer;
    }

    /**
     * 单字节的二进制字符串转 Int 整型
     * @sample
     *  oneByteBinaryStringToInt("1010") => out : 10 => 0xA
     *  oneByteBinaryStringToInt("11111010") => out : 250 => 0xFA
     * @param oneByteBinaryString
     * @return
     */
    public static Integer oneByteBinaryStringToInt(String oneByteBinaryString){
        Integer value = Integer.parseInt(oneByteBinaryString, 2); // 转换为十进制整数
        return value;
    }

    /**
     * 将位长为8位的二进制字符串转为 1个字节
     * @note
     *  注意避坑 : java byte 的局限性
     *      1. byte 取值范围是 [-128, +127]. Java中的 byte 数据类型是 8 位、有符号的,其取值范围是从 -128 到 127
     *      2. 基于1,入参(`binaryString`) 的取值范围 : [0b10000000(即-128) , 0b11111111(即-1)] U [0b00000000, 0b01111111]
     * @param binaryString
     *  sample "01001000" => 72 ; "01111111" => 127
     * @return
     */
    public static byte binaryStringToByte(String binaryString){
        int x = 0;// 注 : int 占用 4 个字节
        for(int j=0; j < BYTE_BIT_LENGTH; j++){
            String currentBinaryBit = binaryString.substring(BYTE_BIT_LENGTH-1-j, (BYTE_BIT_LENGTH-1-j)+1);
            x = x + Integer.parseInt( currentBinaryBit ) * ( (int) Math.pow(2, j) );//强制类型转换会直接截断小数部分
        }
        return (byte) x;
    }

    /**
     * 二进制字符串转十六进制字符串
     * @param binaryString
     * @sample binaryStringToHexString("1111101011111011") => "FAFB" (即: 0xFA, 0xFB)
     *
     */
    public static String binaryStringToHexString(String binaryString){
        byte[] binaryArray = binaryStringToBytes(binaryString);

        StringBuilder hexStr = new StringBuilder();
        int byteSize = binaryArray.length;
        for(int i=0; i< byteSize; i++){
            hexStr.append( byteToHexString( binaryArray[i] ) );
        }
        return hexStr.toString();
    }

    /**
     * char 转 byte 数组[固定2个字节]
     * @description 背景 : char类型即可以存储英文字母,也可存储汉字;汉字在java中使用Unicode编码占两个字节
     * @param c
     * @return
     * @sample
     *  charTo2Bytes('G') = [0, 71]
     *  charTo2Bytes('哇') = [84, -57]
     */
    public static byte[] charTo2Bytes(char c) {
        byte[] b = new byte[2];
        b[0] = (byte) ((c & 0xFF00) >> 8);
        b[1] = (byte) (c & 0xFF);
        return b;
    }

    /**
     * 十六进制字符串转byte数组
     * @param hexString | sample "48656c6c6f"
     * @return | sample [72, 101, 108, 108, 111] 即 [0x48, 0x65, 0x6c, 0x6c, 0x6f ] //注 : 以0x开始的数据表示16进制
     */
    /**
     * 将Hex String转换为Byte数组
     * @param hexString the hex string
     * @return the byte [ ]
     */
    public static byte[] hexStringToBytes(String hexString) {
        if (org.apache.commons.lang3.StringUtils.isBlank(hexString)) {
            return null;
        }
        //hexString = hexString.toLowerCase();
        final byte[] byteArray = new byte[hexString.length() >> 1];
        int index = 0;
        for (int i = 0; i < hexString.length(); i++) {
            if (index > hexString.length() - 1) {
                return byteArray;
            }
            byte highDit = (byte) (Character.digit(hexString.charAt(index), 16) & 0xFF);
            byte lowDit = (byte) (Character.digit(hexString.charAt(index + 1), 16) & 0xFF);
            byteArray[i] = (byte) ((highDit << 4) | (lowDit & 0xFF));
            index += 2;
        }
        return byteArray;
    }
    /**
    public static byte[] hexStringToBytes(String hexString){
        //String hexString = "48656c6c6f"; // 示例十六进制字符串 "Hello"
        byte[] byteArray = DatatypeConverter.parseHexBinary(hexString);
        return byteArray;
    }
    **/

    /**
     * 十六进制字符串转字节数组 | 方法2
     * @note 局限性 : byte 的取值范围 : [-128, 127]
     *  例如 错误的入参示范 :  hexStringToBytes("fffafb") = [-1, -6, -5] (错误结果)
     * @param hexStr
     * @return
     */
    /**
    public static byte[] hexStringToBytes(String hexStr) {
        if (!StringUtils.isEmpty(hexStr) && hexStr.length() % 2 == 0) {
            byte[] data = null;

            try {
                char[] chars = hexStr.toCharArray();
                data = Hex.decodeHex(chars);
            } catch (DecoderException var3) {
                logger.error(var3.getMessage(), var3);
            }

            return data;
        } else {
            return null;
        }
    }
    **/

    /**
     * 字节数组 转 十六进制数组字符串
     * @usage bytesToHexArrayString( new byte [] { 0x34, 0x67} ) = [0x34,0x67]
     * @param byteArray
     * @return
     */
    public static String bytesToHexArrayString(byte[] byteArray) {
        StringBuffer sb = new StringBuffer();
        sb.append("[");
        if (byteArray != null) {
            for (int i = 0; i < byteArray.length; ++i) {
                sb.append("0x").append(byteToHexString(byteArray[i]));
                if (i < byteArray.length - 1) {
                    sb.append(",");
                }
            }
        }

        sb.append("]");
        return sb.toString();
    }

    /**
     * 字节转16进制字符串
     * @sample byteToHexString( (byte)0xFA ) = "FA"
     * @param aByte
     * @return
     */
    public static String byteToHexString(byte aByte) {
        char[] digit = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        char[] tempArr = new char[]{digit[aByte >>> 4 & 15], digit[aByte & 15]};
        String s = new String(tempArr);
        return s;
    }

    /**
     * INT 转 16进制字符串
     * @param v
     * @return
     * @usage intToHexString(255) => "ff"
     */
    public static String intToHexString(int v) {
        String hexStr = Integer.toHexString(v);
        if (hexStr.length() % 2 != 0) {
            hexStr = "0" + hexStr;
        }

        return hexStr;
    }

    /**
     * 16进制转换成为文本字符串
     * @param hexString
     * @return
     * @usage
     *  1. hexStringToTextString("4861") => "Ha"
     *      即 : 0x48 , 0x61 => 71 , 97 => 'H' , 'a'
     */
    public static String hexStringToTextString(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.replace(" ", "");
        byte[] baKeyword = new byte[hexString.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(hexString.substring(i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                logger.error("Fail to convert hex string to text string cause that parse substring to int or byte!hexString:{},index:{},exception:{}", hexString, i, e);//16进制转换成为string类型字符串失败
                //e.printStackTrace();
            }
        }

        try {
            hexString = new String(baKeyword, StandardCharsets.UTF_8);
        } catch (Exception e) {
            logger.error("Fail to convert hex string to text string cause that byte to string!hexString:{},exception:{}", hexString, e);//16进制转换成为string类型字符串失败
        }
        return hexString;
    }

    /* ------------------------ 如下方法,待测验 TODO ---------------------- */

    /**
     * 从输入流中获取字节数组
     * @param in
     * @return
     */
    public static byte[] getBytes(InputStream in) {
        byte[] data = null;

        try {
            byte[] buffer = new byte[1024];

            int len;
            for (; (len = in.read(buffer)) > 0; data = addArray(data, buffer, len)) {
            }
        } catch (IOException var4) {
            logger.error(var4.getMessage(), var4);
        }

        return data;
    }

    public static byte[] addArray(byte[] source, byte[] addedAry) {
        return addArray(source, addedAry, addedAry.length);
    }

    public static byte[] addArray(byte[] source, byte[] addedAry, int availableAddedAryLength) {
        if (addedAry == null) {
            return source;
        } else {
            byte[] buf = new byte[(source == null ? 0 : source.length) + availableAddedAryLength];
            int i;
            if (source != null) {
                for (i = 0; i < source.length; ++i) {
                    buf[i] = source[i];
                }
            }

            for (i = 0; i < availableAddedAryLength; ++i) {
                buf[(source == null ? 0 : source.length) + i] = addedAry[i];
            }

            return buf;
        }
    }

    public static int contains(byte[] source, byte[] data) {
        if (source == null || data == null) { return -1; }
        if (source.length >= data.length && data.length != 0) {
            int pos = -1;
            for (int i = 0; i <= source.length - data.length; ++i) {
                boolean flag = true;
                for (int j = 0; j < data.length; ++j) {
                    if (source[i + j] != data[j]) { flag = false; }
                }
                if (flag) { pos = i; break; }
            }
            return pos;
        }
        return -1;
    }

    public static boolean startWith(byte[] source, byte[] startData) {
        if (source == null) {
            return false;
        } else if (startData == null) {
            return false;
        } else if (source.length >= startData.length && startData.length != 0) {
            boolean flag = true;

            for (int i = 0; i < startData.length; ++i) {
                if (source[i] != startData[i]) {
                    flag = false;
                    break;
                }
            }

            return flag;
        } else {
            return false;
        }
    }

    public static boolean endWith(byte[] source, byte[] endData) {
        if (source == null) {
            return false;
        } else if (endData == null) {
            return false;
        } else if (source.length >= endData.length && endData.length != 0) {
            boolean flag = true;

            for (int i = 0; i < endData.length; ++i) {
                if (source[source.length - endData.length + i] != endData[i]) {
                    flag = false;
                    break;
                }
            }

            return flag;
        } else {
            return false;
        }
    }

    public static byte[] removeStart(byte[] source, int len) {
        if (source == null) {
            return null;
        } else if (source.length < len) {
            return null;
        } else {
            byte[] buf = new byte[source.length - len];

            for (int i = 0; i < buf.length; ++i) {
                buf[i] = source[i + len];
            }

            return buf;
        }
    }

    public static byte[] removeEnd(byte[] source, int len) {
        if (source == null) {
            return null;
        } else if (source.length < len) {
            return null;
        } else {
            byte[] buf = new byte[source.length - len];

            for (int i = 0; i < buf.length; ++i) {
                buf[i] = source[i];
            }

            return buf;
        }
    }

    public static byte[] subByteArray(byte[] data, int beginIndex, int endIndex) {
        if (beginIndex < 0) {
            throw new IndexOutOfBoundsException("beginIndex must bigger than 0,but it is " + beginIndex + "");
        } else if (endIndex >= data.length) {
            throw new IndexOutOfBoundsException("endIndex must smaller than data lenght " + data.length + ",but it is " + endIndex + "");
        } else {
            byte[] buf = new byte[endIndex - beginIndex + 1];

            for (int i = beginIndex; i <= endIndex; ++i) {
                buf[i - beginIndex] = data[i];
            }

            return buf;
        }
    }

    public static byte[] remove(byte[] data, int start, int size) {
        if (data == null) {
            return null;
        } else if (start >= data.length) {
            throw new IndexOutOfBoundsException("start must smaller than data's length:'" + data.length + "',but it is " + start + "");
        } else if (start + size > data.length) {
            throw new IndexOutOfBoundsException("start+size must smaller than data's length:'" + data.length + "',but they are " + start + "+" + size + "");
        } else {
            byte[] buf = new byte[data.length - size];

            int i;
            for (i = 0; i < start; ++i) {
                buf[i] = data[i];
            }

            for (i = start + size; i < data.length; ++i) {
                buf[i - size] = data[i];
            }

            return buf;
        }
    }

    public static byte[] removeContains(byte[] source, byte[] data) {
        int pos;
        if (source == null) {
            return null;
        } else if (data == null) {
            return source;
        } else {
            if ((pos = contains(source, data)) == -1) {
                return source;
            } else if (source.length < data.length) {
                return null;
            } else {
                byte[] buf = new byte[source.length - data.length];

                int i;
                for (i = 0; i < pos; ++i) {
                    buf[i] = source[i];
                }

                for (i = pos + data.length; i < source.length; ++i) {
                    buf[i - data.length] = source[i];
                }

                return buf;
            }
        }
    }

    /** 打印二进制字符串 (每8bit,打印为1行)
     * @param bitString 字符串化的二进制字节流
     *  note : 长度必须为8的倍数(因: 1 byte = 8 bit)
     *  sample : "1011011110100011000011110000000000000000000000000000000000000000"
     * @param isEnable 是否启用本方法的日志打印
     **/
    public static String printBitString(String bitString, boolean isEnable){
        if( bitString == null || bitString.length() %8!=0){//长度必须是8的整数倍
            throw new RuntimeException("The length of input bit string must be an integer multiple of 8! bit string : " + bitString);
        }
        if(bitString == ""){//bitString == ""
            return "";
        }
        StringBuilder result = new StringBuilder();
        String bit8 = null;
        while (bitString.length() >= 8) {
            bit8 = bitString.substring(0, 8);//第 (0, 8] 位 ,共计 8 位
            result.append( String.format("                %s        : %s\n", bit8, BytesUtils.binaryStringToHexString(bit8)) );// 01111111 : 7F
            bitString = bitString.substring(8); //第 (8 , +∞) 位,递归
        }
        return result.toString();
    }
}
posted @ 2024-07-10 09:37  千千寰宇  阅读(19)  评论(0编辑  收藏  举报