package cm.java.util;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
/**
* 将二进制流转为其他数据类型
*/
public class ByteUtil {
/**
* TENS[i] contains the tens digit of the number i, 0 <= i <= 99.
*/
private static final char[] TENS = {
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
'2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
'3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
'4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
'5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
'6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
'7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
'8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
'9', '9', '9', '9', '9', '9', '9', '9', '9', '9'};
/**
* Ones [i] contains the tens digit of the number i, 0 <= i <= 99.
*/
private static final char[] ONES = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',};
/**
* Table for MOD / DIV 10 computation described in Section 10-21 of Hank
* Warren's "Hacker's Delight" online addendum.
* http://www.hackersdelight.org/divcMore.pdf
*/
private static final char[] MOD_10_TABLE = {0, 1, 2, 2, 3, 3, 4, 5, 5, 6,
7, 7, 8, 8, 9, 0};
private static final char SPACE_CH = ' ';
/**
* 私有构造函数,不允许实例化该类
*/
private ByteUtil() {
}
/**
* 将byte流转换为long
*
* byte[] b 二进制流
* short pos 开始转换位置
*/
public static long toLong(byte[] b, int pos) {
return toLong(b, pos, 8);
}
/**
* 将byte流转换为long
*
* byte[] b 二进制流
* int pos 开始转换位置
* int width 转换字节数
*/
public static long toLong(byte[] b, int pos, int width) {
long ret = 0;
for (int i = 0; i < width; i++) {
ret |= (b[i + pos] & 0xFFl) << (8 * i);
}
return ret;
}
/**
* 将byte流按照网络字节序转换为long
*
* byte[] b 二进制流
* int pos 开始转换位置
* int width 转换字节数
*/
public static long toBigEndianLong(byte[] b, int pos, int width) {
long ret = 0;
for (int i = 0; i < width; i++) {
ret |= (b[i + pos] & 0xFFl) << (8 * (width - i - 1));
}
return ret;
}
/**
* 将byte流转换为double
*
* byte[] b 二进制流
* short pos 开始转换位置
*/
public static double toDouble(byte[] b, int pos) {
long l;
l = b[pos];
l &= 0xff;
l |= ((long) b[pos + 1] << 8);
l &= 0xffff;
l |= ((long) b[pos + 2] << 16);
l &= 0xffffff;
l |= ((long) b[pos + 3] << 24);
l &= 0xffffffffl;
l |= ((long) b[pos + 4] << 32);
l &= 0xffffffffffl;
l |= ((long) b[pos + 5] << 40);
l &= 0xffffffffffffl;
l |= ((long) b[pos + 6] << 48);
l |= ((long) b[pos + 7] << 56);
return Double.longBitsToDouble(l);
}
/**
* 将byte流转换为short
*
* byte[] b 二进制流
* short pos 开始转换位置
*/
public static short toShort(byte[] b, int pos) {
short ret = 0;
ret |= (b[pos] & 0xFF);
ret |= (b[pos + 1] & 0xFF) << 8;
return ret;
}
/**
* 将两个byte流转换为int
*
* byte[] b 二进制流
* short pos 开始转换位置
*/
public static int toIntFromTwoBytes(byte[] b, int pos) {
int ret = 0;
ret |= (b[pos] & 0xFF);
ret |= (b[pos + 1] & 0xFF) << 8;
return (int) ret;
}
/**
* 将两个byte流转换为int,大字端
*
* byte[] b 二进制流
* short pos 开始转换位置
*/
public static int toBigEndianIntFromTwoBytes(byte[] b, int pos) {
int ret = 0;
ret |= (b[pos + 1] & 0xFF);
ret |= (b[pos] & 0xFF) << 8;
return (int) ret;
}
/**
* 将byte流按照网络字节序转换为short
*
* byte[] b 二进制流
* short pos 开始转换位置
*/
public static short toBigEndianShort(byte[] b, int pos) {
short ret = 0;
ret |= (b[pos] & 0xFF) << 8;
ret |= (b[pos + 1] & 0xFF);
return ret;
}
/**
* 将byte流按照网络字节序转换为int
*
* byte[] b 二进制流
* short pos 开始转换位置
*/
public static int toBigEndianInteger(byte[] b, int pos) {
int ret = 0;
for (int i = 0; i < 4; i++) {
ret |= (b[i + pos] & 0xFF) << (8 * (3 - i));
}
return ret;
}
/**
* 将int按网络字节流转换为byte数组
*
* int val 要转换的源
* byte[] b 目标数组
* short pos 开始存放位置下标
*/
public static void toBigEndianByteArray(int val, byte[] b, int pos) {
assert (pos + 4 <= b.length);
for (int i = 3; i >= 0; i--) {
b[pos + i] = (byte) (val & 0x000000FF);
val = val >> 8;
}
}
/**
* 将short按网络字节序转换为byte数组
*
* short val 要转换的源
* byte[] b 目标数组
* short pos 开始存放位置下标
*/
public static void toBigEndianByteArray(short val, byte[] b, int pos) {
assert (pos + 2 <= b.length);
b[pos + 1] = (byte) (val & 0x00FF);
b[pos] = (byte) ((val & 0xFF00) >> 8);
}
/**
* 将long按网络字节序转换为byte数组
*
* long val 要转换的源
* byte[] b 目标数组
* short pos 开始存放位置下标
*/
public static void toBigEndianByteArray(long val, byte[] b, int pos) {
assert (pos + 8 <= b.length);
for (int i = 7; i >= 0; i--) {
b[pos + i] = (byte) (val & 0x00000000000000FFl);
val = val >> 8;
}
}
/**
* 将byte流转换为int
*
* byte[] b 二进制流
* short pos 开始转换位置
*/
public static int toInteger(byte[] b, int pos) {
int ret = 0;
for (int i = 0; i < 4; i++) {
ret |= (b[i + pos] & 0xFF) << (8 * i);
}
return ret;
}
/**
* 将byte流转换为int
*
* byte[] b 二进制流
* int pos 开始转换位置
* int width 从几个byte转
*/
public static double toDouble(byte[] b, int pos, int width) {
double retVal = Double.MAX_VALUE;
switch (width) {
case 1:
case 2:
case 4:
return (double) toInteger(b, pos, width);
case 8:
return toDouble(b, pos);
default:
break;
}
return retVal;
}
public static int toBigEndianInteger(byte[] b, int pos, int width) {
int retVal = Integer.MAX_VALUE;
switch (width) {
case 1:
retVal = b[pos];
if (retVal < 0) {
retVal &= 0x000000FF;
}
break;
case 2:
retVal = toBigEndianIntFromTwoBytes(b, pos);
break;
case 4:
retVal = toBigEndianInteger(b, pos);
break;
default:
break;
}
return retVal;
}
public static int toInteger(byte[] b, int pos, int width) {
int retVal = Integer.MAX_VALUE;
switch (width) {
case 1:
retVal = b[pos];
if (retVal < 0) {
retVal &= 0x000000FF;
}
break;
case 2:
retVal = toIntFromTwoBytes(b, pos);
break;
case 4:
retVal = toInteger(b, pos);
break;
default:
break;
}
return retVal;
}
/**
* 将byte流转换为float
*
* @param b 二进制流
* @param pos 开始转换位置
* @return float 转换后的值
*/
public static float toFloat(byte[] b, int pos) {
int accum = 0;
for (int i = 0; i < 4; i++) {
accum |= (b[i + pos] & 0xff) << i * 8;
}
return Float.intBitsToFloat(accum);
}
public static float toFloatEx(byte[] b, int pos) {
try {
byte[] byteTmp = new byte[4];
for (int i = 0; i < 4; i++) {
byteTmp[i] = b[pos + i];
}
ByteBuffer bb = ByteBuffer.wrap(byteTmp);
FloatBuffer fb = bb.asFloatBuffer();
return fb.get();
} catch (Exception e) {
e.printStackTrace();
return 0.0f;
}
}
/**
* 将float转为byte[]
*/
public static void toByteArray(float val, byte[] b, int pos) {
try {
ByteBuffer bb = ByteBuffer.allocate(4);
FloatBuffer fb = bb.asFloatBuffer();
fb.put(val);
for (int i = 0; i < 4; i++) {
b[pos + i] = bb.get(i);
}
// b = bb.array();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 将long转换为byte数组
*
* @param val 要转换的源
* @param b 目标数组
* @param pos 开始存放位置下标
*/
public static void toByteArray(long val, byte[] b, int pos) {
assert (pos + 8 <= b.length);
for (int i = 0; i < 8; ++i) {
b[pos + i] = (byte) (val & 0x00000000000000FFl);
val = val >> 8;
}
}
/**
* 将long的指定长度字节转换为byte数组
*
* @param val 要转换的源 int w 要转化宽度
* @param b 目标数组
* @param pos 开始存放位置下标
*/
public static void toByteArray(long val, int w, byte[] b, int pos) {
assert (pos + 8 <= b.length);
for (int i = 0; i < w; ++i) {
b[pos + i] = (byte) (val & 0x00000000000000FFl);
val = val >> 8;
}
}
/**
* 将int转换为byte数组
*
* @param val 要转换的源
* @param b 目标数组
* @param pos 开始存放位置下标
*/
public static void toByteArray(int val, byte[] b, int pos) {
assert (pos + 4 <= b.length);
for (int i = 0; i < 4; ++i) {
b[pos + i] = (byte) (val & 0x000000FF);
val = val >> 8;
}
}
/**
* 将short转换为byte数组
*
* @param val 要转换的源
* @param b 目标数组
* @param pos 开始存放位置下标
*/
public static void toByteArray(short val, byte[] b, int pos) {
assert (pos + 2 <= b.length);
b[pos] = (byte) (val & 0x00FF);
b[pos + 1] = (byte) ((val & 0xFF00) >> 8);
}
/**
* 将指定位置的字节数组转化为指定长度的字符串
*/
public static String toStringWithLength(byte[] b, int pos, int length) {
StringBuilder str = new StringBuilder();
for (int i = 0; i < length; i++) {
str.append((char) b[pos + i]);
}
String ret = str.toString();
return ret;
}
/**
* 返回一个字符串,从指定位置,直到指定的结束字符
*/
public static String toStringUntil(byte[] b, int pos, byte until) {
StringBuilder str = new StringBuilder();
while (true) {
if (b.length <= pos) {
return null;
}
byte ch = b[pos];
if (ch == until) {
break;
}
str.append((char) ch);
pos++;
}
String ret = str.toString();
return ret;
}
/**
* 从指定位置开始,返回指定的第N个字符串,字符串之间以空格作为间隔符 最后一个字符串可能以length处为结束 index:从0开始计数
*/
public static String indexStringDevidedBySpace(byte[] b, int pos,
int length, int index) {
StringBuilder str = new StringBuilder();
int spaceNum = 0;
boolean valid = false;
// 指定位置开始即为第一个字符串
if (index == 0) {
valid = true;
}
for (int i = 0; i < length; i++) {
char ch = (char) b[pos + i];
if (SPACE_CH == ch) {
// 字符结束
if (valid) {
break;
}
spaceNum++;
// 字符开始
if (spaceNum == index) {
valid = true;
continue;
}
}
if (valid) {
str.append(ch);
}
}
String retStr = str.toString();
return retStr;
}
}