天天看点

java中unicode utf-8以及汉字之间的转换工具类

1.       汉字字符串与unicode之间的转换

1.1          stringToUnicode

  1. /**
  2. * 获取字符串的unicode编码
  3. * 汉字“木”的Unicode 码点为Ox6728
  4. *
  5. * @param s 木
  6. * @return \ufeff\u6728 \ufeff控制字符 用来表示「字节次序标记(Byte Order Mark)」不占用宽度
  7. * 在java中一个char是采用unicode存储的 占用2个字节 比如 汉字木 就是 Ox6728 4bit+4bit+4bit+4bit=2字节
  8. */
  9. public static String stringToUnicode(String s) {
  10. try {
  11. StringBuffer out = new StringBuffer("");
  12. //直接获取字符串的unicode二进制
  13. byte[] bytes = s.getBytes("unicode");
  14. //然后将其byte转换成对应的16进制表示即可
  15. for (int i = 0; i < bytes.length - 1; i += 2) {
  16. out.append("\\u");
  17. String str = Integer.toHexString(bytes[i + 1] & 0xff);
  18. for (int j = str.length(); j < 2; j++) {
  19. out.append("0");
  20. }
  21. String str1 = Integer.toHexString(bytes[i] & 0xff);
  22. out.append(str1);
  23. out.append(str);
  24. }
  25. return out.toString();
  26. } catch (UnsupportedEncodingException e) {
  27. e.printStackTrace();
  28. return null;
  29. }
  30. }

测试

  1. @Test
  2. public void testGetUnicode() throws Exception {
  3. String str = "木";
  4. String s = EncodeUtil.stringToUnicode(str);
  5. System.out.println(s); //Ox6728
  6. }

1.2          unicodeToString

  1. /**
  2. * Unicode转 汉字字符串
  3. *
  4. * @param str \u6728
  5. * @return '木' 26408
  6. */
  7. public static String unicodeToString(String str) {
  8. Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
  9. Matcher matcher = pattern.matcher(str);
  10. char ch;
  11. while (matcher.find()) {
  12. //group 6728
  13. String group = matcher.group(2);
  14. //ch:'木' 26408
  15. ch = (char) Integer.parseInt(group, 16);
  16. //group1 \u6728
  17. String group1 = matcher.group(1);
  18. str = str.replace(group1, ch + "");
  19. }
  20. return str;
  21. }
  1. @Test
  2. public void testUnicodeToString() throws Exception {
  3. String str = "\\u6728";
  4. String s = EncodeUtil.unicodeToString(str);
  5. System.out.println(s); //木
  6. }

2.       汉字字符串与UTF-8之间的转换

2.1          ConvertStringToUTF8

  1. /**
  2. * 汉字 转换为对应的 UTF-8编码
  3. * @param s 木
  4. * @return E69CA8
  5. */
  6. public static String convertStringToUTF8(String s) {
  7. if (s == null || s.equals("")) {
  8. return null;
  9. }
  10. StringBuffer sb = new StringBuffer();
  11. try {
  12. char c;
  13. for (int i = 0; i < s.length(); i++) {
  14. c = s.charAt(i);
  15. if (c >= 0 && c <= 255) {
  16. sb.append(c);
  17. } else {
  18. byte[] b;
  19. b = Character.toString(c).getBytes("utf-8");
  20. for (int j = 0; j < b.length; j++) {
  21. int k = b[j];
  22. //转换为unsigned integer 无符号integer
  23. /*if (k < 0)
  24. k += 256;*/
  25. k = k < 0? k+256:k;
  26. //返回整数参数的字符串表示形式 作为十六进制(base16)中的无符号整数
  27. //该值以十六进制(base16)转换为ASCII数字的字符串
  28. sb.append(Integer.toHexString(k).toUpperCase());
  29. // url转置形式
  30. // sb.append("%" +Integer.toHexString(k).toUpperCase());
  31. }
  32. }
  33. }
  34. } catch (Exception e) {
  35. e.printStackTrace();
  36. }
  37. return sb.toString();
  38. }
  1. @Test
  2. public void testConvertStringToUTF8() {
  3. String str = "木";
  4. String s = EncodeUtil.convertStringToUTF8(str);
  5. System.out.println(s); //E69CA8
  6. }

2.2          ConvertUTF-8ToString

  1. /**
  2. * UTF-8编码 转换为对应的 汉字
  3. *
  4. * @param s E69CA8
  5. * @return 木
  6. */
  7. public static String convertUTF8ToString(String s) {
  8. if (s == null || s.equals("")) {
  9. return null;
  10. }
  11. try {
  12. s = s.toUpperCase();
  13. int total = s.length() / 2;
  14. //标识字节长度
  15. int pos = 0;
  16. byte[] buffer = new byte[total];
  17. for (int i = 0; i < total; i++) {
  18. int start = i * 2;
  19. //将字符串参数解析为第二个参数指定的基数中的有符号整数。
  20. buffer[i] = (byte) Integer.parseInt(s.substring(start, start + 2), 16);
  21. pos++;
  22. }
  23. //通过使用指定的字符集解码指定的字节子阵列来构造一个新的字符串。
  24. //新字符串的长度是字符集的函数,因此可能不等于子数组的长度。
  25. return new String(buffer, 0, pos, "UTF-8");
  26. } catch (UnsupportedEncodingException e) {
  27. e.printStackTrace();
  28. }
  29. return s;
  30. }
  1. @Test
  2. public void testConvertUTF8ToString() {
  3. String str = "E69CA8";
  4. String s = EncodeUtil.convertUTF8ToString(str);
  5. System.out.print(s); //木
  6. }

3.       unicode与utf-8之间的转换

3.1          unicode转为utf8

  1. //将unicode转换为utf-8
  2. @Test
  3. public void testUnicodeToUtf8() {
  4. String str = "\\u6728";
  5. //unicode转换为String String再转换为utf-8
  6. String s = EncodeUtil.convertStringToUTF8(EncodeUtil.unicodeToString(str));
  7. System.out.println(s);
  8. }

3.2          utf8转为unicode

  1. //将utf-8转换为unicode
  2. @Test
  3. public void testUTF8ToUnicode() {
  4. String str = "E69CA8";
  5. //utf-8先转String String再转unicode
  6. String s = EncodeUtil.stringToUnicode(EncodeUtil.convertUTF8ToString(str));
  7. System.out.println(s);
  8. }

总结来说:

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与汉字占用字节个数问题

继续阅读