All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.wicp.tams.commons.apiext.ByteUtil Maven / Gradle / Ivy

There is a newer version: 2.3.4
Show newest version
package net.wicp.tams.commons.apiext;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;

import org.apache.commons.lang.ArrayUtils;

import net.wicp.tams.commons.io.UnsignedLong;

public abstract class ByteUtil {
	/***
	 * 小字节序转为大字节序
	 * 
	 * @param value
	 * @return
	 */
	public static byte[] toBigEndian(byte[] value) {
		for (int i = 0, length = value.length >> 2; i <= length; i++) {
			final int j = value.length - 1 - i;
			final byte t = value[i];
			value[i] = value[j];
			value[j] = t;
		}
		return value;
	}

	/***
	 * 得到无符号int
	 * 
	 * @param b
	 * @return
	 */
	public static int toUnsigned(byte b) {
		return b & 0xFF;
	}

	/***
	 * 得到无符号int
	 * 
	 * @param s
	 * @return
	 */
	public static int toUnsigned(short s) {
		return s & 0xFFFF;
	}

	/***
	 * 得到无符号long
	 * 
	 * @param i
	 * @return
	 */
	public static long toUnsigned(int i) {
		return i & 0xFFFFFFFFL;
	}

	/***
	 * 读无符号的long
	 * 
	 * @param bytes
	 * @param littleEndian
	 * @return
	 */
	public static long readLong(byte[] bytes, boolean littleEndian) {
		long r = 0;
		for (int i = 0; i < bytes.length; ++i) {
			final long v = toUnsigned(bytes[i]);
			if (littleEndian) {
				r |= (v << (i << 3));
			} else {
				r = (r << 8) | v;
			}
		}
		return r;
	}

	public static long readLongL(byte[] bytes) {
		return readLong(bytes, true);
	}

	public static long readLongL(byte[] bytes, int offset, int length) {
		byte[] temp = Arrays.copyOfRange(bytes, offset, offset + length);
		return readLongL(temp);
	}

	public static long readLongB(byte[] bytes) {
		return readLong(bytes, false);
	}

	/**
	 * 读带符号的Long
	 * 
	 * @param bytes
	 * @return
	 */
	public long readLongSigned(byte[] bytes) {
		long r = 0;
		for (int i = 0; i < bytes.length; ++i) {
			final long v = toUnsigned(bytes[i]);
			r |= (v << (i << 3));
			if ((i == bytes.length - 1) && ((v & 0x80) == 0x80)) {
				for (int j = bytes.length; j < 8; j++) {
					r |= (255 << (j << 3));
				}
			}
		}
		return r;
	}

	/***
	 * bytes含有1的个数
	 * 
	 * @param bytes
	 * @return
	 */
	public static int byteshas1(byte[] bytes) {
		int ret = 0;
		for (int i = 0; i < bytes.length; i++) {
			byte b = bytes[i];
			for (int j = 0; j < 8; j++) {
				if ((b & 0x01 << j) != 0x00) {
					ret++;
				}
			}

		}
		return ret;
	}

	/***
	 * bytes含有0的个数
	 * 
	 * @param bytes
	 * @return
	 */
	public static int byteshas0(byte[] bytes) {
		int has1 = byteshas1(bytes);
		return bytes.length * 8 - has1;
	}

	/***
	 * 虽然int占4个字节,但有一个符号位,如果要得到无符号的int,bytes最多只能为3,如果大于3字节,请用readLong
	 * 
	 * @param bytes
	 *            要转的字节
	 * @param littleEndian
	 *            是否小字节序
	 * @return
	 */
	public static int readInt(byte[] bytes, boolean littleEndian) {
		int r = 0;
		for (int i = 0; i < bytes.length; ++i) {
			final int v = toUnsigned(bytes[i]);
			if (littleEndian) {
				r |= (v << (i << 3));
			} else {
				r = (r << 8) | v;
			}
		}
		return r;
	}

	public static int readIntL(byte[] bytes) {
		return readInt(bytes, true);
	}

	public static int readIntL(byte[] bytes, int offset, int length) {
		byte[] temp = Arrays.copyOfRange(bytes, offset, offset + length);
		return readIntL(temp);
	}

	public static int readIntB(byte[] bytes) {
		return readInt(bytes, false);
	}

	/***
	 * 读带符号的整形
	 * 
	 * @param bytes
	 * @return
	 */
	public static int readIntSigned(byte[] bytes) {
		int r = 0;
		for (int i = 0; i < bytes.length; ++i) {
			final int v = toUnsigned(bytes[i]);
			r |= (v << (i << 3));
			if ((i == bytes.length - 1) && ((v & 0x80) == 0x80)) {
				for (int j = bytes.length; j < 4; j++) {
					r |= (255 << (j << 3));
				}
			}
		}
		return r;
	}

	public static String readString(byte[] bytes) {
		try {
			String retstr = new String(trunc00(bytes), "UTF-8");
			return retstr;
		} catch (UnsupportedEncodingException e) {
			throw new IllegalArgumentException();
		}
	}

	/***
	 * 把前后的00二进制去掉进,要求中间不出现00
	 * 
	 * @param bytes
	 * @return
	 */
	public static byte[] trunc00(byte[] bytes) {
		int begindex = -1;
		int endindex = -1;
		for (int i = 0; i < bytes.length; i++) {
			if (bytes[i] != 0x00 && begindex < 0) {
				begindex = i;
				continue;
			}
			if (bytes[i] == 0x00 && begindex >= 0) {
				endindex = i;
				break;
			}
		}

		if (begindex < 0) {
			return ArrayUtils.EMPTY_BYTE_ARRAY;
		} else {
			if (endindex < 0) {
				return bytes;
			} else {
				return ArrayUtils.subarray(bytes, begindex, endindex);
			}
		}
	}

	public static String readString(byte[] bytes, int offset, int length) {
		byte[] temp = Arrays.copyOfRange(bytes, offset, offset + length);
		return readString(trunc00(temp));
	}

	///////////////////////////// 转为字节数据////////////////////////////////////////////
	public static byte[] toByteArray(byte num) {
		return new byte[] { num };
	}

	public static byte[] toByteArray(short num) {
		final byte[] r = new byte[2];
		for (int i = 0; i < 2; i++) {
			r[i] = (byte) (num >>> (8 - i * 8));
		}
		return r;
	}

	public static byte[] toByteArray(int num) {
		final byte[] r = new byte[4];
		for (int i = 0; i < 4; i++) {
			r[i] = (byte) (num >>> (24 - i * 8));
		}
		return r;
	}

	public static byte[] toByteArray(long num) {
		final byte[] r = new byte[8];
		for (int i = 0; i < 8; i++) {
			r[i] = (byte) (num >>> (56 - i * 8));
		}
		return r;
	}

	/***
	 * 把data分隔成每行最多maxLength列的多行数组
	 * 
	 * @param data
	 *            要分隔的数据源
	 * @param maxLength
	 *            每行最多列
	 * @return
	 */
	public static byte[][] splitBytes(byte[] data, int maxLength) {
		if (data.length <= maxLength) {
			return new byte[][] { data };
		} else {
			int length = data.length / maxLength + 1;
			byte[][] retary = new byte[length][maxLength];
			for (int l = 0; l < data.length; l++) {
				int i = l / maxLength;
				int j = l % maxLength;
				retary[i][j] = data[l];
			}
			return retary;

		}
	}

	///////////////////////////////// 字节数组操作///////////////////////////////////////////////////
	public static byte[] or(byte[] data1, byte[] data2) {
		if (data1.length != data2.length) {
			throw new IllegalArgumentException("array lenth does NOT match, " + data1.length + " vs " + data2.length);
		}
		final byte r[] = new byte[data1.length];
		for (int i = 0; i < r.length; i++) {
			r[i] = (byte) (data1[i] | data2[i]);
		}
		return r;
	}

	public static byte[] and(byte[] data1, byte[] data2) {
		if (data1.length != data2.length) {
			throw new IllegalArgumentException("array lenth does NOT match, " + data1.length + " vs " + data2.length);
		}
		final byte r[] = new byte[data1.length];
		for (int i = 0; i < r.length; i++) {
			r[i] = (byte) (data1[i] & data2[i]);
		}
		return r;
	}

	public static byte[] xor(byte[] data1, byte[] data2) {
		if (data1.length != data2.length) {
			throw new IllegalArgumentException("array lenth does NOT match, " + data1.length + " vs " + data2.length);
		}
		final byte r[] = new byte[data1.length];
		for (int i = 0; i < r.length; i++) {
			r[i] = (byte) (data1[i] ^ data2[i]);
		}
		return r;
	}

	public static boolean equals(byte[] data1, byte[] data2) {
		return Arrays.equals(data1, data2);
	}

	public static byte[] concat(byte[] data1, byte[] data2) {
		final byte r[] = new byte[data1.length + data2.length];
		System.arraycopy(data1, 0, r, 0, data1.length);
		System.arraycopy(data2, 0, r, data1.length, data2.length);
		return r;
	}

	/***
	 * 写帮助类
	 * 
	 * @author Administrator
	 *
	 */
	public static class AssitWrite {
		private final byte[] buff;
		private int curPos = 0;

		public AssitWrite(int size) {
			buff = new byte[size];
		}

		/***
		 * 实现小端字节写法,true
		 * 
		 * @param data
		 * @param leng
		 */
		public void writeByte(byte[] data, int leng, boolean littleEndian) {
			if (littleEndian) {
				org.apache.commons.lang3.ArrayUtils.reverse(data);
			}
			int copylen = data.length > leng ? leng : data.length;
			for (int i = 0; i < copylen; i++) {
				buff[curPos + i] = data[i];
			}
			curPos = curPos + leng;
		}

		public void write(byte[] data) {
			writeByte(data, data.length, false);
		}

		public void write(int data, int leng) {
			writeByte(toByteArray(data), leng, true);
		}

		public void write(long data, int leng) {
			writeByte(toByteArray(data), leng, true);
		}

		public void write(String data, int leng) {
			try {
				writeByte(data.getBytes("UTF-8"), leng, false);
			} catch (UnsupportedEncodingException e) {
			}
		}

		public void write(String data) {
			write(data, data.length());
		}

		public void writeEndNull(byte[] data) {
			write(data);
			write(0, 1);
		}

		public byte[] get() {
			return Arrays.copyOf(buff, curPos);
		}

	}

	/***
	 * 读帮助类
	 * 
	 * @author andy.zhou
	 *
	 */
	public static class AssitRead {
		private final byte[] data;
		private int curpos = 0;

		public AssitRead(byte[] data) {
			this.data = data;
		}

		public byte[] readBytes(int length) {
			byte[] ret = ArrayUtils.subarray(data, curpos, curpos + length);
			curpos += length;
			return ret;
		}

		public byte readByte() {
			return readBytes(1)[0];
		}

		public boolean hasMore() {
			return curpos >= data.length ? false : true;
		}

		public String readStringEndNull() throws IOException {
			byte[] allbyte = new byte[128];// 大多数128就够了
			int i = 0;
			while (true) {
				final byte v = readByte();
				if (v == 0x00)
					break;
				allbyte[i++] = v;
			}
			return ByteUtil.readString(allbyte);
		}

		public UnsignedLong readUnsignedLong() {
			final int v = ByteUtil.toUnsigned(readByte());
			if (v < 251)
				return UnsignedLong.valueOf(v);
			else if (v == 251)
				return null;
			else if (v == 252)
				return UnsignedLong.valueOf(ByteUtil.readLongL(readBytes(2)));
			else if (v == 253)
				return UnsignedLong.valueOf(ByteUtil.readLongL(readBytes(3)));
			else if (v == 254)
				return UnsignedLong.valueOf(ByteUtil.readLongL(readBytes(8)));
			else
				throw new RuntimeException("assertion failed, should NOT reach here");
		}

		public String readStringUnsignedLong() {
			UnsignedLong length = readUnsignedLong();
			String retstr = ByteUtil.readString(readBytes(length.intValue()));
			return retstr;
		}

		/**
		 * 读剩余字节
		 * 
		 * @return
		 */
		public byte[] readRest() {
			byte[] ret = ArrayUtils.subarray(data, curpos, data.length);
			return ret;
		}

		public void skip(int length) {
			curpos += length;
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy