一个21字节的UTF-8序列如何仅来自5个字符?

时间:2014-12-30 15:02:39

标签: java unicode encoding utf-8 string-length

在编写一些基本代码来计算String中的字符数后,我发现了一个例子,其中UTF-8编码输出从5"字符&#34创建了21个字节; String

这是输出:

String ==¦ อภิชาติ ¦==
Code units 7
UTF8 Bytes 21
8859 Bytes 7
Characters 5

据我所知,Java char的内部表示是2个字节,有些字符可能需要两个Unicode代码单元来显示它们。

由于UTF-8每个字符不使用超过4个字节,因此对于5个字符byte[]String长度如何超过20?

以下是来源:

import java.io.UnsupportedEncodingException;

public class StringTest {

    public static void main(String[] args) {
        displayStringInfo("อภิชาติ");
    }

    public static void displayStringInfo(String s) {
        System.out.println("Code units " + s.length());     
        try {
            System.out.println("UTF8 Bytes " + s.getBytes("UTF-8").length);
        } catch (UnsupportedEncodingException e) { // not handled }
        System.out.println("Characters " + characterLength(s));
    }

    public static int characterLength(String s) {
        int count = 0;
        for(int i=0; i<s.length(); i++) {
            if(!isLeadingUnit(s.charAt(i)) && !isMark(s.charAt(i))) count++;
        }
        return count;
    }

    private static boolean isMark(char ch) {
        int type = Character.getType(ch);
        return (type == Character.NON_SPACING_MARK ||
               type == Character.ENCLOSING_MARK ||
               type == Character.COMBINING_SPACING_MARK);
    }

    private static boolean isLeadingUnit(char ch) {
        return Character.isHighSurrogate(ch);
    }
}

2 个答案:

答案 0 :(得分:9)

您的“5个字符”字符串实际上由7个Unicode代码点组成:

  • U + 0E2D THAI CHARACTER O ANG
  • U + 0E20 THAI CHARACTER PHO SAMPHAO
  • U + 0E34 THAI CHARACTER SARA I
  • U + 0E0A THAI CHARACTER CHO CHANG
  • U + 0E32 THAI CHARACTER SARA AA
  • U + 0E15 THAI CHARACTER TO TAO
  • U + 0E34 THAI CHARACTER SARA I

所有这些都在U + 0800到U + FFFF范围内,在UTF-8中每个字符需要3个字节,因此总长度为7×3 = 21个字节。

答案 1 :(得分:3)

字符串中有 7 个字符:

 ' อ' (0x0e2d) encoded as {0xe0, 0xb8, 0xad}
  'ภ' (0x0e20) - / -      {0xe0, 0xb8, 0xa0}
  ' ิ' (0x0e34) - / -      {0xe0, 0xb8, 0xb4}
  'ช' (0x0e0a) - / -      {0xe0, 0xb8, 0x8a}
  'า' (0x0e32) - / -      {0xe0, 0xb8, 0xb2}
  'ต' (0x0e15) - / -      {0xe0, 0xb8, 0x95}
  ' ิ' (0x0e34) - / -      {0xe0, 0xb8, 0xb4}

每个符号由UTF-8中的三个字节编码,因此 你有7 * 3 == 21字节altogeter