• Unicode 与(UTF-8,UTF-16,UTF-32,UCS-2)


    Unicode是什么?

    Unicode源于一个很简单的想法:将全世界所有的字符包含在一个集合里,计算机只要支持这一个字符集,就能显示所有的字符,再也不会有乱码了。

    U+597D = 好

     597D 是16进制的表示,其实就是数字。 每一个字符对应一个数字。每个数字叫码点

    Unicode 就是一个映射表。一个数字表示一个字符。全世界的字符都在这个表里。所以叫字符集

    ASCII

    Ascll也是一个字符集,只不过它只有英文字母和一起符号。0-127的数字就可以搞定所有的字符。但是不适用于其他的文字。Unicode 字符集其中0至127这128个数字表示的字符仍然跟ASCII完全一样.

    UTF-8 与UTF-16,UTF-32的区别

    Unicode只规定了每个字符的码点,到底用什么样的字节序表示这个码点,就涉及到编码方法。

    最直观的编码方法是,每个码点使用四个字节表示,字节内容一一对应码点。这种编码方法就叫做UTF-32。比如,码点0就用四个字节的0表示,码点597D就在前面加两个字节的0。

    U+0000 = 0x0000 0000
    
    U+597D = 0x0000 597D

    UTF-32的优点在于,转换规则简单直观,查找效率高。缺点在于浪费空间,同样内容的英语文本,它会比ASCII编码大四倍。这个缺点很致命,导致实际上没有人使用这种编码方法,HTML 5标准就明文规定,网页不得编码成UTF-32。

    人们真正需要的是一种节省空间的编码方法,这导致了UTF-8的诞生。UTF-8是一种变长的编码方法,字符长度从1个字节到4个字节不等。越是常用的字符,字节越短,最前面的128个字符,只使用1个字节表示,与ASCII码完全相同。

    UTF-16编码介于UTF-32与UTF-8之间,同时结合了定长和变长两种编码方法的特点。

    它的编码规则很简单:基本平面的字符占用2个字节,辅助平面的字符占用4个字节。也就是说,UTF-16的编码长度要么是2个字节(U+0000到U+FFFF),要么是4个字节(U+010000到U+10FFFF)。

     

    当用程序打开一个文件时我们怎么知道那是用的UTF-8还是UTF-16啊.

    自然会有点啥标志,在文件的开头几个字节就是标志.

    EF BB BF 表示UTF-8

    FE FF 表示UTF-16.

    用UTF-16表示"汉"
    
    假如用UTF-16表示的话就是01101100   01001001(共16 bit,两个字节).程序解析的时候知道是UTF-16就把两个字节当成一个单元来解析.这个很简单.
    
    用UTF-8表示"汉"
    
    用UTF-8就有复杂点.因为此时程序是把一个字节一个字节的来读取,然后再根据字节中开头的bit标志来识别是该把1个还是两个或三个字节做为一个单元来处理.
    
    0xxxxxxx,如果是这样的01串,也就是以0开头后面是啥就不用管了XX代表任意bit.就表示把一个字节做为一个单元.就跟ASCII完全一样.
    
    110xxxxx 10xxxxxx.如果是这样的格式,则把两个字节当一个单元
    
    1110xxxx 10xxxxxx 10xxxxxx 如果是这种格式则是三个字节当一个单元.

    所有要用1110xxxx 10xxxxxx 10xxxxxx这种格式.把27721对应的二进制从左到右填充XXX符号(实际上不一定从左到右,也可以从右到左,这是涉及到另外一个问题.等会说.

    刚说到填充方式可以不一样,于是就出现了Big-Endian,Little-Endian的术语.Big-Endian就是从左到右,Little-Endian是从右到左.

    由上面我们可以看出UTF-8需要判断每个字节中的开头标志信息,所以如果一当某个字节在传送过程中出错了,就会导致后面的字节也会解析出错.而UTF-16不会判断开头标志,即使错也只会错一个字符,所以容错能力强.

    JavaScript使用哪一种编码?

    JavaScript语言采用Unicode字符集,但是只支持一种编码方法。

    这种编码既不是UTF-16,也不是UTF-8,更不是UTF-32。上面那些编码方法,JavaScript都不用。

    JavaScript用的是UCS-2!

    UCS的开发进度快于Unicode,1990年就公布了第一套编码方法UCS-2,使用2个字节表示已经有码点的字符。(那个时候只有一个平面,就是基本平面,所以2个字节就够用了。)UTF-16编码迟至1996年7月才公布,明确宣布是UCS-2的超集,即基本平面字符沿用UCS-2编码,辅助平面字符定义了4个字节的表示方法。

    两者的关系简单说,就是UTF-16取代了UCS-2,或者说UCS-2整合进了UTF-16。所以,现在只有UTF-16,没有UCS-2。

    由于JavaScript只能处理UCS-2编码,造成所有字符在这门语言中都是2个字节,如果是4个字节的字符,会当作两个双字节的字符处理。JavaScript的字符函数都受到这一点的影响,无法返回正确结果。

    ECMAScript 6

    JavaScript的下一个版本ECMAScript 6(简称ES6),大幅增强了Unicode支持,基本上解决了这个问题。

    (1)正确识别字符

    ES6可以自动识别4字节的码点。因此,遍历字符串就简单多了。

    for (let s of string ) {
      // ...
    }

    但是,为了保持兼容,length属性还是原来的行为方式。为了得到字符串的正确长度,可以用下面的方式。

    Array.from(string).length

    (2)码点表示法

    JavaScript允许直接用码点表示Unicode字符,写法是"反斜杠+u+码点"。

    '好' === 'u597D' // true

    但是,这种表示法对4字节的码点无效。ES6修正了这个问题,只要将码点放在大括号内,就能正确识别。

    u{1D306}

    (3)字符串处理函数

    String.fromCodePoint():从Unicode码点返回对应字符
    String.prototype.codePointAt():从字符返回对应的码点
    String.prototype.at():返回字符串给定位置的字符

    (4)正则表达式

    ES6提供了u修饰符,对正则表达式添加4字节码点的支持。

    /^.$/u.test(xxx)

    参考:

    http://www.ruanyifeng.com/blog/2014/12/unicode.html

  • 相关阅读:
    问题:关于抛出例外的一个问题。
    向北京球迷致敬!!!
    [下载]高质量C++C编程指南
    WinCE.NET中播放声音
    WINCE.NET中程序只运行一次
    解决vs2003开发PDA(wince.net4.2)调试与部署问题
    WinCE.NET中设置系统日期时间
    网页上发送mail(PHP)
    点阵字库预览工具 V1.0.0
    WINCE.NET4.2下如何获取程序当前运行目录
  • 原文地址:https://www.cnblogs.com/btgyoyo/p/6203264.html
Copyright © 2020-2023  润新知