java unicode补充字符带来的码点和代码单元问题
码点与代码单元
java string有两种判定字符的方式,一种是以码点,一种以代码单元,简单讲,码点就是真正的字符,代码单元是按大小即char型长度2个字节划分字符串。
所以length和charat方法都不能正确的表示我们所认为的字符数量个字符位置
关于 Character 摘自jdk文档
char数据类型(因此Character对象封装的值)基于原始Unicode规范,其将字符定义为固定宽度的16位实体。 Unicode标准已经被更改为允许其表示需要超过16位的字符。 法定代码点的范围现在是U + 0000到U + 10FFFF,称为Unicode标量值 。 (请参阅Unicode标准中U + n符号的 definition。 )
The set of characters from U+0000 to U+FFFF有时被称为基本多语言平面(BMP) 。 其代码点大于U + FFFF的Characters称为补充字符 s。 Java平台在char阵列和String和StringBuffer类中使用UTF-16表示形式。 在该表示中,补充字符表示为char值,第一个来自高替代范围( uD800- uDBFF),第二个来自低代理范围( uDC00- uDFFF)。
因此,值char表示基本多语言平面(BMP)代码点,包括代码代码点或UTF-16编码的代码单元。 一个int值代表所有Unicode代码点,包括补充代码点。 int的较低(最低有效)21位用于表示Unicode码点,而高(最高有效)11位必须为零。 除非另有说明,关于补充字符和char值的行为如下:
仅接受char值的方法不能支持补充字符。 他们将char值从代理范围视为未定义的字符。 例如, Character.isLetter('\uD840')返回false ,即使这个特定值如果后面是字符串中的任何低代理值都将代表一个字母。
接受int值的方法支持所有Unicode字符,包括补充字符。 例如, Character.isLetter(0x2F81A)返回true因为代码点值代表一个字母(CJK表意文字)。
关于unicode-16摘自百度
UTF-16编码以16位无符号整数为单位。我们把Unicode
unicode
unicode
编码记作U。编码规则如下:
如果U<0x10000,U的UTF-16编码就是U对应的16位无符号整数(为书写简便,下文将16位无符号整数记作WORD)。
如果U≥0x10000,我们先计算U'=U-0x10000,然后将U'写成二进制形式:yyyy yyyy yyxx xxxx xxxx,U的UTF-16编码(二进制)就是:110110yyyyyyyyyy 110111xxxxxxxxxx。
为什么U'可以被写成20个二进制位?Unicode的最大码位是0x10FFFF,减去0x10000后,U'的最大值是0xFFFFF,所以肯定可以用20个二进制位表示。例如:Unicode编码0x20C30,减去0x10000后,得到0x10C30,写成二进制是:0001 0000 1100 0011 0000。用前10位依次替代模板中的y,用后10位依次替代模板中的x,就得到:1101100001000011 1101110000110000,即0xD843 0xDC30。
按照上述规则,Unicode编码0x10000-0x10FFFF的UTF-16编码有两个WORD,第一个WORD的高6位是110110,第二个WORD的高6位是110111。可见,第一个WORD的取值范围(二进制)是11011000 00000000到11011011 11111111,即0xD800-0xDBFF。第二个WORD的取值范围(二进制)是11011100 00000000到11011111 11111111,即0xDC00-0xDFFF。
为了将一个WORD的UTF-16编码与两个WORD的UTF-16编码区分开来,Unicode编码的设计者将0xD800-0xDFFF保留下来,并称为代理区(Surrogate):
D800-DB7F
High Surrogates
高位替代
DB80-DBFF
High Private Use Surrogates
高位专用替代
DC00-DFFF
Low Surrogates
低位替代
高位替代就是指这个范围的码位是两个WORD的UTF-16编码的第一个WORD。低位替代就是指这个范围的码位是两个WORD的UTF-16编码的第二个WORD。那么,高位专用替代是什么意思?我们来解答这个问题,顺便看看怎么由UTF-16编码推导Unicode编码。
如果一个字符的UTF-16编码的第一个WORD在0xDB80到0xDBFF之间,那么它的Unicode编码在什么范围内?我们知道第二个WORD的取值范围是0xDC00-0xDFFF,所以这个字符的UTF-16编码范围应该是0xDB80 0xDC00到0xDBFF 0xDFFF。我们将这个范围写成二进制:
1101101110000000 11011100 00000000 - 1101101111111111 1101111111111111
按照编码的相反步骤,取出高低WORD的后10位,并拼在一起,得到
1110 0000 0000 0000 0000 - 1111 1111 1111 1111 1111
XML
XML
即0xe0000-0xfffff,按照编码的相反步骤再加上0x10000,得到0xf0000-0x10ffff。这就是UTF-16编码的第一个WORD在0xdb80到0xdbff之间的Unicode编码范围,即平面15和平面16。因为Unicode标准将平面15和平面16都作为专用区,所以0xDB80到0xDBFF之间的保留码位被称作高位专用替代[1] 。
java unicode补充字符带来的码点和代码单元问题的更多相关文章
- Java中的代码点和代码单元(转)
文章来源:http://blog.csdn.net/weizhaozhe/article/details/3909079 这篇文章讲的很细,但是对于初学者也很难理解,在后面的笔记中,我会陈述自己的简单 ...
- Java中代码点与代码单元(转)
摘要 本文介绍 Java 平台支持增补字符的方式.增补字符是 Unicode 标准中代码点超出 U+FFFF 的字符,因此它们无法在 Java 编程语言中描述为单个的 16 位实体(例如char数据类 ...
- 深入学习Java中的字符串,代码点和代码单元
在Java字符串处理时,在使用length和charAt方法时,应该格外小心,因为length返回的是UTF-16编码表示下的代码单元数量,而非我们所认为的字符的个数,charAt方法返回的是指定位置 ...
- 【转】Java中的代码点与代码单元
转载自:http://blog.csdn.net/xujinsmile/article/details/8526387 最近看core java,之前一直不明白,看了不少帖子和博客,总算搞明白了. J ...
- Java 字符编码 ASCII、Unicode、UTF-8、代码点和代码单元
1 ASCII码 统一规定英语字符与二进制位之间的关系.ASCII码一共规定了128个字符的编码.例如,空格“SPACE”是32(二进制00100000),大写字母A是65(二进制01000001). ...
- Java IO4:字符编码
前言 字符编码,这本不属于IO的内容,但字节流之后写的应该是字符流,既然是字符流,那就涉及一个"字符编码的"问题,考虑到字符编码不仅仅是在IO这块,Java中很多场景都涉及到这个概 ...
- JAVA的中文字符乱码问题
来源:http://luzefengoo.blog.163.com/blog/static/1403593882012754428536/ JAVA的中文字符乱码问题一直很让人头疼.特别是在WEB应用 ...
- Core Java 总结(字符和字符串类问题)
所有代码均在本地编译运行测试,环境为 Windows7 32位机器 + eclipse Mars.2 Release (4.5.2) 2016-10-17 整理 字符,字符串类问题 正则表达式问题 J ...
- Java Core 学习笔记——3.char/Unicode/代码点/代码单元
通用字符集(UCS) UCS是由ISO制定的ISO 10646(或称ISO/IEC 10646)标准所制定的标准字符集. UCS包括了其他所有的字符集(包含了已知语言的所以字符). ISO/IEC 1 ...
随机推荐
- 动态lambda 构建
var param = Expression.Parameter(typeof(T)); var datetime1 = Expression.Constant(dt1); var datetime2 ...
- String的本质是一个char*,只是以类的形式提供,使用起来比较方便
String的本质是一个char*,只是以类的形式提供,使用起来比较方便 Class String {private: char* m_data;}摘自<后台开发 核心技术与应用实践__徐晓鑫& ...
- 让用户使用第三方账号(如亚马逊账号)接入AWS IoT系统
我们想象这么一个IoT应用场景:厂商A使用AWS IoT来开发物联网解决方案,那么A把设备卖给用户的时候,需要使用户能够登入AWS IoT系统来控制其购买的A的设备,也就是说给用户分配适当的权限.下面 ...
- 从零开始学习音视频编程技术(三) 开发环境搭建(Qt4.86手动设置环境,主要就是设置g++和qmake,比较透彻,附下载链接)
1.先下载安装Qt 我们使用的版本是4.8. 可以自行百度下载也可以从下面的网盘地址下载: Qt库和编译器下载: 链接:http://pan.baidu.com/s/1hrUxLIG 密码:0181 ...
- CentOS 7 配置163源
具体的操作步骤: 1.打开终端,输入su指令切换到root用户:su 2.切换到系统yum源的目录下,即:cd /etc/yum.repos.d 3.备份系统默认yum源(也可直接删除):mv Cen ...
- How to setup Assigned Access in Windows 10 (Kiosk Mode) 设置分配的访问权限(Kiosk模式)
Let’s say you’re building some sort of ingenious mechanical contraption to be displayed in public th ...
- =WM_VSCROLL(消息反射) 和 WM_VSCROLL(消息响应)的区别(控件拥有者自己不处这个理消息,而是反射给控件对象本身来处理这个消息)
=WM_VSCROLL(消息反射) 和 WM_VSCROLL(消息响应)的区别 所谓消息反射就是控件拥有者自己不处这个理消息,而是反射给控件对象本身来处理这个消息 1.“=WM_VSCROLL”是消息 ...
- MSYS2 瘦身小攻略(使用junction)
MSYS2, 吃硬盘的大神 MSYS2,集成了 x86 x64两个开发环境,且可以使用 pacman 进行包管理,可谓方便的很!可是,这个东东也有一个很不好的地方,就是实在太占硬盘.尽管下载的软件包一 ...
- 使用WebBrowser并调用网页中的JS函数
在界面上拖入QAxWidget,注意这里不建议直接在UI设计界面指定控件,否则可能引起QtCreator崩溃 建议在代码中动态设置,如: ui->axWidget->setControl( ...
- ACL FAQ
acl 下载地址:https://sourceforge.net/projects/acl/https://github.com/zhengshuxin/acl/http://git.oschina. ...