其他分享
首页 > 其他分享> > Okio原理分析之字符编码

Okio原理分析之字符编码

作者:互联网

OKio的原理分析,准备分3个部分来分析:

1.字符编码

字符编码(Character encoding)、字集码是把字符集中的字符编码为指定集合中某一对象(例如:比特模式、自然数序列、8位组或者电脉冲),以便文本在计算机中存储和通过通信网络的传递。常见的例子包括将拉丁字母表编码成摩斯电码和ASCII。其中,ASCII将字母、数字和其它符号编号,并用7比特的二进制来表示这个整数。通常会额外使用一个扩充的比特,以便于以1个字节的方式存储。

在计算机系统里面,编码的原因可以总结为:

UCS和Unicode

通用字符集(英语:Universal Character Set, UCS)是由ISO制定的ISO 10646(或称ISO/IEC 10646)标准所定义的标准字符集。

通用字符集包括了其他所有字符集。它保证了与其他字符集的双向兼容,即,如果你将任何文本字符串翻译到UCS格式,然后再翻译回原编码,你不会丢失任何信息。

Unicode,中文又称万国码、国际码、统一码、单一码,是计算机科学领域里的一项业界标准

Unicode规范定义了,每个文件的最前面分别加入一个表示编码顺序的字符,用FEFF来表示,正好是2个字节。如果文本文件的头2个字节是FEFF,表示用的大头方式(第一个字节在前),用FFFE的表示用的小头方式(第二个字节在前)

Unicode是一个符号集合(字符集),定义了符号的二进制代码,但是没有规定如何存储二进制代码

Unicode和UCS是来自2个不同的组织,Unicode对集合添加了一些新的规则和规范

历史上存在两个独立的尝试创立单一字符集的组织

从Unicode 2.0开始,Unicode采用了与ISO 10646-1相同的字库和字码;ISO也承诺,ISO 10646将不会替超出U+10FFFF的UCS-4编码赋值,以使得两者保持一致。两个项目仍都独立存在,并独立地公布各自的标准。但统一码联盟和ISO/IEC JTC1/SC2都同意保持两者标准的码表兼容,并紧密地共同调整任何未来的扩展。在发布的时候,Unicode一般都会采用有关字码最常见的字体,但ISO 10646一般都尽可能采用Century字体

UTF

Unicode的实现方式不同于编码方式。一个字符的Unicode编码是确定的。但是在实际传输过程中,由于不同系统平台的设计不一定一致,以及出于节省空间的目的,对Unicode编码的实现方式有所不同。Unicode的实现方式称为Unicode转换格式(Unicode Transformation Format,简称为UTF)。

UTF是"Unicode/UCS Transformation Format"的首字母缩写,即把Unicode字符转换为某种格式之意。UTF-16正式定义于ISO/IEC 10646-1的附录C,而RFC2781也定义了相似的做法。

编码格式

UTF-8 有以下编码规则:

   UCS-4 range (hex.)     UTF-8 octet sequence (binary)
 
   0000 0000-0000 007F   0xxxxxxx
 
   0000 0080-0000 07FF   110xxxxx 10xxxxxx
 
   0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx

   0001 0000-001F FFFF   11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
 
   0020 0000-03FF FFFF   111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
 
   0400 0000-7FFF FFFF   1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

详细的编码说明可以参考:https://tools.ietf.org/html/rfc2279

2.Java里面的编码说明

Java字符和字节

此节内容,截取自深入分析 Java 中的中文编码问题

以字符串”I am 君山”的 char 数组为 49 20 61 6d 20 541b 5c71,为例,下面把它按照不同的编码格式转化成相应的字节。

    public static void encode() {
        String name = "I am 君山";
        System.out.println( " default charset = " + Charset.defaultCharset()+" : " +bytesToHex(name.getBytes()));
        try {
            byte[] iso8859 = name.getBytes("ISO-8859-1");
            System.out.println("ISO-8859-1 = " + bytesToHex(iso8859));
            byte[] gb2312 = name.getBytes("GB2312");
            System.out.println("GB2312 = " + bytesToHex(gb2312));
            byte[] gbk = name.getBytes("GBK");
            System.out.println("GBK = " + bytesToHex(gbk));
            byte[] utf16 = name.getBytes("UTF-16");
            System.out.println("UTF-16 = " + bytesToHex(utf16));
            byte[] utf8 = name.getBytes("UTF-8");
            System.out.println("UTF-8 = " + bytesToHex(utf8));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    public static String bytesToHex(byte[] bytes) {
        char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = HEX_ARRAY[v >>> 4];
            hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
        }
        return new String(hexChars);
    }

执行结果是:

 default charset = UTF-8 : 4920616D20E5909BE5B1B1
ISO-8859-1 = 4920616D203F3F
GB2312 = 4920616D20BEFDC9BD
GBK = 4920616D20BEFDC9BD
UTF-16 = FEFF004900200061006D0020541B5C71
UTF-8 = 4920616D20E5909BE5B1B1

按照 ISO-8859-1 编码
在这里插入图片描述

按照 GB2312 编码
在这里插入图片描述

按照 GBK 编码
在这里插入图片描述

按照 UTF-16 编码
在这里插入图片描述

按照 UTF-8 编码
在这里插入图片描述

标签:编码,UTF,字节,字符,10xxxxxx,ISO,Unicode,Okio
来源: https://blog.csdn.net/weixin_42695485/article/details/111827146