import javax.xml.bind.DatatypeConverter;import java.util.Arrays;import java.util.Base64;public final class BytesHub { private static final char[] HEX_CODE = "0123456789ABCDEF".toCharArray(); private final byte[] bytes; BytesHub(byte[] bytes) { this.bytes = bytes.clone(); } public static BytesHub fromBase64(String baseStr) { return new BytesHub(Base64.getDecoder().decode(baseStr)); } public static BytesHub fromHex(byte[] bytes) { return new BytesHub(bytes); } public static BytesHub fromHexStr(String hexStr) { hexStr = hexStr.toLowerCase(); byte[] bytes = DatatypeConverter.parseHexBinary(hexStr); return new BytesHub(bytes); } public static BytesHub fromPrettyHexStr(String hexStr) { hexStr = hexStr.toLowerCase(); hexStr = hexStr.replaceAll("[^0-9a-f]", ""); byte[] bytes = DatatypeConverter.parseHexBinary(hexStr); return new BytesHub(bytes); } public byte[] toHex() { return bytes.clone(); } public String printHexBinary(byte[] data, String separator) { if (data == null || data.length == 0) { return ""; } StringBuilder r = new StringBuilder(data.length * 2); r.append(HEX_CODE[(data[0] >> 4) & 0xF]); r.append(HEX_CODE[(data[0] & 0xF)]); for (int i = 1; i < data.length; i++) { r.append(separator); r.append(HEX_CODE[(data[i] >> 4) & 0xF]); r.append(HEX_CODE[(data[i] & 0xF)]); } return r.toString(); } public String toHexUpperStr() { return printHexBinary(bytes, "").toUpperCase(); } public String toHexLowerStr() { return printHexBinary(bytes, "").toLowerCase(); } public String toHexPrettyUpperStr() { return printHexBinary(bytes, " ").toUpperCase(); } public String toHexPrettyLowerStr() { return printHexBinary(bytes, " ").toLowerCase(); } public String toHexPrettyUpperStr(String separator) { return printHexBinary(bytes, separator).toUpperCase(); } public String toHexPrettyLowerStr(String separator) { return printHexBinary(bytes, separator).toLowerCase(); } public String toBase64() { return Base64.getEncoder().encodeToString(bytes); } public BytesHub append(BytesHub bytesHub) { return append(bytesHub.toHex()); } public BytesHub append(byte[] bs) { int length = this.bytes.length; int newLength = length + bs.length; byte[] newBs = Arrays.copyOf(this.bytes, newLength); System.arraycopy(bs, 0, newBs, length, bs.length); return new BytesHub(newBs); } public BytesHub append(BytesHub... bytesHubs) { int newLength = this.bytes.length; for (BytesHub bytesHub : bytesHubs) { newLength += bytesHub.bytes.length; } byte[] newBs = Arrays.copyOf(this.bytes, newLength); int index = this.bytes.length; for (BytesHub bytesHub : bytesHubs) { byte[] bs = bytesHub.bytes; System.arraycopy(bs, 0, newBs, index, bs.length); index += bs.length; } return new BytesHub(newBs); }}