1. int 轉(zhuǎn) byte[ ]
/**
* 將int轉(zhuǎn)為低字節(jié)在前泻骤,高字節(jié)在后的byte數(shù)組
*/
public static byte[] intToArrayByLow(int n) {
byte[] bytes = new byte[4];
bytes[0] = (byte) (n & 0xff);
bytes[1] = (byte) (n >>> 8 & 0xff);
bytes[2] = (byte) (n >>> 16 & 0xff);
bytes[3] = (byte) (n >>> 24 & 0xff);
return bytes;
}
說明:
- & 0xff (與運(yùn)算):
- 兩個bit(1或0)進(jìn)行與運(yùn)算時上煤,如果兩者都為1搀缠,結(jié)果為1绊茧,否則為0,
- 而0xff轉(zhuǎn)化為2進(jìn)制為:0000000011111111,
- 當(dāng)一個int和 0xff進(jìn)行與運(yùn)算時跌帐,即表示提取這個int的最低八位护戳。
例如:
int a = 10000;// a的二進(jìn)制為 10011100010000
int b = a & 0xff;// a和0xff 與運(yùn)算后践磅,b的二進(jìn)制為 10000,即十進(jìn)制的16
System.out.println("b的十進(jìn)制="+b);// 輸出16
-
n >>> 8(位運(yùn)算):
>>8表示右移8位灸异,如果該數(shù)為正府适,則高位補(bǔ)0,若為負(fù)數(shù)肺樟,則高位補(bǔ)1檐春;例如:
1. res = 20 >> 2;
20的二進(jìn)制為 0001 0100,右移2位后為 0000 0101么伯,則結(jié)果就為 res = 5;
2. res = -20 >> 2;
-20的二進(jìn)制為其正數(shù)的補(bǔ)碼加1疟暖,即 11111111111111111111111111101100,
右移2位后為 11111111111111111111111111111011,結(jié)果為 res = -5;
3. 而對于>>>符號而言:
不管正負(fù)俐巴,都是右移后高位補(bǔ)0;
res = 20 >>> 2; 的結(jié)果與 20>>2 相同骨望;
res = -20 >>> 2;
-20的二進(jìn)制為 1110 1011,右移2位欣舵,為111010 擎鸠,此時高位補(bǔ)0,即 0011 1010
所以 bytes[1] = (byte) (n >>> 8 & 0xff);
表示 先右移8位缘圈,然后取最低的八位劣光。
也即從右到左,取第9到16位
- 再特別說明一點(diǎn),上面的轉(zhuǎn)換方法是采用低字節(jié)在前的方式糟把,一開始接觸的時候看著各種協(xié)議文檔寫著“低字節(jié)在前”绢涡,根本不知道是什么意思。
這里解釋一下低字節(jié)在前的意思遣疯,打個比方雄可,咱們不是說int有4個字節(jié)嗎? 那轉(zhuǎn)成byte數(shù)組就是byte[4]對吧缠犀?
byte[4]下標(biāo)從0開始到3滞项,0為前面,3為后面夭坪。
int的4個字節(jié)文判,最右邊的是最低字節(jié),最左邊的是最高字節(jié)室梅。
那么低字節(jié)在前的意思就是最右邊的字節(jié)存在byte[0]戏仓, 最左邊的字節(jié)存儲在byte[3]
2. byte[] 轉(zhuǎn) int
/**
* 低字節(jié)在前的方式獲取int值
*/
public static int getInt(byte[] b, int offset) {
int n = 0;
int len = b.length;
if (len >= offset + 4) {
// 低字節(jié)在前
int byte0 = b[offset] & 0xff; // 最右邊的字節(jié),不需要移位
int byte1 = b[offset + 1] & 0xff;// 右邊第二個字節(jié)亡鼠,需要左移一個字節(jié)赏殃,8位
int byte2 = b[offset + 2] & 0xff;// 右邊第三個字節(jié),需要左移兩個字節(jié)间涵,16位
int byte3 = b[offset + 3] & 0xff;// 最左邊的字節(jié)仁热,需要左移三哥字節(jié),24位
n = byte0 | byte1 << 8 | byte2 << 16 | byte3 << 24;
}
return n;
}
上面的代碼中勾哩,為什么需要對每個字節(jié)進(jìn)行 & 0xff運(yùn)算呢抗蠢? 不懂的同學(xué)可以參考下面的鏈接學(xué)習(xí)一下。
https://blog.csdn.net/iblade/article/details/73289831
3. short轉(zhuǎn)byte[]
short轉(zhuǎn)成byte[]其實(shí)和 int轉(zhuǎn)byte[]的邏輯一樣思劳,只不過int是四個字節(jié)迅矛,short是兩個字節(jié)。
/**
* 將short轉(zhuǎn)為低字節(jié)在前潜叛,高字節(jié)在后的byte數(shù)組
*/
public static byte[] shortToByteArrayByLow(short n) {
byte[] bytes = new byte[4];
bytes[0] = (byte) (n & 0xff);
bytes[1] = (byte) (n >>> 8 & 0xff);
return bytes;
}
4. byte[]轉(zhuǎn)short
/**
* @param b 低字節(jié)在前
* @param offset
* @return
*/
public static short getShortByLow(byte[] b, int offset) {
short n = 0;
int len = b.length;
if (len >= offset + 2) {
// 低字節(jié)在前
int byte0 = b[offset] & 0xff; // 最右邊的字節(jié)秽褒,不需要移位
int byte1 = b[offset + 1] & 0xff;// 右邊第二個字節(jié)壶硅,需要左移一個字節(jié),8位
n = (short) (byte0 | byte1 << 8);
}
return n;
}
5.long轉(zhuǎn)byte[]
long轉(zhuǎn)成byte[]其實(shí)和 int轉(zhuǎn)byte[]的邏輯一樣销斟,只不過int是四個字節(jié)庐椒,long是八個字節(jié)。
/**
* long轉(zhuǎn)byte[8]蚂踊,低字節(jié)在前
*/
public static byte[] longToByteArrayByLow(long n) {
byte[] bytes = new byte[8];
bytes[0] = (byte) (n & 0xff);
bytes[1] = (byte) (n >>> 8 & 0xff);
bytes[2] = (byte) (n >>> 16 & 0xff);
bytes[3] = (byte) (n >>> 24 & 0xff);
bytes[4] = (byte) (n >>> 32 & 0xff);
bytes[5] = (byte) (n >>> 40 & 0xff);
bytes[6] = (byte) (n >>> 48 & 0xff);
bytes[7] = (byte) (n >>> 56 & 0xff);
return bytes;
}
6.byte[]轉(zhuǎn)long
注意:要先把每個字節(jié)轉(zhuǎn)成long類型而不是int類型哦约谈,不然后面左移32位以上,會超出int的存儲范圍導(dǎo)致數(shù)據(jù)錯誤悴势。
/**
* 將byte數(shù)組轉(zhuǎn)為long
*/
public static long getLongByLow(byte[] b, int offset) {
long n = 0;
int len = b.length;
if (len >= offset + 8) {
// 低字節(jié)在前
long byte0 = b[offset] & 0xff; // 最右邊的字節(jié)窗宇,不需要移位
long byte1 = b[offset + 1] & 0xff;// 右邊第二個字節(jié)措伐,需要左移一個字節(jié)特纤,8位
long byte2 = b[offset + 2] & 0xff;// 右邊第三個字節(jié),需要左移兩個字節(jié)侥加,16位
long byte3 = b[offset + 3] & 0xff;// 最左邊的字節(jié)捧存,需要左移三哥字節(jié),24位
long byte4 = b[offset + 4] & 0xff;// 最左邊的字節(jié)担败,需要左移三哥字節(jié)昔穴,32位
long byte5 = b[offset + 5] & 0xff;// 最左邊的字節(jié),需要左移三哥字節(jié)提前,40位
long byte6 = b[offset + 6] & 0xff;// 最左邊的字節(jié)吗货,需要左移三哥字節(jié),48位
long byte7 = b[offset + 7] & 0xff;// 最左邊的字節(jié)狈网,需要左移三哥字節(jié)宙搬,56位
n = byte0 | byte1 << 8 | byte2 << 16 | byte3 << 24 | byte4 << 32 | byte5 << 40 | byte6 << 48 | byte7 << 56;
}
return n;
}