本帖最后由 caixingke 于 2014-9-27 12:03 编辑
中文的几种编码: UNICODE --- JAVA默认的编码. ---其实就是UTF-16编码. 这是最统一的编码,可以用来表示所有语言的字符, 而且是定长双字节(也有四字节的)编码,包括英文字母在内。 所以可以说它是不兼容iso8859-1编码的,也不兼容任何编码。 不过,相对于iso8859-1编码来说,uniocode编码只是在前面增加了一个0字节. 双字节码点: 称为"非代理码点"---范围: 0~D7FF 以及 E000~FFFF; 四字节码点: 称为"代码对surrogate pair" 高字节, 其值称为"高代理码点high-surrogate":其范围为: '\uD800'-'\uDBFF' 低字节, 其值称为"低代理码点low-surrogate" : 其范围为: '\uDBFF'-'\uDC00'
低代理码点之前只能是一个高代理码点, 而不能是另一个低代理码点、一个非代理码点或者是文本的开头。 高代理码点的后面也只能跟一个低代理码点, 而不能是另一个高代理码点、一个非代理码点或者是文本的结尾。
从这里看到 高代理码点 和 低代理码点 和 非代理码点 的范围都是独立的, 所以, 任取一个双字节, 就可以判断其是 高代理,还是低代理, 还是非代理码点. 这样, 确定字符边界最多只需要扫描前一个或后一个编码单元,而不需考虑其他部分。
只要 不删掉 代理对 中的任一编码单元, 或者 只要 不在代理对中高低代码码点间插入另外的字符, 就可以保证数据的完整性。 而且,即便数据被破坏了,错误也是局部的。 其实, 通常, 代理对非常罕见,非代理码点将非常普遍。 这样, 可以提高效率, 甚至, 可允许一些处理过程可以不对代理对采取特别的操作, 或者使用已有处理字符序列的机制来处理代理对。 有人要问, 这些高代理点/低代理点的知识有用吗?
我就举个例子, String类中有如下这些方法
public int codePointAt(int index)
public int codePointBefore(int index)
public int codePointCount(int beginIndex, int endIndex)
public int offsetByCodePoints(int index, int codePointOffset)
只有懂了高代理点/低代理点 这些知识, 才能说看得懂这4个方法.
GB2312 --- 早期的, 只支持简体, 兼容: ISO-8859-1, 即扩展的ASCII编码. 现在基本不用, 多用下面要说的GBK.
GBK --- WIN默认的编码. 兼容GB2312, 也支持繁体. 与unicode兼容, 收录了2万多个汉字字符; 每一个字符2个字节. (但对于单字节的英文字符, 其只占1个字节, 以原版ASCII码存在, ------- 这个我已经验证过了) 字库的编码范围:
字库的编码范围: 0x8140~0xFEFE. 首字节: 81-FE 次字节: 40-FE 为什么要首字节要从81开始呢? 因为要有别于单字节的ASCII字符.
其中用户自定义区:
(1) AAA1-AFFE,码位 564 个。 (2) F8A1-FEFE,码位 658 个。 (3) A140-A7A0,码位 672 个。 可参见 http://ff.163.com/newflyff/gbk-list/ 这里是一些关于每一个汉字的编码, 从0xA1A0---0xFEAF
注意, 这里涉及的一些字母并不是英文字符, 而是我们常说的"双字节"的字符!
"单字节"的字符是放在0x0000--0x00ff这个扩展ASCII区域.
---这里的"单字节", 实际上仍然占用2个字节空间的. UTF-8 --- LINUX默认的编码. 编码兼容iso8859-1编码,同时也可以用来表示所有语言的字符, 不过,utf编码是不定长编码,每一个字符的长度从1-6个字节不等。 英文字母都是用一个字节表示,而汉字使用三个字节。 另外,utf编码自带简单的校验功能。 注意, 虽然说utf是为了使用更少的空间而使用的,但那只是相对于unicode编码来说; 如果已经知道是汉字,则使用GB2312/GBK无疑是最节省的。 不过另一方面,值得说明的是,虽然utf编码对汉字使用3个字节, 但即使对于汉字网页,utf编码也会比unicode编码节省, 因为网页中包含了很多的英文字符。
|