编码字符集与字符集编码

编码字符集与字符集编码

编码字符集

  • ASCII:最先出现的编码字符集,包含了大小写的从A到Z和符号,用8位表示,共258个字符,老美一开始只固定了前127个字符(称为半角),而后面127个字符是在计算机在其他欧美国家开始使用时扩展的,是扩展字符集(全角)。

  • GB2312和GBK:当中国开始使用计算机表示汉字时,ASCII已经没有空间可以给汉字字符填充,所以中国索性把两个连在一起的大于127的ASCII字符当作一个汉字,这个方案称为GB2312;当GB2312不足够表示所有汉字时,中国规定 两个连在一起的第一个字符大于127的两个ASCII字符当作一个汉字,称为GBK方案。因此会出现:一个汉字字符相当于两个英文字符的情况。

  • Unicode:当计算机在全世界广泛传播时,出现了许多编码字符集,各个编码字符集之间无法相互识别,当同时出现在同一篇文档中会出现乱码。因此国际标准组织ISO出台了一套16位的字符编码方案以总括现有的各个编码字符集, 称为Unicode。在互联网出现之后,ISO规定了每次传输16位的方案称为UTF-16

字符集编码

  • Unicode是无法用16位表示所有文字字符的,随着不断有文字填充,必将使用更多位表示,这就将导致ASCII中的半角前面许多位都是0,白白浪费了空间。因此出现了Unicode的字符集编码方案

  • UTF-16:Unicode最开始的编码方案,笼统地用两个字节表示一个字符,不能解决空间浪费的问题

  • UTF-8:网络每次传输8位,可变长度的编码方案,可由1~4个字节表示一个字符,增加标识符以表示多少个字节表示一个字符,更加自由,解决了空间浪费问题。但也存在问题,有些文字由于增加了多个标识符,导致需要多个字节表示,如一个汉字字符需要三个字节表示。

Java中的编码字符集

  • I.java.lang.Character类规定了java使用的编码字符集,从java.lang.Character类注释的解读,我们可以知道:

    Java使用了Unicode编码字符集,具体来说Java中的字符数值范围是从0X0000到0x10FFFF,而0x0000到0xFFFF支持UTF-16编码方案,称为BMP(Basic Multilingual Plane 基础多语言面);大于0XFFFF的字符即是扩展字符,大小相当于两个char类型字符。

    char类型只支持BMP(即UTF-16包含的字符),char类型数据的value是一个Character类型数据,如’\u005CuD840’,它代表的是该char类型数据在Unicode database中指向的字符,即Character类型不等同于char类型, 如Character.isLetter(’\u005CuD840’)返回的是false,因为Character.isLetter(char char)要求的是传入一个char类型的数据,但该语句中传入的是Character类型的数据

    int类型除了支持BMP外还支持扩展字符,如 Character.isLetter(0x2F81A)返回的是true,0x2F81A是一个扩展字符的数值.

    • 注释原文如下:
      		 * <p>A {@code char} value, therefore, represents Basic
      		 * Multilingual Plane (BMP) code points, including the surrogate
      		 * code points, or code units of the UTF-16 encoding. An
      		 * {@code int} value represents all Unicode code points,
      		 * including supplementary code points. The lower (least significant)
      		 * 21 bits of {@code int} are used to represent Unicode code
      		 * points and the upper (most significant) 11 bits must be zero.
      		 * Unless otherwise specified, the behavior with respect to
      		 * supplementary characters and surrogate {@code char} values is
      		 * as follows:
      		 *
      		 * <ul>
      		 * <li>The methods that only accept a {@code char} value cannot support
      		 * supplementary characters. They treat {@code char} values from the
      		 * surrogate ranges as undefined characters. For example,
      		 * {@code Character.isLetter('\u005CuD840')} returns {@code false}, even though
      		 * this specific value if followed by any low-surrogate value in a string
      		 * would represent a letter.
      		 *
      		 * <li>The methods that accept an {@code int} value support all
      		 * Unicode characters, including supplementary characters. For
      		 * example, {@code Character.isLetter(0x2F81A)} returns
      		 * {@code true} because the code point value represents a letter
      		 * (a CJK ideograph).
      		 * </ul>
      		 *
      		 * <p>In the Java SE API documentation, <em>Unicode code point</em> is
      		 * used for character values in the range between U+0000 and U+10FFFF,
      		 * and <em>Unicode code unit</em> is used for 16-bit
      		 * {@code char} values that are code units of the <em>UTF-16</em>
      
  • II.Character类中提供了判断字符是BMP还是扩展字符的方法

		public static final char MIN_VALUE = '\u0000';
		
		public static final char MAX_VALUE = '\uFFFF';					

		public static final int MIN_CODE_POINT = 0x000000;
		
		public static final int MAX_CODE_POINT = 0X10FFFF;

		public static boolean isBmpCodePoint(int codePoint) {
	        return codePoint >>> 16 == 0;
	        // Optimized form of:
	        //     codePoint >= MIN_VALUE && codePoint <= MAX_VALUE
	        // We consistently use logical shift (>>>) to facilitate
	        // additional runtime optimizations.
	    }

		public static boolean isValidCodePoint(int codePoint) {
	        // Optimized form of:
	        //     codePoint >= MIN_CODE_POINT && codePoint <= MAX_CODE_POINT
	        int plane = codePoint >>> 16;
	        return plane < ((MAX_CODE_POINT + 1) >>> 16);
	    }

提供了将扩展字符从数值转为字符类型的方法

		//从此处我们可以发现,一个扩展字符相当两个char类字符
		static void toSurrogates(int codePoint, char[] dst, int index) {
	        // We write elements "backwards" to guarantee all-or-nothing
	        dst[index+1] = lowSurrogate(codePoint);
	        dst[index] = highSurrogate(codePoint);
	    }

猜你喜欢

转载自blog.csdn.net/weixin_38927996/article/details/87523342