Unicode in JavaScript

Unicode in JavaScript

by Jinya

【转载请注明出处,http://blog.csdn.net/EI__Nino】

名词解释:

BMP:(BasicMultilingual Plane)它又简称为"零号平面", plane 0

UCS:通用字符集(Universal Character Set, UCS)

ISO:国际标准化组织(ISO)

UTF:UCS Transformation Format,

BOM:Byte Order Mark 字节序

CJK: 统一表意符号 (CJK Unified Ideographs)

BE:Big Endian 大端

LE:Little Endian 小端

一、简介

Unicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。

二、UCS

通用字符集(UniversalCharacter Set, UCS)是由ISO制定的ISO 10646(或称ISO/IEC 10646)标准所定义的标准字符集。UCS-2用两个字节编码,UCS-4用4个字节编码。

UCS-4根据最高位为0的最高字节分成27=128个group。每个group再根据次高字节分为256个平面(plane)。每个平面根据第3个字节分为256行 (row),每行有256个码位(cell)。group 0的平面0被称作BMP(Basic MultilingualPlane)。如果UCS-4的前两个字节为全零,那么将UCS-4的BMP去掉前面的两个零字节就得到了UCS-2。

三、Unicode

Unicode标准准备把康熙字典的所有汉字放入到Unicode 32bit编码中。

Unicode扩展自ASCII字元集。在严格的ASCII中,每个字元用7位元表示,或者电脑上普遍使用的每字元有8位元宽;而Unicode使用全16位元字元集。这使得Unicode能够表示世界上所有的书写语言中可能用於电脑通讯的字元、象形文字和其他符号。Unicode最初打算作为ASCII的补充,可能的话,最终将代替它。考虑到ASCII是电脑中最具支配地位的标准,所以这的确是一个很高的目标。

Unicode影响到了电脑工业的每个部分,但也许会对作业系统和程序设计语言的影响最大。从这方面来看,我们已经上路了。Windows NT从底层支持Unicode(不幸的是,Windows 98只是小部分支援Unicode)。先天即被ANSI束缚的C程序设计语言通过对宽字元集的支持来支持Unicode。

四、UTF-8

字节FF和FE在UTF-8编码中永远不会出现,因此他们可以用来表明UTF-16或UTF-32文本(见BOM) UTF-8 是字节顺序无关的。

UTF-8以字节为单位对Unicode进行编码。从Unicode到UTF-8的编码方式如下:


Unicode编码(十六进制) 


UTF-8 字节流(二进制)


000000 - 00007F


0xxxxxxx   (7x)


000080 - 0007FF


110xxxxx 10xxxxxx  (11x)


000800 - 00FFFF


1110xxxx 10xxxxxx 10xxxxxx  (16x)


010000 - 10FFFF


11110xxx 10xxxxxx 10xxxxxx 10xxxxxx  (21x)

UTF-8的特点是对不同范围的字符使用不同长度的编码。对于0x00-0x7F之间的字符,处于0号平面,BMP,UTF-8编码与ASCII编码完全相同。

-> “\x32"
   2

-> "\u0032"
   "2"
 

UTF-8编码的最大长度是4个字节。从上表可以看出,4字节模板有21个x,即可以容纳21位二进制数字。

Unicode的最大码位0x10FFFF也只有21位。

例1:"汉"字的Unicode编码是0x6C49。0x6C49在0x0800-0xFFFF之间,使用用3字节模板了:1110xxxx 10xxxxxx 10xxxxxx。

将0x6C49写成二进制是:0110
1100 0100 1001
, 用这个比特流依次代替模板中的x,得到:11100110
10110001 10001001,即E6 B1 89。

-> encodeURI(“汉")
   “%E6%B1%89"

例2:Unicode编码0x20C30在0x010000-0x10FFFF之间,使用用4字节模板了:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx。将0x20C30写成21位二进制数字(不足21位就在前面补0):0 0010 0000 1100 0011 0000,用这个比特流依次代替模板中的x,得到:11110000 10100000 10110000 10110000,即F0 A0 B0 B0。

五、The love between Javascript and Unicode

可以使用String.fromCharCode 方法从任意进制的数字转成字符串

\u加一个十六进制数字可以转成字符串

-> String.fromCharCode("0x4e01")
    "丁"

-> 0x4e01.toString(10)
   "19969"

-> String.fromCharCode(19969)
    "丁"

-> "0x4e01".toString()
   "0x4e01"

-> "\u4e01".toString()
    “丁"
-> "\u4e01".toString()
    "丁"

六、输出

输出 "\u4e01"

->eval('"\u4e01"')
    "丁"
==
"\u4e01" -> "丁" ->eval(‘"丁"’)

->eval('"\\u4e01"')
    "丁"
==
"\\u4e01" -> "\u4e01" ->eval(‘"\u4e01"’)

-> eval('"\\\u4e01"')
    "丁"
==
"\\\u4e01" -> "\丁" ->eval(‘"\丁"’)

-> eval('"\\\\u4e01"')
    "\u4e01"
==
"\\\\u4e01" -> "\\u4e01" ->eval(‘"\\u4e01"’)

->'\u4e01'
    "丁"

->'\\u4e01'
   "\u4e01"

->'\\\u4e01'
    "\丁"

->'\\\\u4e01'
   "\\u4e01"

输出 "\丁"

-> "\丁"
    "丁"

-> "\\丁"
    "\丁"

-> "\\\丁"
    "\丁"
 

七、BOM

字节序有两种,分别是“大端”(Big Endian, BE)和“小端”(Little Endian, LE)。

根据字节序的不同,UTF-16可被实现为UTF-16LE或UTF-16BE,UTF-32可被实现为UTF-32LE或UTF-32BE。例如:


Unicode编码


UTF-16LE


UTF-16BE


UTF32-LE


UTF32-BE


0x006C49


49 6C


6C 49


49 6C 00 00


00 00 6C 49


0x020C30


43 D8 30 DC


D8 43 DC 30


30 0C 02 00


00 02 0C 30

Unicode标准建议用BOM(Byte Order Mark)来区分字节序,即在传输字节流前,先传输被作为BOM的字符“零宽无中断空格”。这个字符的编码是FEFF,而反过来的FFFE(UTF-16)和FFFE0000(UTF-32)在Unicode中都是未定义的码位,不应该出现在实际传输中。

下表是各种UTF编码的BOM:


UTF编码


Byte Order Mark (BOM)


UTF-8 without BOM



UTF-8 with BOM


EF BB BF


UTF-16LE


FF FE


UTF-16BE


FE FF


UTF-32LE


FF FE 00 00


UTF-32BE


00 00 FE FF

八、讨论

为什么中文会占3个字节?

中文范围 4E00-9FBF:CJK 统一表意符号 (CJK Unified Ideographs)

unicode 编码 000800 - 00FFFF 内的UTF-8 二进制表示为:1110xxxx 10xxxxxx 10xxxxxx 。

英文是在ASCII里可以表示,而ASCII编码的表示和UTF-8编码完全相同。他们的范围在0x00-0x7F之间。

unicode 编码 000000 - 00007F 内的UTF-8 二进制表示为:0xxxxxxx    。

随机获取中文?

-> 0x4e00.toString(10)
    19968
-> 0x9FBF.toString(10)
       40895
->  40895-19968
     20927

   String.fromCharCode(19968+Math.round(Math.random()*20927)

是否需要 BOM 头 ?

它的字节顺序在所有系统中都是一样的,因此它实际上并不需要BOM。但是PHP中,session创建前需要无输出,所以一般utf-8编码的php文件都要去除Bom头

HTML中的Unicode 和 javascript表示方法一样吗?

“&#” + unicode数字 得到对应的字符

document.write(“丁”)   => 丁

document.write(“一”)   =>丁

怎样查找中文?

-> “么么哒,memda".match(/[\u4e00-\u9FBF]/img)
    ["么", "么", "哒"]

长度?

->““么".length
    1

->"\u4e01".length
    1

怎么从汉字获取到unicode编码?

-> “么”.charCodeAt(0).toString(16)
    "4e48"

-> var a = “么么哒,meme”
-> a.replace(/[\u4e00-\u9fbf]/img,function($){return "\\u"+$.charCodeAt(0).toString(16); })
    "\u4e48\u4e48\u54d2,meme"

-> parseInt(encodeURI(“丁").split("%").slice(1).map(function(v){return parseInt(v,16).toString(2).replace(/^1*0/,”"); }).join(""),2).toString(16)
   “4e01"
==
encodeURI(“丁”) => “%E4%B8%81" =>[“E4”,”B8”,”81”] => ["0100","111000", “000001"]

=>”0100111000000001”=> 19969 =>”4e01"

参考:

http://www.cnblogs.com/ecalf/archive/2012/09/04/unicode.html

http://baike.baidu.com/link?url=4mS6twL-TXFMhtFZ8tnP9luwk-HoNQKf7sGA8KiIKI-K0Pkd0K3iRtbe0scF0BP4QGFp2b4EqqzPrJU5R24e1a

https://github.com/chenjinya/matrix

时间: 2024-10-07 07:04:15

Unicode in JavaScript的相关文章

Unicode与JavaScript详解

Unicode与JavaScript详解 作者: 阮一峰 日期: 2014年12月11日 上个月,我做了一次分享,详细介绍了Unicode字符集,以及JavaScript语言对它的支持.下面就是这次分享的讲稿. 一.Unicode是什么? Unicode源于一个很简单的想法:将全世界所有的字符包含在一个集合里,计算机只要支持这一个字符集,就能显示所有的字符,再也不会有乱码了. 它从0开始,为每个符号指定一个编号,这叫做"码点"(code point).比如,码点0的符号就是null(表

Unicode与JavaScript详解 [很好的文章转]

上个月,我做了一次分享,详细介绍了Unicode字符集,以及JavaScript语言对它的支持.下面就是这次分享的讲稿. 一.Unicode是什么? Unicode源于一个很简单的想法:将全世界所有的字符包含在一个集合里,计算机只要支持这一个字符集,就能显示所有的字符,再也不会有乱码了. 它从0开始,为每个符号指定一个编号,这叫做"码点"(code point).比如,码点0的符号就是null(表示所有二进制位都是0). U+0000 = null 上式中,U+表示紧跟在后面的十六进制

JavaScript的Unicode难题

退一步说, JavaScript处理Unicode时有些怪异. 这篇文章会说明JS在Unicode上令人痛苦的部分, 然后提供解决方案, 并说明在未来的ECMAScript6中是如何改善这些问题的. Unicode基础知识       为了您能更好的理解Unicode在JavaScript里的问题, 先确保大家了解Unicode为何物.       最简单的我们可以把 Unicode 想像成一个数据库, 任何您能想到的符号都对应着一个数字(我们把这个数字叫做它的码位)和一个唯一的名字. 这样一来

《javascript权威指南》读书笔记——第二篇

<javascript权威指南>读书笔记--第二篇 金刚 javascript js javascript权威指南 今天是今年的196天,分享今天的读书笔记. 第2章 词法结构 2.1 字符集 JavaScript程序是用Unicode字符集编写. Unicode是ASCII和Latin-1的超集,支持几乎所有语言. ES3 要求支持Unicode 2.1及后续版本 ES5 要求支持Unicode 3及后续版本 2.1.1 区分大小写 JavaScript是区分大小写的. HTML 并不区分大

我所了解的JavaScript糟粕和鸡肋

糟粕 全局变量 众所周知,全局变量在很小的程序中可能会带来方便,但随着程序变得越来大,全局变量将难以处理,全局变量将降低程序的可靠性. 在js中有3种方式定义全局变量 脱离任何函数安排一个var语句   //var foo=value; 直接添加一个属性到全局对象上  //window.foo=value; 直接使用未经声明的变更(其实这叫隐匿全局变量)    //foo=value; 作用域 众所周知,在JavaScript中没有块级作用域,而且在JavaScript有提升变量声明的功能,所以

特殊字符\u2028导致的Javascript脚本异常

这原本是个小错误,但排查花了不少时间,因此写下来和大家分享一下. 起因 通过Ajax动态从后台读取文章内容,并显示在页面上,加载到某篇文章的时候,报javascript语法错误,无法显示文章内容. Ajax从后台读取时返回的数据格式为Json,使用Newtonsoft.Json库来组装Json. 分析原因 因为其它文章可以正常加载,仅有一篇文章报Javascript语法错误,所以可以大致确定是文章内容导致的异常.把文章内容贴到写字板中仔细查找,发现有几个小黑方块,手工去掉这几个小黑方块后,加载正

[转载]JavaScript 中小数和大整数的精度丢失

标题: JavaScript 中小数和大整数的精度丢失作者: Demon链接: http://demon.tw/copy-paste/javascript-precision.html版权: 本博客的所有文章,都遵守“署名-非商业性使用-相同方式共享 2.5 中国大陆”协议条款. 先来看两个问题: 0.1 + 0.2 == 0.3; // false 9999999999999999 == 10000000000000000; // true 第一个问题是小数的精度问题,在业界不少博客里已有讨论

JavaScript糟粕和鸡肋

糟粕 全局变量 众所周知,全局变量在很小的程序中可能会带来方便,但随着程序变得越来大,全局变量将难以处理,全局变量将降低程序的可靠性. 在js中有3种方式定义全局变量 脱离任何函数安排一个var语句   //var foo=value; 直接添加一个属性到全局对象上  //window.foo=value; 直接使用未经声明的变更(其实这叫隐匿全局变量)    //foo=value; 作用域 众所周知,在JavaScript中没有块级作用域,而且在JavaScript有提升变量声明的功能,所以

js解析emoji表情

Emoji 公司的产品之前只有网页端,并没有提供emoji表情,之后将某个模块整合到app中,里面有个评论功能,在手机端可以输入emoji,显示的时候是空白,说明数据库并没有存储成功,查阅资料后得知emoji是四个字节,而mysql5.5.3前的版本utf8编码最多只支持3个字节. js解析emoji 先需要了解几个概念,js的编码方式.utf16.unicode 1.JavaScript语言采用Unicode字符集,但是只支持一种编码方法ucs-2 2.utf16编码 utf16是ucs-2的