JAVA 十六進(jìn)制與字符串的轉(zhuǎn)換
筆者前幾日在開服過程中需要將字符串轉(zhuǎn)化成為16進(jìn)制的字符串,在網(wǎng)上找到了一些方法嘗試之后,均發(fā)現(xiàn)存在一個(gè)問題-->字符串轉(zhuǎn)為16進(jìn)制后再轉(zhuǎn)回來,英文正常,中文出現(xiàn)亂碼
經(jīng)過考慮決定通過以下方式進(jìn)行解決:
1)在將字符串轉(zhuǎn)為16進(jìn)制之前先進(jìn)行一次轉(zhuǎn)化,先將其轉(zhuǎn)化成為Unicode編碼(相當(dāng)于把中文用英文字符代替),在轉(zhuǎn)化成為16進(jìn)制
2)相反的,在十六進(jìn)制轉(zhuǎn)換為字符串后的得到的是Unicode編碼,此時(shí)再將Unicode編碼解碼即可獲取原始字符串
代碼如下:
/** * 字符串轉(zhuǎn)換unicode */ public static String string2Unicode(String string) { StringBuffer unicode = new StringBuffer(); for (int i = 0; i < string.length(); i++) { // 取出每一個(gè)字符 char c = string.charAt(i); // 轉(zhuǎn)換為unicode unicode.append("\\u" + Integer.toHexString(c)); } return unicode.toString(); }
*字符串轉(zhuǎn)為16進(jìn)制
/** * 字符串轉(zhuǎn)化成為16進(jìn)制字符串 * @param s * @return */ public static String strTo16(String s) { String str = ""; for (int i = 0; i < s.length(); i++) { int ch = (int) s.charAt(i); String s4 = Integer.toHexString(ch); str = str + s4; } return str; }
*16進(jìn)制轉(zhuǎn)為字符串
/** * 16進(jìn)制轉(zhuǎn)換成為string類型字符串 * @param s * @return */ public static String hexStringToString(String s) { if (s == null || s.equals("")) { return null; } s = s.replace(" ", ""); byte[] baKeyword = new byte[s.length() / 2]; for (int i = 0; i < baKeyword.length; i++) { try { baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16)); } catch (Exception e) { e.printStackTrace(); } } try { s = new String(baKeyword, "UTF-8"); new String(); } catch (Exception e1) { e1.printStackTrace(); } return s; }
*Unicode轉(zhuǎn)為字符串
/** * unicode 轉(zhuǎn)字符串 */ public static String unicode2String(String unicode) { StringBuffer string = new StringBuffer(); String[] hex = unicode.split("\\\\u"); for (int i = 1; i < hex.length; i++) { // 轉(zhuǎn)換出每一個(gè)代碼點(diǎn) int data = Integer.parseInt(hex[i], 16); // 追加成string string.append((char) data); } return string.toString(); }
此方法雖然解決了轉(zhuǎn)化過程中中文亂碼的問題,但是過于復(fù)雜,筆者后來又發(fā)現(xiàn)一種新的轉(zhuǎn)化方式,可直接轉(zhuǎn)化,中文不亂碼,
代碼如下:
*字符串轉(zhuǎn)16進(jìn)制
/** * 字符串轉(zhuǎn)換成為16進(jìn)制(無需Unicode編碼) * @param str * @return */ public static String str2HexStr(String str) { char[] chars = "0123456789ABCDEF".toCharArray(); StringBuilder sb = new StringBuilder(""); byte[] bs = str.getBytes(); int bit; for (int i = 0; i < bs.length; i++) { bit = (bs[i] & 0x0f0) >> 4; sb.append(chars[bit]); bit = bs[i] & 0x0f; sb.append(chars[bit]); // sb.append(' '); } return sb.toString().trim(); }
*16進(jìn)制轉(zhuǎn)為字符串
/** * 16進(jìn)制直接轉(zhuǎn)換成為字符串(無需Unicode解碼) * @param hexStr * @return */ public static String hexStr2Str(String hexStr) { String str = "0123456789ABCDEF"; char[] hexs = hexStr.toCharArray(); byte[] bytes = new byte[hexStr.length() / 2]; int n; for (int i = 0; i < bytes.length; i++) { n = str.indexOf(hexs[2 * i]) * 16; n += str.indexOf(hexs[2 * i + 1]); bytes[i] = (byte) (n & 0xff); } return new String(bytes); }
下面是補(bǔ)充
java字符串和十六進(jìn)制字符串互轉(zhuǎn)
public class HexStringUtils { private static final char[] DIGITS_HEX = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; protected static char[] encodeHex(byte[] data) { int l = data.length; char[] out = new char[l << 1]; for (int i = 0, j = 0; i < l; i++) { out[j++] = DIGITS_HEX[(0xF0 & data[i]) >>> 4]; out[j++] = DIGITS_HEX[0x0F & data[i]]; } return out; } protected static byte[] decodeHex(char[] data) { int len = data.length; if ((len & 0x01) != 0) { throw new RuntimeException("字符個(gè)數(shù)應(yīng)該為偶數(shù)"); } byte[] out = new byte[len >> 1]; for (int i = 0, j = 0; j < len; i++) { int f = toDigit(data[j], j) << 4; j++; f |= toDigit(data[j], j); j++; out[i] = (byte) (f & 0xFF); } return out; } protected static int toDigit(char ch, int index) { int digit = Character.digit(ch, 16); if (digit == -1) { throw new RuntimeException("Illegal hexadecimal character " + ch + " at index " + index); } return digit; } public static String toHex(String str) { return new String(encodeHex(str.getBytes())); } public static String fromHex(String hex) { return new String(decodeHex(hex.toCharArray())); } public static void main(String[] args) { String s = "abc你好"; String hex = toHex(s); String decode = fromHex(hex); System.out.println("原字符串:" + s); System.out.println("十六進(jìn)制字符串:" + hex); System.out.println("還原:" + decode); } }
toHexString
public static String toHexString(int i)以十六進(jìn)制的無符號(hào)整數(shù)形式返回一個(gè)整數(shù)參數(shù)的字符串表示形式。
如果參數(shù)為負(fù),那么無符號(hào)整數(shù)值為參數(shù)加上 232;否則等于該參數(shù)。將該值轉(zhuǎn)換為十六進(jìn)制(基數(shù) 16)的無前導(dǎo) 0 的 ASCII 數(shù)字字符串。如果無符號(hào)數(shù)的大小值為零,則用一個(gè)零字符 '0' ('\u0030') 表示它;否則,無符號(hào)數(shù)大小的表示形式中的第一個(gè)字符將不是零字符。用以下字符作為十六進(jìn)制數(shù)字:
0123456789abcdef
這些字符的范圍是從 '\u0030' 到 '\u0039' 和從 '\u0061' 到 '\u0066'。如果希望得到大寫字母,可以在結(jié)果上調(diào)用 String.toUpperCase() 方法:
Integer.toHexString(n).toUpperCase()
參數(shù):
i - 要轉(zhuǎn)換成字符串的整數(shù)。
返回:
用十六進(jìn)制(基數(shù) 16)參數(shù)表示的無符號(hào)整數(shù)值的字符串表示形式。
// 轉(zhuǎn)化字符串為十六進(jìn)制編碼 public static String toHexString(String s) { String str=""; for (int i=0;i<s.length();i++) { int ch = (int)s.charAt(i); String s4 = Integer.toHexString(ch); str = str + s4; } return str; } // 轉(zhuǎn)化十六進(jìn)制編碼為字符串 public static String toStringHex(String s) { byte[] baKeyword = new byte[s.length()/2]; for(int i = 0; i < baKeyword.length; i++) { try { baKeyword[i] = (byte)(0xff & Integer.parseInt(s.substring(i*2, i*2+2),16)); } catch(Exception e) { e.printStackTrace(); } } try { s = new String(baKeyword, "utf-8");//UTF-16le:Not } catch (Exception e1) { e1.printStackTrace(); } return s; } // 轉(zhuǎn)化十六進(jìn)制編碼為字符串 public static String toStringHex(String s) { byte[] baKeyword = new byte[s.length()/2]; for(int i = 0; i < baKeyword.length; i++) { try { baKeyword[i] = (byte)(0xff & Integer.parseInt(s.substring(i*2, i*2+2),16)); } catch(Exception e) { e.printStackTrace(); } } try { s = new String(baKeyword, "utf-8");//UTF-16le:Not } catch (Exception e1) { e1.printStackTrace(); } return s; } public static void main(String[] args) { System.out.println(encode("中文")); System.out.println(decode(encode("中文"))); } /* * 16進(jìn)制數(shù)字字符集 */ private static String hexString="0123456789ABCDEF"; /* * 將字符串編碼成16進(jìn)制數(shù)字,適用于所有字符(包括中文) */ public static String encode(String str) { //根據(jù)默認(rèn)編碼獲取字節(jié)數(shù)組 byte[] bytes=str.getBytes(); StringBuilder sb=new StringBuilder(bytes.length*2); //將字節(jié)數(shù)組中每個(gè)字節(jié)拆解成2位16進(jìn)制整數(shù) for(int i=0;i<bytes.length;i++) { sb.append(hexString.charAt((bytes[i]&0xf0)>>4)); sb.append(hexString.charAt((bytes[i]&0x0f)>>0)); } return sb.toString(); } /* * 將16進(jìn)制數(shù)字解碼成字符串,適用于所有字符(包括中文) */ public static String decode(String bytes) { ByteArrayOutputStream baos=new ByteArrayOutputStream(bytes.length()/2); //將每2位16進(jìn)制整數(shù)組裝成一個(gè)字節(jié) for(int i=0;i<bytes.length();i+=2) baos.write((hexString.indexOf(bytes.charAt(i))<<4 |hexString.indexOf(bytes.charAt(i+1)))); return new String(baos.toByteArray()); }
第二種方法:
將指定byte數(shù)組以16進(jìn)制的形式打印到控制臺(tái)
package com.nantian.iclient.atm.sdb; public class Util { public Util() { } /** * 將指定byte數(shù)組以16進(jìn)制的形式打印到控制臺(tái) * @param hint String * @param b byte[] * @return void */ public static void printHexString(String hint, byte[] b) { System.out.print(hint); for (int i = 0; i < b.length; i++) { String hex = Integer.toHexString(b[i] & 0xFF); if (hex.length() == 1) { hex = '0' + hex; } System.out.print(hex.toUpperCase() + " "); } System.out.println(""); } /** * * @param b byte[] * @return String */ public static String Bytes2HexString(byte[] b) { String ret = ""; for (int i = 0; i < b.length; i++) { String hex = Integer.toHexString(b[i] & 0xFF); if (hex.length() == 1) { hex = '0' + hex; } ret += hex.toUpperCase(); } return ret; } /** * 將兩個(gè)ASCII字符合成一個(gè)字節(jié); * 如:"EF"--> 0xEF * @param src0 byte * @param src1 byte * @return byte */ public static byte uniteBytes(byte src0, byte src1) { byte _b0 = Byte.decode("0x" + new String(new byte[]{src0})).byteValue(); _b0 = (byte)(_b0 << 4); byte _b1 = Byte.decode("0x" + new String(new byte[]{src1})).byteValue(); byte ret = (byte)(_b0 ^ _b1); return ret; } /** * 將指定字符串src,以每兩個(gè)字符分割轉(zhuǎn)換為16進(jìn)制形式 * 如:"2B44EFD9" --> byte[]{0x2B, 0x44, 0xEF, 0xD9} * @param src String * @return byte[] */ public static byte[] HexString2Bytes(String src){ byte[] ret = new byte[8]; byte[] tmp = src.getBytes(); for(int i=0; i<8; i++){ ret[i] = uniteBytes(tmp[i*2], tmp[i*2+1]); } return ret; } }
以上就是JAVA 十六進(jìn)制與字符串的轉(zhuǎn)換的詳細(xì)內(nèi)容,更多關(guān)于JAVA 十六進(jìn)制的資料請關(guān)注腳本之家其它相關(guān)文章!
- Java 正則表達(dá)式詳解
- JAVA8 十大新特性詳解
- Java環(huán)境變量的設(shè)置方法(圖文教程)
- java寫入文件的幾種方法分享
- javascript的console.log()用法小結(jié)
- JavaScript window.setTimeout() 的詳細(xì)用法
- JavaScript 下拉菜單實(shí)現(xiàn)代碼
- javascript getElementById 使用方法及用法
- IIS Express 取代 ASP.NET Development Server的配置方法
- 將IIS Express改成可以通過ip地址訪問的設(shè)置方法
- 使用本機(jī)IIS?Express開發(fā)Asp.Net?Core應(yīng)用圖文教程
- 設(shè)置IIS Express并發(fā)數(shù)
- VS2015 IIS Express無法啟動(dòng)的解決方法
- IISExpress?配置允許外部訪問詳細(xì)介紹
相關(guān)文章
java發(fā)送HttpClient請求及接收請求結(jié)果過程的簡單實(shí)例
下面小編就為大家?guī)硪黄猨ava發(fā)送HttpClient請求及接收請求結(jié)果過程的簡單實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-11-11java客戶端線上Apollo服務(wù)端的實(shí)現(xiàn)
這篇文章主要介紹了java客戶端線上Apollo服務(wù)端的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08Java JDK與cglib動(dòng)態(tài)代理有什么區(qū)別
這篇文章主要介紹了Java JDK動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理的區(qū)別文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-03-03RestFul風(fēng)格 — 使用@PathVariable傳遞參數(shù)報(bào)錯(cuò)404的解決
這篇文章主要介紹了RestFul風(fēng)格 — 使用@PathVariable傳遞參數(shù)報(bào)錯(cuò)404的解決,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10