1. 漢字字符串與unicode之間的轉換
1.1 stringToUnicode
-
/**
-
* 獲取字符串的unicode編碼
-
* 漢字“木”的Unicode 碼點為Ox6728
-
*
-
* @param s 木
-
* @return \ufeff\u6728 \ufeff控制字符 用來表示「字節次序標記(Byte Order Mark)」不占用寬度
-
* 在java中一個char是采用unicode存儲的 占用2個字節 比如 漢字木 就是 Ox6728 4bit+4bit+4bit+4bit=2字節
-
*/
-
public static String stringToUnicode(String s) {
-
try {
-
StringBuffer out =
new StringBuffer(
"");
-
//直接獲取字符串的unicode二進制
-
byte[] bytes = s.getBytes(
"unicode");
-
//然后將其byte轉換成對應的16進制表示即可
-
for (
int i =
0; i < bytes.length -
1; i +=
2) {
-
out.append(
"\\u");
-
String str = Integer.toHexString(bytes[i +
1] &
0xff);
-
for (
int j = str.length(); j <
2; j++) {
-
out.append(
"0");
-
}
-
String str1 = Integer.toHexString(bytes[i] &
0xff);
-
out.append(str1);
-
out.append(str);
-
}
-
return out.toString();
-
}
catch (UnsupportedEncodingException e) {
-
e.printStackTrace();
-
return
null;
-
}
-
}
測試
-
@Test
-
public void testGetUnicode() throws Exception {
-
String str =
"木";
-
String s = EncodeUtil.stringToUnicode(str);
-
System.out.println(s);
//Ox6728
-
}
1.2 unicodeToString
-
/**
-
* Unicode轉 漢字字符串
-
*
-
* @param str \u6728
-
* @return '木' 26408
-
*/
-
public static String unicodeToString(String str) {
-
-
Pattern pattern = Pattern.compile(
"(\\\\u(\\p{XDigit}{4}))");
-
Matcher matcher = pattern.matcher(str);
-
char ch;
-
while (matcher.find()) {
-
//group 6728
-
String group = matcher.group(
2);
-
//ch:'木' 26408
-
ch = (
char) Integer.parseInt(group,
16);
-
//group1 \u6728
-
String group1 = matcher.group(
1);
-
str = str.replace(group1, ch +
"");
-
}
-
return str;
-
}
測試
-
@Test
-
public void testUnicodeToString() throws Exception {
-
String str =
"\\u6728";
-
String s = EncodeUtil.unicodeToString(str);
-
System.out.println(s);
//木
-
}
2. 漢字字符串與UTF-8之間的轉換
2.1 ConvertStringToUTF8
-
/**
-
* 漢字 轉換為對應的 UTF-8編碼
-
* @param s 木
-
* @return E69CA8
-
*/
-
public static String convertStringToUTF8(String s) {
-
if (s ==
null || s.equals(
"")) {
-
return
null;
-
}
-
StringBuffer sb =
new StringBuffer();
-
try {
-
char c;
-
for (
int i =
0; i < s.length(); i++) {
-
c = s.charAt(i);
-
if (c >=
0 && c <=
255) {
-
sb.append(c);
-
}
else {
-
byte[] b;
-
b = Character.toString(c).getBytes(
"utf-8");
-
for (
int j =
0; j < b.length; j++) {
-
int k = b[j];
-
//轉換為unsigned integer 無符號integer
-
/*if (k < 0)
-
k += 256;*/
-
k = k <
0? k+
256:k;
-
//返回整數參數的字符串表示形式 作為十六進制(base16)中的無符號整數
-
//該值以十六進制(base16)轉換為ASCII數字的字符串
-
sb.append(Integer.toHexString(k).toUpperCase());
-
-
// url轉置形式
-
// sb.append("%" +Integer.toHexString(k).toUpperCase());
-
}
-
}
-
}
-
}
catch (Exception e) {
-
e.printStackTrace();
-
}
-
return sb.toString();
-
}
測試
-
@Test
-
public void testConvertStringToUTF8() {
-
String str =
"木";
-
String s = EncodeUtil.convertStringToUTF8(str);
-
System.out.println(s);
//E69CA8
-
}
2.2 ConvertUTF-8ToString
-
/**
-
* UTF-8編碼 轉換為對應的 漢字
-
*
-
* @param s E69CA8
-
* @return 木
-
*/
-
public static String convertUTF8ToString(String s) {
-
if (s ==
null || s.equals(
"")) {
-
return
null;
-
}
-
try {
-
s = s.toUpperCase();
-
int total = s.length() /
2;
-
//標識字節長度
-
int pos =
0;
-
byte[] buffer =
new
byte[total];
-
for (
int i =
0; i < total; i++) {
-
int start = i *
2;
-
//將字符串參數解析為第二個參數指定的基數中的有符號整數。
-
buffer[i] = (
byte) Integer.parseInt(s.substring(start, start +
2),
16);
-
pos++;
-
}
-
//通過使用指定的字符集解碼指定的字節子陣列來構造一個新的字符串。
-
//新字符串的長度是字符集的函數,因此可能不等於子數組的長度。
-
return
new String(buffer,
0, pos,
"UTF-8");
-
}
catch (UnsupportedEncodingException e) {
-
e.printStackTrace();
-
}
-
return s;
-
}
測試
-
@Test
-
public void testConvertUTF8ToString() {
-
String str =
"E69CA8";
-
String s = EncodeUtil.convertUTF8ToString(str);
-
System.out.print(s);
//木
-
}
3. unicode與utf-8之間的轉換
3.1 unicode轉為utf8
-
//將unicode轉換為utf-8
-
@Test
-
public void testUnicodeToUtf8() {
-
String str =
"\\u6728";
-
//unicode轉換為String String再轉換為utf-8
-
String s = EncodeUtil.convertStringToUTF8(EncodeUtil.unicodeToString(str));
-
System.out.println(s);
-
}
3.2 utf8轉為unicode
-
//將utf-8轉換為unicode
-
@Test
-
public void testUTF8ToUnicode() {
-
String str =
"E69CA8";
-
//utf-8先轉String String再轉unicode
-
String s = EncodeUtil.stringToUnicode(EncodeUtil.convertUTF8ToString(str));
-
System.out.println(s);
-
}
總結來說:
1. java中的一個char是兩個字節,以unicode方式存儲在內存中。
2. 一個典型的錯誤是
String s = new String(”木”.getBytes(“utf-8”),”gbk”);
為什么會報錯呢?原因是 utf-8編碼的字節數組怎能使用gbk來解析呢?一個漢字在utf-8下占用3個字節,而在gbk下占用2個字節,是無法解析的。
3. java中提供了將漢字編碼為utf8的方法 UrlEncoder.encode()以及解碼的方法UrlDecoder.decode()
參考:
Java unicode中文編碼轉換和反轉
java 漢字與UTF-8十六進制編碼 間相互轉換方法
java中char與漢字占用字節個數問題