Unicode 编码

25 篇文章 0 订阅
8 篇文章 0 订阅

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

      Unicode 编码系统,可分为编码方式和实现方式两个层次。Unicode用数字0-0x10FFFF   (( {注意,这并不表示最多用三个字节就可以表示unicode字符集,因为字符的唯一数字映射到内存中的编码方案(如UTF-8, UTF-16, UTF-32)会使用可能多于三个字节来对应该唯一数字}  ))    来映射世界上所有文字和符号的字符,最多可以容纳1114112个字符,或者说有1114112个码位。码位就是可以分配给字符的数字。UTF-8、UTF-16、UTF-32都是将数字转换到程序数据的编码方案。

      Unicode 为编码系统, 它的功能是将所有的字符映射到一个唯一的数字上(0-0x10FFFF中), 它的实现方式即如何将 这些数字用内存中的字节表示出来则为 UTF-8, UTF-16, UTF-32等编码方案。

例如在Unicode中:汉字“字”对应的数字是23383(十进制),十六进制表示为5B57。在Unicode中,我们有很多方式将数字23383表示成程序中的数据,包括:UTF-8、UTF-16、UTF-32。UTF是“UCS Transformation Format”的缩写,可以翻译成Unicode字符集转换格式,即怎样将Unicode定义的数字转换成程序数据。例如,“汉字”对应的数字是0x6c49和0x5b57,而编码的程序数据是:

1
2
3
char data_utf8[] = {0xE6, 0xB1, 0x89, 0xE5, 0xAD, 0x97}; // UTF-8编码
char16_t data_utf16[] = {0x6C49, 0x5B57}; // UTF-16编码
char32_t data_utf32[] = {0x00006C49, 0x00005B57}; // UTF-32编码

这里用char、char16_t、char32_t分别表示无符号8位整数,无符号16位整数和无符号32位整数。

UTF-8、UTF-16、UTF-32分别以char、char16_t、char32_t作为编码单位。(注: char16_t 和 char32_t 是 C++ 11 标准新增的关键字。如果你的编译器不支持 C++ 11 标准,请改用 unsigned short 和 unsigned long。)“汉字”的UTF-8编码需要6个字节。“汉字”的UTF-16编码需要两个char16_t,大小是4个字节。“汉字”的UTF-32编码需要两个char32_t,大小是8个字节。根据字节序的不同,UTF-16可以被实现为UTF-16LE或UTF-16BE,UTF-32可以被实现为UTF-32LE或UTF-32BE。

UTF-8

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

Unicode编码(十六进制) 
UTF-8 字节流(二进制)
000000 - 00007F
0xxxxxxx
000080 - 0007FF
110xxxxx 10xxxxxx
000800 - 00FFFF
1110xxxx 10xxxxxx 10xxxxxx
010000 - 10FFFF
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

UTF-8的特点是对不同范围的字符使用不同长度的编码。对于0x00-0x7F之间的字符,UTF-8编码与ASCII编码完全相同。UTF-8编码的最大长度是4个字节。

UTF-16

UTF-16编码以16位无符号整数为单位。我们把Unicode 编码记作U。编码规则如下:
如果U<0x10000,U的UTF-16编码就是U对应的16位无符号整数(为书写简便,下文将16位无符号整数记作WORD)。

.............................................

UTF-32

UTF-32编码以32位无符号整数为单位。Unicode的UTF-32编码就是其对应的32位无符号整数。

 

字节序  字节序有两种,分别是“大端”(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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unicode是一种字符编码标准,用于将字符集中的每个字符映射到唯一的数字值。Go语言内置支持Unicode编码,包括UTF-8、UTF-16和UTF-32编码。 在Go语言中,可以使用rune类型来表示Unicode字符,它实际上是int32类型的别名。可以使用单引号来表示一个字符,例如: ```go var ch rune = '我' fmt.Printf("字符 %c 的Unicode编码是 %U\n", ch, ch) ``` 输出结果: ``` 字符 我 的Unicode编码是 U+6211 ``` 可以使用strconv包中的函数将字符串转换为Unicode编码的rune切片,例如: ```go str := "Hello, 世界" runes := []rune(str) for i := 0; i < len(runes); i++ { fmt.Printf("%c 的Unicode编码是 %U\n", runes[i], runes[i]) } ``` 输出结果: ``` H 的Unicode编码是 U+0048 e 的Unicode编码是 U+0065 l 的Unicode编码是 U+006C l 的Unicode编码是 U+006C o 的Unicode编码是 U+006F , 的Unicode编码是 U+002C 的Unicode编码是 U+0020 世 的Unicode编码是 U+4E16 界 的Unicode编码是 U+754C ``` 需要注意的是,使用range遍历字符串时,得到的是UTF-8编码的字节切片,而不是Unicode字符。如果需要处理Unicode字符,请先将字符串转换为rune切片。例如: ```go str := "Hello, 世界" for _, ch := range str { fmt.Printf("%c 的Unicode编码是 %U\n", ch, ch) } ``` 输出结果: ``` H 的Unicode编码是 U+0048 e 的Unicode编码是 U+0065 l 的Unicode编码是 U+006C l 的Unicode编码是 U+006C o 的Unicode编码是 U+006F , 的Unicode编码是 U+002C 的Unicode编码是 U+0020 世 的Unicode编码是 U+4E16 界 的Unicode编码是 U+754C ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值