package cn.org.hentai.jtt1078.util; import cn.org.hentai.jtt1078.flv.AudioTag; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; /** * Created by matrixy on 2017/8/22. */ public final class ByteUtils { public static byte[] parse(String hexString) { String[] hexes = hexString.split(" "); byte[] data = new byte[hexes.length]; for (int i = 0; i < hexes.length; i++) data[i] = (byte)(Integer.parseInt(hexes[i], 16) & 0xff); return data; } public static synchronized void dump(byte[] data) { dump(data, data.length); } public static synchronized void dump(byte[] data, int len) { for (int i = 0, l = len; i < l && i < data.length; ) { String ascii = ""; int k = 0, f = 0; for (; k < 16 && k < data.length; k++) { if (k + i < l) { f++; byte d = data[i + k]; String hex = Integer.toHexString(d & 0xff).toUpperCase(); if (hex.length() == 1) hex = "0" + hex; if (d >= 0x20 && d < 127) ascii += (char)d; else ascii += '.'; System.out.print(hex); } else { System.out.print(' '); System.out.print(' '); } if (k % 4 == 3) System.out.print(" "); else System.out.print(' '); } i += f; System.out.println(ascii); } } public static String toString(byte[] data) { if (null == data) return ""; return toString(data, data.length); } public static String toString(byte[] buff, int length) { StringBuffer sb = new StringBuffer(length * 2); for (int i = 0; i < buff.length && i < length; i++) { if ((buff[i] & 0xff) < 0x10) sb.append('0'); sb.append(Integer.toHexString(buff[i] & 0xff).toUpperCase()); sb.append(' '); } return sb.toString(); } public static boolean getBit(int val, int pos) { return getBit(new byte[] { (byte)((val >> 0) & 0xff), (byte)((val >> 8) & 0xff), (byte)((val >> 16) & 0xff), (byte)((val >> 24) & 0xff) }, pos); } public static int reverse(int val) { byte[] bytes = toBytes(val); byte[] ret = new byte[4]; for (int i = 0; i < 4; i++) ret[i] = bytes[3 - i]; return toInt(ret); } public static byte[] toLEBytes(int val) { byte[] bytes = new byte[4]; for (int i = 0; i < 4; i++) { bytes[3 - i] = (byte)(val >> ((3 - i) * 8) & 0xff); } return bytes; } public static byte[] toLEBytes(short s) { byte[] bytes = new byte[2]; bytes[0] = (byte)(s & 0xff); bytes[1] = (byte)((s >> 8) & 0xff); return bytes; } public static int toInt(byte[] bytes) { int val = 0; for (int i = 0; i < 4; i++) val |= (bytes[i] & 0xff) << ((3 - i) * 8); return val; } public static byte[] toBytes(int val) { byte[] bytes = new byte[4]; for (int i = 0; i < 4; i++) { bytes[i] = (byte)(val >> ((3 - i) * 8) & 0xff); } return bytes; } public static byte[] toBytes(long val) { byte[] bytes = new byte[8]; for (int i = 0; i < 8; i++) { bytes[i] = (byte)(val >> ((7 - i) * 8) & 0xff); } return bytes; } public static int getInt(byte[] data, int offset, int length) { int val = 0; for (int i = 0; i < length; i++) val |= (data[offset + i] & 0xff) << ((length - i - 1) * 8); return val; } public static long getLong(byte[] data, int offset, int length) { long val = 0; for (int i = 0; i < length; i++) val |= ((long)data[offset + i] & 0xff) << ((length - i - 1) * 8); return val; } public static boolean getBit(byte[] data, int pos) { return ((data[pos / 8] >> (pos % 8)) & 0x01) == 0x01; } public static byte[] concat(byte[]...byteArrays) { int len = 0, index = 0; for (int i = 0; i < byteArrays.length; i++) len += byteArrays[i].length; byte[] buff = new byte[len]; for (int i = 0; i < byteArrays.length; i++) { System.arraycopy(byteArrays[i], 0, buff, index, byteArrays[i].length); index += byteArrays[i].length; } return buff; } public static boolean compare(byte[] data1, byte[] data2) { if (data1.length != data2.length) return false; for (int i = 0; i < data1.length; i++) if ((data1[i] & 0xff) != (data2[i] & 0xff)) return false; return true; } // 相当于(short *) byte_pointer的效果 public static short[] toShortArray(byte[] src) { short[] dst = new short[src.length / 2]; for (int i = 0, k = 0; i < src.length; ) { dst[k++] = (short)((src[i++] & 0xff) | ((src[i++] & 0xff) << 8)); } return dst; } // 相当于(char *) short_pointer的效果 public static byte[] toByteArray(short[] src) { byte[] dst = new byte[src.length * 2]; for (int i = 0, k = 0; i < src.length; i++) { dst[k++] = (byte)(src[i] & 0xff); dst[k++] = (byte)((src[i] >> 8) & 0xff); } return dst; } public static String toHexString(byte[] bytes, int offset, int length) { StringBuilder sb = new StringBuilder(length * 3); for (int i = offset; i < offset + length && i < bytes.length; i++) { sb.append(String.format("%02X ", bytes[i])); } return sb.toString().trim(); } // 可选:打印整个数组 public static String toHexString(byte[] bytes) { return toHexString(bytes, 0, bytes.length); } public static int getShort(byte[] bytes, int offset) { return ((bytes[offset] & 0xFF) << 8) | (bytes[offset + 1] & 0xFF); } public static long getLong(byte[] bytes, int offset) { return ((long)(bytes[offset] & 0xFF) << 56) | ((long)(bytes[offset + 1] & 0xFF) << 48) | ((long)(bytes[offset + 2] & 0xFF) << 40) | ((long)(bytes[offset + 3] & 0xFF) << 32) | ((long)(bytes[offset + 4] & 0xFF) << 24) | ((long)(bytes[offset + 5] & 0xFF) << 16) | ((long)(bytes[offset + 6] & 0xFF) << 8) | ((long)(bytes[offset + 7] & 0xFF)); } /** * Flv 音频封装编码 * * @param audioTag 音频tag * @return 字节流 * @author xingkong * @date 2021-09-07 17:02 */ public static ByteBuf encode(AudioTag audioTag) throws Exception { ByteBuf buffer = Unpooled.buffer(); if (audioTag == null) { return buffer; } //----------------------tag header begin------- buffer.writeByte(8); buffer.writeMedium(audioTag.getTagDataSize()); buffer.writeMedium(audioTag.getOffSetTimestamp() & 0xFFFFFF); buffer.writeByte(audioTag.getOffSetTimestamp() >> 24); buffer.writeMedium(audioTag.getStreamId()); //---------------------tag header length 11--------- //---------------------tag header end---------------- byte formatAndRateAndSize = (byte) (audioTag.getFormat() << 4 | audioTag.getRate() << 2 | audioTag.getSize() << 1 | audioTag.getType()); //-------------data begin------- buffer.writeByte(formatAndRateAndSize); buffer.writeBytes(audioTag.getData()); //-------------data end ------- //应该等于11+tagDataSize buffer.writeInt(buffer.writerIndex()); return buffer; } /** * 读取bytebuf剩下的字节 * * @param msg 可读取bytebuf * @return 剩下所有的字节 * @author xingkong * @date 2021-09-07 16:15 */ public static byte[] readReadableBytes(ByteBuf msg) { byte[] content = new byte[msg.readableBytes()]; msg.readBytes(content); msg.release(); return content; } /** * 转换数据 转换为我们需要的报文形式 * * @param data 带转换的报文 * @return 转换好的报文 * @author xingkong * @date 2021/9/8 */ public static byte[] make(byte[] data) { ByteBuf buffer = Unpooled.buffer(); buffer.writeBytes(String.format("%x\r\n", data.length).getBytes()); buffer.writeBytes(data); buffer.writeByte((byte) '\r'); buffer.writeByte((byte) '\n'); return readReadableBytes(buffer); } }