简单几句话总结Unicode,UTF-8和UTF-16

合集下载

字符编码(1)——Unicode,utf-8

字符编码(1)——Unicode,utf-8

字符编码(1)——Unicode,utf-8字符编码编码是⼀个将⼀组Unicode字符转换业个字节序列的过程。

⽽解码是将⼀个编码字节序列转换为⼀组Unicode字符的过程。

Unicode字符是什么?Unicode字符集可以简写为UCS,也就是Unicode charactor setUnicode编码是国际组织制定的可以容纳世界上所有⽂字和符号的字符编码⽅案。

它通过0到0x10FFFF来映射字符,最多可容纳1114112个字符(16进制的10FFFF的值是1114111,然后加⼀个0x000000就是1114112个)。

可以看⼀下1114112的⼆进制表⽰形式为:1 0001 00000000 00000000UTF是什么?UTF是Unicode转换格式的意思,是UCS Transformation Format的缩写。

Utf-8UTF-8以字节为单位对Unicode进⾏编码。

utf-8特点是对不同范围的字符⽤不同长度的编码。

从Unicode到UTF-8的编码⽅式如下:Unicode编码(16进制) ║ UTF-8 字节流(⼆进制)000000 - 00007F ║ 0xxxxxxx000080 - 0007FF ║ 110xxxxx 10xxxxxx000800 - 00FFFF ║ 1110xxxx 10xxxxxx 10xxxxxx010000 - 10FFFF ║ 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx例如:“赵”这个字的Unicode编码(16进制表⽰⽅法)是:8d 75这个编码在.net中可以通过ToString()⽅法来实现。

为了进⾏后边的说明。

这⾥先给出测试⽤的转换⽅法:public static class CharSetHelper{public static string TransCoding(this int iValue,eTrans eType){return Convert.ToString(iValue, (int)eType);}public static string GetCorrectCoding(this string selfChar, Encoding encoding, eTrans eType){int iUnicode = (int)char.Parse(selfChar);return iUnicode.TransCoding(eType);}}public enum eTrans{Binary=2,Octonary=8,Decimal=10,Hexadecimal=16}⼀个枚举,⽤于枚举数的进制,⼀个从字串转换到特定的字符编码,并以指定进制表⽰的⽅法。

utf8 编码规则

utf8 编码规则

utf8 编码规则
UTF-8(8-bit Unicode Transformation Format)是一种变长字符编码,用于Unicode的实现方式之一。

UTF-8编码规则如下:
1. UTF-8是以字节为单位进行编码的,一个Unicode字符可以由1到4个字节表示。

2. 对于单字节的字符(即ASCII字符),UTF-8编码与ASCII编码相同,使用一个字节表示。

3. 对于多字节的字符,UTF-8编码使用额外的字节来表示Unicode码点。

首字节以0开头,后续字节以10开头。

4. UTF-8的编码长度根据Unicode码点的范围来确定:
- Unicode码点范围U+0000 至U+007F(ASCII字符):编码成一个字节,与ASCII编码相同。

- Unicode码点范围U+0080 至U+07FF:编码成两个字节,其中首字节的前三位为110,后续字节均为10开头。

- Unicode码点范围U+0800 至U+FFFF:编码成三个字节,其中首字节的前四位为1110,后续字节均为10开头。

- Unicode码点范围U+10000 至U+10FFFF:编码成四个字节,其中首字节的前五位为11110,后续字节均为10开头。

其他Unicode码点超出这些范围的字符,无法使用UTF-8编码表示。

5. UTF-8编码的字节顺序是从左到右,从高位到低位依次排列。

总结来说,UTF-8编码规则通过使用变长字节表示Unicode字符,保证了对ASCII字符的兼容,并且能够表示Unicode范围内的所有字符。

Unicode,GBK,GB2312,UTF-8概念基础(转载)

Unicode,GBK,GB2312,UTF-8概念基础(转载)

Unicode,GBK,GB2312,UTF-8概念基础(转载)第⼀篇:JAVA字符编码系列⼀:Unicode,GBK,GB2312,UTF-8概念基础本部分采⽤重⽤,转载⼀篇⽂章来完成这部分的⽬标。

来源:holen'blog 对字符编码与Unicode,ISO 10646,UCS,UTF8,UTF16,GBK,GB2312的理解地址:/holen/archive/2004/11/30/188182.aspxUnicode:制定的编码机制, 要将全世界常⽤⽂字都函括进去.在1.0中是16位编码, 由U+0000到U+FFFF. 每个2byte码对应⼀个字符; 在2.0开始抛弃了16位限制, 原来的16位作为基本位平⾯, 另外增加了16个位平⾯, 相当于20位编码, 编码范围0到0x10FFFF.UCS:ISO制定的ISO10646标准所定义的 Universal Character Set, 采⽤4byte编码.Unicode与UCS的关系:ISO与是两个不同的组织, 因此最初制定了不同的标准; 但⾃从unicode2.0开始, unicode采⽤了与ISO 10646-1相同的字库和字码, ISO也承诺ISO10646将不会给超出0x10FFFF的UCS-4编码赋值, 使得两者保持⼀致.UCS的编码⽅式:UCS-2, 与unicode的2byte编码基本⼀样.UCS-4, 4byte编码, ⽬前是在UCS-2前加上2个全零的byte.UTF: Unicode/UCS Transformation FormatUTF-8, 8bit编码, ASCII不作变换, 其他字符做变长编码, 每个字符1-3 byte. 通常作为外码. 有以下优点:* 与CPU字节顺序⽆关, 可以在不同平台之间交流* 容错能⼒⾼, 任何⼀个字节损坏后, 最多只会导致⼀个编码码位损失, 不会链锁错误(如GB码错⼀个字节就会整⾏乱码)UTF-16, 16bit编码, 是变长码, ⼤致相当于20位编码, 值在0到0x10FFFF之间, 基本上就是unicode编码的实现. 它是变长码, 与CPU字序有关, 但因为最省空间, 常作为⽹络传输的外码.UTF-16是unicode的preferred encoding.UTF-32, 仅使⽤了unicode范围(0到0x10FFFF)的32位编码, 相当于UCS-4的⼦集.UTF与unicode的关系:Unicode是⼀个字符集, 可以看作为内码.⽽UTF是⼀种编码⽅式, 它的出现是因为unicode不适宜在某些场合直接传输和处理. UTF-16直接就是unicode编码, 没有变换, 但它包含了0x00在编码内, 头256字节码的第⼀个byte都是0x00, 在操作系统(C语⾔)中有特殊意义, 会引起问题. 采⽤UTF-8编码对unicode的直接编码作些变换可以避免这问题, 并带来⼀些优点.中国国标编码:GB 13000: 完全等同于ISO 10646-1/Unicode 2.1, 今后也将随ISO 10646/Unicode的标准更改⽽同步更改.GBK: 对GB2312的扩充, 以容纳GB2312字符集范围以外的Unicode 2.1的统⼀汉字部分, 并且增加了部分unicode中没有的字符.GB 18030-2000: 基于GB 13000, 作为Unicode 3.0的GBK扩展版本, 覆盖了所有unicode编码, 地位等同于UTF-8, UTF-16, 是⼀种unicode编码形式. 变长编码, ⽤单字节/双字节/4字节对字符编码. GB18030向下兼容GB2312/GBK.GB 18030是中国所有⾮⼿持/嵌⼊式计算机系统的强制实施标准.-------------------------------什么是 UCS 和 ISO 10646?国际标准 ISO 10646 定义了通⽤字符集 (Universal Character Set, UCS). UCS 是所有其他字符集标准的⼀个超集. 它保证与其他字符集是双向兼容的.就是说, 如果你将任何⽂本字符串翻译到 UCS格式, 然后再翻译回原编码, 你不会丢失任何信息.UCS 包含了⽤于表达所有已知语⾔的字符. 不仅包括拉丁语,希腊语, 斯拉夫语,希伯来语,阿拉伯语,亚美尼亚语和乔治亚语的描述, 还包括中⽂, ⽇⽂和韩⽂这样的象形⽂字, 以及平假名, ⽚假名, 孟加拉语, 旁遮普语果鲁穆奇字符(Gurmukhi), 泰⽶尔语, 印.埃纳德语(Kannada), Malayalam, 泰国语, ⽼挝语, 汉语拼⾳(Bopomofo), Hangul, Devangari, Gujarati, Oriya, Telugu 以及其他数也数不清的语. 对于还没有加⼊的语⾔, 由于正在研究怎样在计算机中最好地编码它们, 因⽽最终它们都将被加⼊. 这些语⾔包括 Tibetian, ⾼棉语, Runic(古代北欧⽂字), 埃塞俄⽐亚语, 其他象形⽂字, 以及各种各样的印-欧语系的语⾔, 还包括挑选出来的艺术语⾔⽐如 Tengwar, Cirth 和克林贡语(Klingon). UCS 还包括⼤量的图形的, 印刷⽤的, 数学⽤的和科学⽤的符号, 包括所有由 TeX, Postscript, MS-DOS,MS-Windows, Macintosh, OCR 字体, 以及许多其他字处理和出版系统提供的字符.ISO 10646 定义了⼀个 31 位的字符集. 然⽽, 在这巨⼤的编码空间中, 迄今为⽌只分配了前 65534 个码位 (0x0000 到 0xFFFD). 这个 UCS 的 16位⼦集称为基本多语⾔⾯ (Basic Multilingual Plane, BMP). 将被编码在 16 位 BMP 以外的字符都属于⾮常特殊的字符(⽐如象形⽂字), 且只有专家在历史和科学领域⾥才会⽤到它们. 按当前的计划, 将来也许再也不会有字符被分配到从 0x000000 到 0x10FFFF 这个覆盖了超过 100 万个潜在的未来字符的21 位的编码空间以外去了. ISO 10646-1 标准第⼀次发表于 1993 年, 定义了字符集与 BMP 中内容的架构. 定义 BMP 以外的字符编码的第⼆部分 ISO 10646-2 正在准备中, 但也许要过好⼏年才能完成. 新的字符仍源源不断地加⼊到 BMP 中, 但已经存在的字符是稳定的且不会再改变了.UCS 不仅给每个字符分配⼀个代码, ⽽且赋予了⼀个正式的名字. 表⽰⼀个 UCS 或 Unicode 值的⼗六进制数, 通常在前⾯加上 "U+", 就象 U+0041 代表字符"拉丁⼤写字母A". UCS 字符 U+0000 到 U+007F 与 US-ASCII(ISO 646) 是⼀致的, U+0000 到 U+00FF 与 ISO 8859-1(Latin-1) 也是⼀致的. 从U+E000 到 U+F8FF, 已经 BMP 以外的⼤范围的编码是为私⽤保留的.什么是组合字符?UCS⾥有些编码点分配给了组合字符.它们类似于打字机上的⽆间隔重⾳键. 单个的组合字符不是⼀个完整的字符. 它是⼀个类似于重⾳符或其他指⽰标记, 加在前⼀个字符后⾯. 因⽽, 重⾳符可以加在任何字符后⾯. 那些最重要的被加重的字符, 就象普通语⾔的正字法(orthographies of common languages)⾥⽤到的那种, 在 UCS ⾥都有⾃⼰的位置, 以确保同⽼的字符集的向后兼容性. 既有⾃⼰的编码位置, ⼜可以表⽰为⼀个普通字符跟随⼀个组合字符的被加重字符, 被称为预作字符(precomposed characters). UCS ⾥的预作字符是为了同没有预作字符的旧编码, ⽐如 ISO 8859, 保持向后兼容性⽽设的. 组合字符机制允许在任何字符后加上重⾳符或其他指⽰标记, 这在科学符号中特别有⽤, ⽐如数学⽅程式和国际⾳标字母, 可能会需要在⼀个基本字符后组合上⼀个或多个指⽰标记.组合字符跟随着被修饰的字符. ⽐如, 德语中的元⾳变⾳字符 ("拉丁⼤写字母A 加上分⾳符"), 既可以表⽰为 UCS 码 U+00C4 的预作字符, 也可以表⽰成⼀个普通 "拉丁⼤写字母A" 跟着⼀个"组合分⾳符":U+0041 U+0308 这样的组合. 当需要堆叠多个重⾳符, 或在⼀个基本字符的上⾯和下⾯都要加上组合标记时, 可以使⽤多个组合字符. ⽐如在泰国⽂中, ⼀个基本字符最多可加上两个组合字符.什么是 UCS 实现级别?不是所有的系统都需要⽀持象组合字符这样的 UCS ⾥所有的先进机制. 因此 ISO 10646 指定了下列三种实现级别:级别1不⽀持组合字符和 Hangul Jamo 字符 (⼀种特别的, 更加复杂的韩国⽂的编码, 使⽤两个或三个⼦字符来编码⼀个韩⽂⾳节)级别2类似于级别1, 但在某些⽂字中, 允许⼀列固定的组合字符 (例如, 希伯来⽂, 阿拉伯⽂, Devangari, 孟加拉语, 果鲁穆奇语, Gujarati, Oriya, 泰⽶尔语, Telugo, 印.埃纳德语, Malayalam, 泰国语和⽼挝语). 如果没有这最起码的⼏个组合字符, UCS 就不能完整地表达这些语⾔.级别3⽀持所有的 UCS 字符, 例如数学家可以在任意⼀个字符上加上⼀个 tilde(颚化符号,西班⽛语字母上⾯的~)或⼀个箭头(或两者都加).什么是 Unicode?历史上, 有两个独⽴的, 创⽴单⼀字符集的尝试. ⼀个是国际标准化组织(ISO)的 ISO 10646 项⽬, 另⼀个是由(⼀开始⼤多是美国的)多语⾔软件制造商组成的协会组织的 Unicode 项⽬. 幸运的是, 1991年前后, 两个项⽬的参与者都认识到, 世界不需要两个不同的单⼀字符集. 它们合并双⽅的⼯作成果, 并为创⽴⼀个单⼀编码表⽽协同⼯作. 两个项⽬仍都存在并独⽴地公布各⾃的标准, 但 Unicode 协会和 ISO/IEC JTC1/SC2 都同意保持 Unicode 和 ISO 10646 标准的码表兼容, 并紧密地共同调整任何未来的扩展.那么 Unicode 和 ISO 10646 不同在什么地⽅?Unicode 协会公布的 Unicode 标准严密地包含了 ISO 10646-1 实现级别3的基本多语⾔⾯. 在两个标准⾥所有的字符都在相同的位置并且有相同的名字.Unicode 标准额外定义了许多与字符有关的语义符号学, ⼀般⽽⾔是对于实现⾼质量的印刷出版系统的更好的参考. Unicode 详细说明了绘制某些语⾔(⽐如阿拉伯语)表达形式的算法, 处理双向⽂字(⽐如拉丁与希伯来⽂混合⽂字)的算法和排序与字符串⽐较所需的算法, 以及其他许多东西.另⼀⽅⾯, ISO 10646 标准, 就象⼴为⼈知的 ISO 8859 标准⼀样, 只不过是⼀个简单的字符集表. 它指定了⼀些与标准有关的术语, 定义了⼀些编码的别名, 并包括了规范说明, 指定了怎样使⽤ UCS 连接其他 ISO 标准的实现, ⽐如 ISO 6429 和 ISO 2022. 还有⼀些与 ISO 紧密相关的, ⽐如 ISO 14651 是关于 UCS 字符串排序的.考虑到 Unicode 标准有⼀个易记的名字, 且在任何好的书店⾥的 Addison-Wesley ⾥有, 只花费 ISO 版本的⼀⼩部分, 且包括更多的辅助信息, 因⽽它成为使⽤⼴泛得多的参考也就不⾜为奇了. 然⽽, ⼀般认为, ⽤于打印 ISO 10646-1 标准的字体在某些⽅⾯的质量要⾼于⽤于打印 Unicode 2.0的. 专业字体设计者总是被建议说要两个标准都实现, 但⼀些提供的样例字形有显著的区别. ISO 10646-1 标准同样使⽤四种不同的风格变体来显⽰表意⽂字如中⽂, ⽇⽂和韩⽂ (CJK), ⽽ Unicode 2.0 的表⾥只有中⽂的变体. 这导致了普遍的认为 Unicode 对⽇本⽤户来说是不可接收的传说, 尽管是错误的.什么是 UTF-8?⾸先 UCS 和 Unicode 只是分配整数给字符的编码表. 现在存在好⼏种将⼀串字符表⽰为⼀串字节的⽅法. 最显⽽易见的两种⽅法是将 Unicode ⽂本存储为 2 个或 4 个字节序列的串. 这两种⽅法的正式名称分别为 UCS-2 和 UCS-4. 除⾮另外指定, 否则⼤多数的字节都是这样的(Bigendian convention). 将⼀个 ASCII 或 Latin-1 的⽂件转换成 UCS-2 只需简单地在每个 ASCII 字节前插⼊ 0x00. 如果要转换成 UCS-4, 则必须在每个 ASCII 字节前插⼊三个 0x00.在 Unix 下使⽤ UCS-2 (或 UCS-4) 会导致⾮常严重的问题. ⽤这些编码的字符串会包含⼀些特殊的字符, ⽐如 '/0' 或 '/', 它们在⽂件名和其他 C 库函数参数⾥都有特别的含义. 另外, ⼤多数使⽤ ASCII ⽂件的 UNIX 下的⼯具, 如果不进⾏重⼤修改是⽆法读取 16 位的字符的. 基于这些原因, 在⽂件名, ⽂本⽂件, 环境变量等地⽅, UCS-2 不适合作为 Unicode 的外部编码.在 ISO 10646-1 Annex R 和 RFC 2279 ⾥定义的 UTF-8 编码没有这些问题. 它是在 Unix 风格的操作系统下使⽤ Unicode 的明显的⽅法.UTF-8 有⼀下特性:UCS 字符 U+0000 到 U+007F (ASCII) 被编码为字节 0x00 到 0x7F (ASCII 兼容). 这意味着只包含 7 位 ASCII 字符的⽂件在 ASCII 和 UTF-8 两种编码⽅式下是⼀样的.所有 >U+007F 的 UCS 字符被编码为⼀个多个字节的串, 每个字节都有标记位集. 因此, ASCII 字节 (0x00-0x7F) 不可能作为任何其他字符的⼀部分.表⽰⾮ ASCII 字符的多字节串的第⼀个字节总是在 0xC0 到 0xFD 的范围⾥, 并指出这个字符包含多少个字节. 多字节串的其余字节都在 0x80 到0xBF 范围⾥. 这使得重新同步⾮常容易, 并使编码⽆国界, 且很少受丢失字节的影响.可以编⼊所有可能的 231个 UCS 代码UTF-8 编码字符理论上可以最多到 6 个字节长, 然⽽ 16 位 BMP 字符最多只⽤到 3 字节长.Bigendian UCS-4 字节串的排列顺序是预定的.字节 0xFE 和 0xFF 在 UTF-8 编码中从未⽤到.下列字节串⽤来表⽰⼀个字符. ⽤到哪个串取决于该字符在 Unicode 中的序号.U-00000000 - U-0000007F: 0xxxxxxxU-00000080 - U-000007FF: 110xxxxx 10xxxxxxU-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxxU-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxxU-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxxU-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxxxxx 的位置由字符编码数的⼆进制表⽰的位填⼊. 越靠右的 x 具有越少的特殊意义. 只⽤最短的那个⾜够表达⼀个字符编码数的多字节串. 注意在多字节串中, 第⼀个字节的开头"1"的数⽬就是整个串中字节的数⽬.例如: Unicode 字符 U+00A9 = 1010 1001 (版权符号) 在 UTF-8 ⾥的编码为:11000010 10101001 = 0xC2 0xA9⽽字符 U+2260 = 0010 0010 0110 0000 (不等于) 编码为:11100010 10001001 10100000 = 0xE2 0x89 0xA0这种编码的官⽅名字拼写为 UTF-8, 其中 UTF 代表 UCS Transformation Format. 请勿在任何⽂档中⽤其他名字 (⽐如 utf8 或 UTF_8) 来表⽰ UTF-8,当然除⾮你指的是⼀个变量名⽽不是这种编码本⾝.什么编程语⾔⽀持 Unicode?在⼤约 1993 年之后开发的⼤多数现代编程语⾔都有⼀个特别的数据类型, 叫做 Unicode/ISO 10646-1 字符. 在 Ada95 中叫 Wide_Character, 在 Java 中叫 char.ISO C 也详细说明了处理多字节编码和宽字符 (wide characters) 的机制, 1994 年 9 ⽉ Amendment 1 to ISO C 发表时⼜加⼊了更多. 这些机制主要是为各类东亚编码⽽设计的, 它们⽐处理 UCS 所需的要健壮得多. UTF-8 是 ISO C 标准调⽤多字节字符串的编码的⼀个例⼦, wchar_t 类型可以⽤来存放Unicode 字符.---------------------作者:qinysong来源:CSDN原⽂:https:///qinysong/article/details/1179480版权声明:本⽂为博主原创⽂章,转载请附上博⽂链接!。

汉字的utf-8编码

汉字的utf-8编码

汉字的utf-8编码
UTF-8 是一种可变长度的字符编码,可以用于表示Unicode 字符集中的所有字符,包括汉字。

汉字的UTF-8 编码通常是由一个或多个字节组成,具体的编码方式如下:
1. 常用汉字的编码范围:
-汉字的编码范围主要位于Unicode 的CJK(中日韩)统一表意文字区块,即U+4E00 到U+9FFF。

2. UTF-8 编码规则:
-单字节字符(ASCII 字符):对于ASCII 字符,UTF-8 使用一个字节表示,与ASCII 编码相同。

-多字节字符(包括汉字):UTF-8 使用多个字节表示。

汉字的编码规则如下:
-对于U+4E00 到U+7F 的范围,采用三个字节表示。

-对于U+800 到U+FFFF 的范围,采用三个字节表示。

-对于U+10000 到U+10FFFF 的范围,采用四个字节表示。

3. 汉字的例子:
-汉字"中" 的Unicode 编码是U+4E2D,其UTF-8 编码是三个字节:`E4 B8 AD`。

-汉字"国" 的Unicode 编码是U+56FD,其UTF-8 编码也是三个字节:`E5 9B BD`。

UTF-8 编码采用可变长度的方式,使得表示范围更广泛的字符需要更多的字节。

这种灵活性使得UTF-8 成为目前互联网上最为广泛使用的字符编码方案之一。

请注意,UTF-8 编码的字节顺序是固定的,不受字节顺序标记(BOM)的影响。

UTF-8编码详解

UTF-8编码详解

但是,这里又出现了新的问题。不同的国家有不同的字母,因此,哪怕它们都使用256个符号的编码方式,代表的字母却不一样。比如,130在法语编码中代表了é,在希伯来语编码中却代表了字母Gimel (ג),在俄语编码中又会代表另一个符号。但是不管怎样,所有这些编码方式中,0—127表示的符号是一样的,不一样的只是128—255的这一段。
UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
UTF-8的编码规则很简单,只有二条:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
6. Unicode与UTF-8之间的转换
通过上一节的例子,可以看到“严”的Unicode码是4E25,UTF-8编码是E4B8A5,两者是不一样的。它们之间的转换可以通过程序实现。
在Windows平台下,有一个最简单的转化方法,就是使用内置的记事本小程序Notepad.exe。打开文件后,点击“文件”菜单中的“另存为”命令,会跳出一个对话框,在最底部有一个“编码”的下拉条。
2、非ASCII编码
英语用128个符号编码就够了,但是用来表示其他语言,128个符号是不够的。比如,在法语中,字母上方有注音符号,它就无法用ASCII码表示。于是,一些欧洲国家就决定,利用字节中闲置的最高位编入新的符号。比如,法语中的é的编码为130(二进制10000010)。这样一来,这些欧洲国家使用的编码体系,可以表示最多256个符号。
它们造成的结果是:1)出现了unicode的多种存储方式,也就是说有许多种不同的二进制格式,可以用来表示unicode。2)unicode在很长一段时间内无法推广,直到互联网的出现。

[Charset]UTF-8, UTF-16, UTF-16LE, UTF-16BE的区别

[Charset]UTF-8, UTF-16, UTF-16LE, UTF-16BE的区别

[Charset]UTF-8, UTF-16, UTF-16LE, UTF-16BE的区别最近遇到的麻烦事charset里的问题, 一般我们都用unicode来作为统一编码, 但unicode也有多种表现形式首先, 我们说的unicode, 其实就是utf-16, 但最通用的却是utf-8,原因: 我猜大概是英文占的比例比较大, 这样utf-8的存储优势比较明显, 因为utf-16是固定16位的(双字节), 而utf-8则是看情况而定, 即可变长度, 常规的128个ASCII只需要8位(单字节), 而汉字需要24位UTF-16, UTF-16LE, UTF-16BE, 及其区别BOM同样都是unicode, 为什么要搞3种这么麻烦?先说UTF-16BE (big endian), 比较好理解的, 俗称大头比如说char 'a', ascii为0x61, 那么它的utf-8, 则为[0x61], 但utf-16是16位的, 所以为[0x00, 0x61]再说UTF-16LE(little endian), 俗称小头, 这个是比较常用的还是char 'a', 它的代码却反过来: [0x61, 0x00], 据说是为了提高速度而迎合CPU的胃口, CPU就是这到倒着吃数据的, 这里面有汇编的知识, 不多说然后说UTF-16, 要从代码里自动判断一个文件到底是UTF-16LE还是BE, 对于单纯的英文字符来说还比较好办, 但要有特殊字符, 图形符号, 汉字, 法文, 俄语, 火星语之类的话, 相信各位都很头痛吧, 所以, unicode组织引入了BOM的概念, 即byte order mark, 顾名思义, 就是表名这个文件到底是LE还是BE的,其方法就是, 在UTF-16文件的头2个字节里做个标记: LE [0xFF, 0xFE], BE [0xFE, 0xFF]理解了这个后, 在java里遇到utf-16还是会遇到麻烦, 因为要在文件里面单独判断头2个再字节是很不流畅的小结:Java代码1. 如果这个UTF-16文件里带有BOM的话, charset就用"UTF-16", java会自动根据BOM判断LE还是BE, 如果你在这里指定了"UTF-16LE"或"UTF-16BE"的话, 猜错了会生成乱七八糟的文件, 哪怕猜对了, java也会把头2个字节当成文本输出给你而不会略过去, 因为[FF FE]或[FE FF]这2个代码没有内容, 所以, windows会用"?"代替给你2. 如果这个UTF-16文件里不带BOM的话, 则charset就要用"UTF-16LE"或"UTF-16BE"来指定LE还是BE的编码方式另外, UTF-8也有BOM的, [0xEF, 0xBB, 0xBF], 但可有可无, 但用windows的notepad另存为时会自动帮你加上这个, 而很多非windows平台的UTF8文件又没有这个BOM, 真是难为我们这些程序员啊错误的例子1. 文件A, UTF16格式, 带BOM LE,InputStreamReader reader=new InputStreamReader(fin, "utf-16le")会多输出一个"?"在第一个字节, 原因: java没有把头2位当成BOM2. 文件A, UTF16格式, 带BOM LE,InputStreamReader reader=new InputStreamReader(fin, "utf-16be")会出乱码, 原因: 字节的高低位弄反了, 'a' 在文件里[0x61, 0x00], 但java以为'a'应该是[0x00 0x61]3. 文件A, UTF16格式, 带BOM BE,InputStreamReader reader=new InputStreamReader(fin, "utf-16le")会出乱码, 原因: 字节的高低位弄反了, 'a' 在文件里[0x00, 0x61], 但java以为'a'应该是[0x61 0x00]4. 文件A, UTF16格式, 带BOM BE,InputStreamReader reader=new InputStreamReader(fin, "utf-16be")会多输出一个"?"在第一个字节, 原因: java没有把头2位当成BOM5. 文件A, UTF16格式, LE 不带BOM,InputStreamReader reader=new InputStreamReader(fin, "utf-16")会出乱码, 因为utf-16对于java来说, 默认为be(1.6JDK, 以后的说不准)但windows的notepad打开正常, 因为notepad默认为le, - -#6. 文件A, UTF16格式, BE 不带BOM,InputStreamReader reader=new InputStreamReader(fin, "utf-16")恭喜你, 蒙对了但winodws的notepad打开时, 每个字符中间都多了一个" ", 因为notepad把它当成ASNI 了在windows下输出unicode文件通过java出来unicode文件, 也容易混淆Java代码1. charset为"UTF-16"时, java会默认添加BOM [0xFE, 0xFF], 并以BE的格式编写byte2. charset为"UTF-16BE"时, java不会添加BOM, 但编码方式为BE3. charset为"UTF-16LE"时, java不会添加BOM, 但编码方式为LE以上通过test.getByte("utf-16"), test.getByte("utf-16be"), test.getByte("utf-16le") 可以验证而windows的notepad默认的unicode为LE, 并带BOM,所以, 推荐输出UTF-16LE, 并人为添加BOM, 即:Java代码。

Unicode和UTF-8之间的转换

Unicode和UTF-8之间的转换

Unicode和UTF-8之间的转换⼀、引⾔通过这⼏天的研究,终于明⽩了Unicode和UTF-8之间编码的区别。

Unicode是⼀个字符集,⽽UTF-8是Unicode的其中⼀种,Unicode是定长的都为双字节,⽽UTF-8是可变的,对于汉字来说Unicode占有的字节⽐UTF-8占⽤的字节少1个字节。

Unicode为双字节,⽽UTF-8中汉字占三个字节。

注: Unicode编码⽬前规划的总空间是17个平⾯,0x0000 ⾄ 0x10FFFF。

每个平⾯有 65536 个码点。

因此这个总的长度也有⼀百多万个。

⼆、UTF-8 UTF-8编码字符理论上可以最多到6个字节长,然⽽16位BMP(Basic Multilingual Plane)字符最多只⽤到3字节长。

下⾯看⼀下UTF-8编码表:1 U-00000000 - U-0000007F: 0xxxxxxx23 U-00000080 - U-000007FF: 110xxxxx 10xxxxxx45 U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx67 U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx89 U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx1011 U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx xxx 的位置由字符编码数的⼆进制表⽰的位填⼊,越靠右的 x 具有越少的特殊意义,只⽤最短的那个⾜够表达⼀个字符编码数的多字节串。

注意在多字节串中,第⼀个字节的开头"1"的数⽬就是整个串中字节的数⽬。

utf8 16 进制 编码转换中文

utf8 16 进制 编码转换中文

标题:深度探讨UTF-8 16进制编码转换中文的全面指南在当今数字化时代,我们经常会遇到各种编码转换的需求,特别是在处理中文字符时。

而UTF-8编码作为一种最为常见的字符编码方式,其16进制编码转换中文的方法也成为了不可或缺的知识点。

在本文中,我将全面探讨UTF-8 16进制编码转换中文的相关知识,并为你提供深度和广度兼具的指南。

1. 了解UTF-8编码我们需要了解UTF-8编码的基本概念。

UTF-8是一种针对Unicode的可变长度字符编码,它可以将Unicode码点映射成1到4个字节,从而表示不同的字符。

在UTF-8编码中,中文字符通常采用3个字节进行存储,而其16进制编码则是以\x开头的形式表示。

中文字符“中”在UTF-8编码中的16进制表示为E4B8AD。

2. UTF-8 16进制编码转换中文接下来,让我们深入探讨UTF-8 16进制编码如何转换为中文字符。

在实际操作中,我们可以通过将16进制编码按照每两个字符一组进行分割,并使用特定的工具或代码进行转换,从而得到对应的中文字符。

对于16进制编码E4B8AD,我们可以通过将其分割为E4、B8、AD,并依次转换为相应的中文字符,即“中”。

3. 深入理解16进制编码转换原理我们还需要深入理解16进制编码转换的原理。

在计算机中,16进制编码是一种表示数字的进制方式,它将数字分割为16个等份,分别用0~9和A~F表示。

当我们将16进制编码转换为中文字符时,实际上是将一系列数字按照特定规则进行映射和转换,从而得到最终的中文字符。

4. 个人观点和理解就我个人而言,对于UTF-8 16进制编码转换中文的理解是非常重要的。

在实际工作中,我经常会遇到需要处理中文字符编码的情况,而对于UTF-8编码的深入理解和熟练运用,可以极大地提高工作效率和数据处理的准确性。

我认为掌握UTF-8 16进制编码转换中文的方法是非常有价值的。

总结回顾通过本文的全面探讨,我们对于UTF-8 16进制编码转换中文有了更深入的理解。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

概念
先说一说基本的概念,这包括什么是Unicode,什么是UTF-8,什么是UTF-16。

Unicode,UTF-8,UTF-16完整的说明请参考Wiki(Unicode,UTF-8,UTF-16)。

用比较简单的话来说就是,Unicode定义了所有可以用来表示字符的数值集合(称之为Code Point)。

UTF-8和UTF-16等UTF标准定义了这些数值和字符的映射关系。

UTF-8
优势
UTF-8最大的优势是,没有字节序的概念。

所以特别适合用于字符串的网络数据传输,不用考虑大小端问题。

劣势
本地字符串处理过程中,如果使用UTF-8,对于英文字符的处理没有太大的问题。

一个char 变量表示一个英文字符。

但是对于中文等远东字符集来说,就比较坑爹了。

char str[]; str[0]并不能完整表示一个汉字。

UTF-8编码格式下,一个汉字需要至少3个char才能表示。

这对于通过下标来操作字符串的操作来说是非常痛苦的一件事情。

另外,一个汉字需要至少3个char来表示,也让汉字在网络传输上存在劣势,占用太多流量。

UTF-16
优势
UTF-16 LE是windows上默认的Unicode编码方式,使用wchar_t表示。

所有wchar_t *类型的字符串(包括硬编码在.h/.cpp里的字符串字面值),VC都自动采用UTF-16的编码(字符串字面值,literal string,存在很多坑。

特别是char *类型的字面值,最终内存使用何种编码方式完全取决于当前文件的编码方式。

也就是说当前文件如果是GBK编码的,那么文件里char * str = "中午",str指向的内存字符串二进制是使用GBK编码的。

如果文件编码是UTF-8,那么内存是使用UTF-8编码。

所以为什么一直要强调字符串应该放在资源文件里,而不是硬编码在.h/.cpp文件里!)。

UTF-16另外一个优势就是常用字符都可以使用两个个字节表示,也就是一个wchar_t(这里指Windows平台)。

所以,在Windows平台上,特别适合使用wchar_t来作为字符串的存储基类型。

一个wchar_t表示一个字符。

操作使用非常方便。

劣势
没有统一的表示UTF-16编码的字符类型。

C++98/03里对wchar_t的定义是非常宽泛的。

这导致在Windows平台上,wchar_t是2字节的;在Unix-like系统上是4字节的。

代码移植上,可能会遇到挑战(我没移植过,所以不确定会有什么难度,以及难度有多大)。

即使最新的C++11里已经定义除了char16_t表示UTF-16,MS的VS2013还不支持char16_t。

所以目前使用char16_t还不具移植性。

据我了解,UTF-16编码和GBK编码相比,还存在一个排序的劣势。

也就是说,如果要按照
汉语拼音的字母顺序对汉字进行排序,GBK会得到正确的结果,而UTF-16就不行(暂时我还没这种需求,所以我没验证过,不过好像我马上就要与到这种需求了,到时候我再验证下)。

UTF-16编码字符串的网络传输,要考虑大小端的问题。

UTF-32
优势
这个优势就明显了,所有字符都是4字节,fix-length。

一个wchar_t(Unix-like系统上)表示一个字符。

劣势
对于以英文为主的字符串来说,空间消耗大。

面临和上面UTF-16一样的问题。

一致性,排序,网络传输。

char32_t VS2013还不支持(甚至VS 14 CPT也没打算支持)。

总结
UTF-8最适合用来作为字符串网络传输的编码格式。

UTF-16最适合当作本地字符串编码格式。

如果定义好了网络传输协议,那么UTF-16也非常合适当作网络字符串传输的编码格式,特别是中文等远东地区字符集。

比起UTF-8来说,节省流量。

UTF-32没什么特殊癖好或者需求的话,暂时还用不上。

相关文档
最新文档