美文网首页
编码笔记

编码笔记

作者: 梦的飞翔_862e | 来源:发表于2020-07-07 17:53 被阅读0次

    java中经常会用到编码转换,但是经常会搞混,看了几个大神的解释,加入自己的理解,花了点时间整理下,供查阅。

    1、常用编码

    目前比较常用的编码有ASCII码,ISO-8859-1,GB2312,GBK,Unicode等
    1)ASCII码:仅用计算机的最小存储单位一个字节来标识,即8位,ascii码规定了一个英文字符和二进制位的对应关系,一共规定了128个字符,其中0-31是不能打印的字符,ascii码实际仅占用了后7个二进制位,最高位始终为0;
    2)ISO-8859-1
    IOS组织在ASCII基础上扩展,低7位仍然是ascii码,利用最高为来表示其余字符,IOS标准有IOS-8859-1 ~ IOS-8859-15,其中1涵盖了大多数西欧字符,应用最广泛,但是还是做多表示256个字符
    3)GB2312
    GB2312由两个字节组成,涉及到几个概念:
    区位码:GB2312将汉字编入94*94的二位表中,行称为区,列称为位,比如一个字在行54,列43 那么它的区位码就是5443
    国际码:将区和位上的数字分别加上32(16进制表示就是20H),形成国际码,加上20H的原因是GB2312覆盖了ascii的字母和字符,仅保留了32个不可打印的字符,所以每个区字节和位字节都需要偏移32(就是从33开始).
    举个例子:万的区位码是45区82位,转为16进制的区位码是2D52H,加上2020H等于4D72H
    机内码:存储中,每个字节无法区分是ascii码还是gb2312,所以微软规定了如果使用gb2312,每个字节的最高为是1,与ascii码区别,最高位设置为1,那么就是将国际码的每个字节加上128(2的7次幂,转为16进制就是每个字节+80H),得到了
    机内码=国际码+8080H=区位码+A0A0H
    所以万的机内码=2D52H+A0A0H=4D72H+8080H=CDF2H
    我们在电脑文本中看到的已经转换的gb2312编码实际上是机内码

    4)GBK
    是对GB2312的扩展,兼容GB2312,没做过多研究
    5)Unicode
    unicode 只是符号集,规定了符号的二进制代码,并没有规定如何存储。Unicode有17个平面,每个平面有2^16=65536个Code Point,总共2^16*17=1114112个,所以最后的码位是10FFFF。这个没有详细研究

    2. utf-8

    unicode的实现方式之一是utf-8,utf-8在实际开发过程中用的最多,所以做了比较详细的记录。
    概念:utf-8是一种变长的编码方式,使用1-4个字节标识不同的符号
    编码规则
    1)对于单字节的符号,第一位为0,后面7位为unicode码,因此对于英文字母,utf-8编码与ascii码一样
    2)对n(n>1)个字节的符号,第一个字节前n位是1,第n+1位为0,后面子节点前来两位一律为10,剩余所有位为unicode码
    从编码规则来看,如果第一个字节的第一位是0,那么这个字符就占一个字节,如果第一个字节前几位是1,那么就占几个字节
    看下utf-8存储字节和unicode的对应范围
    1个字节对应的unicode范围是0000 0000-0000 007F
    2个字节对应unicode的范围是0000 0080-0000 07FF
    3个字节对应unicode的范围是0000 0800-0000 FFFF
    4个字节对应unicode的范围是0001 0000-0010 FFFF
    这里unicode都用的4个字节来表示,得详细解释下,先说一个字节
    1个字节的二进制范围是0000 0000-0111 1111,转为16进制是00-7F,所以4个字节表示unicode就是0000 0000-0000 007F
    2个字节,根据编码规则,第一个字节的前三位必须是110,第二个字节的前两位必须是10,那么第一个字节有5位,第二个字节有6位来存储unicode,即开始范围是1100 0010 1000 0000,开始我比较疑惑为什不从1100 0001 1000 0000开始,随后发现,unicode的0 000100 0000实际上在一个字节的表示范围内。结束范围比较好理解,是11011111 10111111,表示unicode的实际只有0111 1111 1111,即7FF,所以2个字节对应的unicode范围是0000 0080-0000 07FF。
    3个字节,2个字节实际表示unicode的位数是11,那么三个字节起始表示unicode的是应该是12位,第一位是1 ,即1000 0000 0000(800H),实际存储的字节则为11100000 10100000 10000000,3个字节实际表示unicode的位数是16位(高4+中6+低6),所以3个字节的范围是FFFFH
    4个字节起始unicode应该是17位,最高位为1,则起始为10000H,即11110000 10100000 10000000 10000000,4个字节实际表示unicode的有21位,所以最大为1FFFFF,但是unicode的最后码位是10FFFF,所以4个字节表示unicode的范围是0001 0000-0010 FFFF

    看图还是更清楚些


    image.png

    参考网站:
    https://blog.csdn.net/zrf2112/article/details/50718684
    http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html

    相关文章

      网友评论

          本文标题:编码笔记

          本文链接:https://www.haomeiwen.com/subject/qutzqktx.html