java - 關(guān)于字符串編碼。
問題描述
public static void main(String[] args) throws Exception { String str = 'resource'; System.out.println(Arrays.toString(getHash(str,'MD5').getBytes()));//使用默認(rèn)解碼后輸出}public static String getHash(String str, String hashType) { try {MessageDigest digest = MessageDigest.getInstance(hashType);digest.reset();byte[] b = digest.digest(str.getBytes());System.out.println(Arrays.toString(b)); //編碼前輸出return new String(b); //使用默認(rèn)編碼 } catch (NoSuchAlgorithmException e) {e.printStackTrace(); } return str;}
輸出:[-106, -85, 78, 22, 63, 78, -32, 58, -86, 77, 16, 81, -86, 81, -46, 4]
[-17, -65, -67, -17, -65, -67, 78, 22, 63, 78, -17, -65, -67, 58, -17, -65, -67, 77, 16, 81, -17, -65, -67, 81, -17, -65, -67, 4]
為什么編碼前和編碼后再解碼所輸出的不一樣?
問題解答
回答1:你可能認(rèn)為(new String(b)).getBytes().equals(b),實(shí)際上并非如此。(盡管new String(s.getBytes()).equals(s)一定是。)
因?yàn)閎yte[]轉(zhuǎn)換成String時(shí),有些字節(jié)是未必能轉(zhuǎn)換成字符的,比如第一個(gè)-106、第二個(gè)-85就是,所以轉(zhuǎn)換成String時(shí)前兩個(gè)就變成了未知字符(表面上會(huì)顯示?,但實(shí)際上是一個(gè)Unicode字符),再轉(zhuǎn)成byte[](你這邊defaultCharset應(yīng)該是UTF-8吧),每個(gè)未知字符就變成3個(gè)字節(jié)了。
如果用GBK的話,情況還算好,但還是略有不同:
[-106, -85, 78, 22, 63, 78, -32, 58, -86, 77, 16, 81, -86, 81, -46, 4][-106, -85, 78, 22, 63, 78, 63, 58, -86, 77, 16, 81, -86, 81, 63, 4]
所以結(jié)論是:如果用String表示一個(gè)Hash值,不能把byte[]強(qiáng)轉(zhuǎn)換成String,而是按慣例轉(zhuǎn)換成16進(jìn)制表示。
相關(guān)文章:
1. docker不顯示端口映射呢?2. java - 請(qǐng)問在main方法中寫成對(duì)象名.屬性()并賦值,與直接參參數(shù)賦值輸錯(cuò)誤是什么原因?3. MySQL數(shù)據(jù)庫(kù)中文亂碼的原因4. docker - 各位電腦上有多少個(gè)容器啊?容器一多,自己都搞混了,咋辦呢?5. macos - mac下docker如何設(shè)置代理6. android studio總是在processes running好久7. 關(guān)docker hub上有些鏡像的tag被標(biāo)記““This image has vulnerabilities””8. mysql - 新浪微博中的關(guān)注功能是如何設(shè)計(jì)表結(jié)構(gòu)的?9. docker-compose 為何找不到配置文件?10. docker gitlab 如何git clone?
