十六進制字符串轉字節數組
/** * 功能: 十六進制字符串轉字節數組 * @param hexString 十六進制字符串 * @return 字節數組 */ public static byte[] convertHexStringToBytes(String hexString){ //判空 if(hexString == null || hexString.length() == 0) { return null; } //合法性校驗 if(!hexString.matches("[a-fA-F0-9]*") || hexString.length() % 2 != 0) { return null; } //計算 int mid = hexString.length() / 2; byte[]bytes = new byte[mid]; for (int i = 0; i < mid; i++) { bytes[i] = Integer.valueOf(hexString.substring(i * 2, i * 2 + 2), 16).byteValue(); } return bytes; }
字節數組轉十六進制字符串
/** * 字節數組轉16進制數 * @param bytes 字節數組 * @return 返回值 */ public static String convertBytesToHexString(byte[]bytes) { StringBuilder res = new StringBuilder(""); for (byte aByte : bytes) { String temp = Integer.toHexString(aByte & 0xff); if (temp.length() == 1) { temp = '0' + temp; } res.append(temp); } return res.toString().toUpperCase(); }
整數轉化為十六進制字符串
/** * 功能:將整數轉化為合法的十六進制字符串 * @param source 整數 * @param len 至少占多少個字節 * @return 十六進制數 * * 說明:為什么要有len? * 某些場景需要指定大小的二進制字符串(這里的大小指的是轉化為字節數組后所占大小) * 例如,現在需要把1這個整數轉化為十六進制數, * 如果len為1,結果為 01 * 如果len為2,結果為 0001 * * 但是len不限制大小,比如len設置為1,source為125120,那么結果仍然為1e8c0, * 不會截斷結果 */ public static String convertIntToHexString(int source, int len) { //一個字節占兩位,所以要乘以2 len <<= 1; StringBuilder res = new StringBuilder(Integer.toHexString(source)); int comp = len - res.length(); //位數不足,需要補0 if(comp > 0) { for (int i = 0; i < comp; i++) { res.insert(0, "0"); } } return res.toString(); }
個人理解
上文提及的“合法十六進制字符串”指的是什么?
需要滿足如下條件:
1、只能包含數字以及字母ABCDEF(包含大小寫)
2、字符的個數必須是雙數,比如“1”只能寫成“01”
&0xff 到底有什么含義?
首先我們先了解一下基本作用
1 & 0 = 0
1 & 1 = 1
0 & 0 = 0
計算機中二進制數都是以補碼的形式存在
a & 0xff 表示取 a 補碼的后八位。
16進制字符串的范圍是 0x00 到 0xff,0到255
java中的byte是有符號的,一個byte表示的范圍是 -128到127。
而在這里,我們不需要byte的符號屬性,只需要它老老實實的表示0到255即可,所以不得不將128到255之間的數據做一個映射。
換句話說,11111111(補碼), 如果最高位作為符號位, 它是-1,如果不作為符號位,那就能表示255.
public static void main(String[] args) { byte a = -1; int b = a & 0xff; System.out.println(a); System.out.println(b); }
結果是:
-1 255
a & 0xff的返回值是int,也就是說,將a這個字節的補碼原封不動的拿出來,放到int中。
因為int 是四個字節,我們現在只用了兩個字節,自然觸碰不到符號位,這么一操作,就可以將 -1 映射成 255。
這樣就可以理解字節轉字符串中的這個轉換了:
Integer.toHexString(aByte & 0xff);
簡而言之,我們確實需要存256個數,但是范圍是0-255,而不是 -128-127,因為java不支持unsigned byte這種數據類型,所以我們需要借助容量更大的int完成這一轉換。
換句話說,如果java支持無符號byte,就不需要做這種轉換了。(C#中的byte就是沒有符號的,sbyte才是有符號的)
關於原碼、補碼、反碼的相關概念,推薦文章: https://zhuanlan.zhihu.com/p/91967268
如有錯誤,懇請批評指正!