`
ggsonic
  • 浏览: 266741 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论
阅读更多
1. Unicode和UTF-8
为了统一全世界各国语言文字和专业领域符号(例如数学符号、乐谱符号)的编码,ISO制定了ISO 10646标准,也称为UCS(Universal Character Set)。UCS编码的长度是31位,可以表示231个字符。如果两个字符编码的高位相同,只有低16位不同,则它们属于一个平面(Plane),所以一个平面由216个字符组成。目前常用的大部分字符都位于第一个平面(编码范围是U-00000000~U-0000FFFD),称为BMP(Basic Multilingual Plane)或Plane 0,为了向后兼容,其中编号为0~256的字符和Latin-1相同。UCS编码通常用U-xxxxxxxx这种形式表示,而BMP的编码通常用U+xxxx这种形式表示,其中x是十六进制数字。在ISO制定UCS的同时,另一个由厂商联合组织也在着手制定这样的编码,称为Unicode,后来两家联手制定统一的编码,但各自发布各自的标准文档,所以UCS编码和Unicode码是相同的。

有了字符编码,另一个问题就是这样的编码在计算机中怎么表示。现在已经不可能用一个字节表示一个字符了,最直接的想法就是用四个字节表示一个字符,这种表示方法称为UCS-4或UTF-32,UTF是Unicode Transformation Format的缩写。一方面这样比较浪费存储空间,由于常用字符都集中在BMP,高位的两个字节通常是0,如果只用ASCII码或Latin-1,高位的三个字节都是0。另一种比较节省存储空间的办法是用两个字节表示一个字符,称为UCS-2或UTF-16,这样只能表示BMP中的字符,但BMP中有一些扩展字符,可以用两个这样的扩展字符表示其它平面的字符,称为Surrogate Pair。无论是UTF-32还是UTF-16都有一个更严重的问题是和C语言不兼容,在C语言中0字节表示字符串结尾,库函数strlen、strcpy等等都依赖于这一点,如果字符串用UTF-32存储,其中有很多0字节并不表示字符串结尾,这就乱套了。

UNIX之父Ken Thompson提出的UTF-8编码很好地解决了这些问题,现在得到广泛应用。UTF-8具有以下性质:

编码为U+0000~U+007F的字符只占一个字节,就是0x00~0x7F,和ASCII码兼容。

编码大于U+007F的字符用2~6个字节表示,每个字节的最高位都是1,而ASCII码的最高位都是0,因此非ASCII码字符的表示中不会出现ASCII码字节(也就不会出现0字节)。

用于表示非ASCII码字符的多字节序列中,第一个字节的取值范围是0xC0~0xFD,根据它可以判断后面有多少个字节也属于当前字符的编码。后面每个字节的取值范围都是0x80~0xBF,见下面的详细说明。

UCS定义的所有231个字符都可以用UTF-8编码表示出来。

UTF-8编码最长6个字节,BMP字符的UTF-8编码最长三个字节。

0xFE和0xFF这两个字节在UTF-8编码中不会出现。

具体来说,UTF-8编码有以下几种格式:

U-00000000 – U-0000007F:  0xxxxxxx
U-00000080 – U-000007FF:  110xxxxx 10xxxxxx
U-00000800 – U-0000FFFF:  1110xxxx 10xxxxxx 10xxxxxx
U-00010000 – U-001FFFFF:  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 – U-03FFFFFF:  111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 – U-7FFFFFFF:  1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

第一个字节要么最高位是0(ASCII字节),要么最高两位都是1,最高位之后1的个数决定后面有多少个字节也属于当前字符编码,例如111110xx,最高位之后还有四个1,表示后面有四个字节也属于当前字符的编码。后面每个字节的最高两位都是10,可以和第一个字节区分开。这样的设计有利于误码同步,例如在网络传输过程中丢失了几个字节,很容易判断当前字符是不完整的,也很容易找到下一个字符从哪里开始,结果顶多丢掉一两个字符,而不会导致后面的编码解释全部混乱了。上面的格式中标为x的位就是UCS编码,最后一种6字节的格式中x位有31个,可以表示31位的UCS编码,UTF-8就像一列火车,第一个字节是车头,后面每个字节是车厢,其中承载的货物是UCS编码。UTF-8规定承载的UCS编码以大端表示,也就是说第一个字节中的x是UCS编码的高位,后面字节中的x是UCS编码的低位。

例如U+00A9(©字符)的二进制是10101001,编码成UTF-8是11000010 10101001(0xC2 0xA9),但不能编码成11100000 10000010 10101001,UTF-8规定每个字符只能用尽可能少的字节来编码

2. Python的ASCII, GB2312, Unicode , UTF-8
ASCII 是一种字符集,包括大小写的英文字母、数字、控制字符等,它用一个字节表示,范围是 0-127 Unicode分为UTF-8和UTF-16。
UTF-8变长度的,最多 6 个字节,小于 127 的字符用一个字节表示,与 ASCII 字符集的结果一样,ASCII 编码下的英语文本不需要修改就可以当作 UTF-8 编码进行处理。
Python 从 2.2 开始支持 Unicode ,函数 decode( char_set )可以实现 其它编码到 Unicode 的转换,函数 encode( char_set )实现 Unicode 到其它编码方式的转换。
比如
("你好").decode( "GB2312")

将得到
u'\u4f60\u597d',

即 "你"和“好"的 Unicode 码分别是 0x4f60 和 0x597d

再用
(u'\u4f60\u597d').encode("UTF-8")

将得到
'\xe4\xbd\xa0\xe5\xa5\xbd'

它是 “你好”的UTF-8编码结果。

python中使用 unicode的关键:unicode是一个类,函数unicode(str,"utf8")从utf8编码(当然也可以是别的编码)的字符串str生成 unicode类的对象,而函数unc.encode("utf8")将unicode类的对象unc转换为(编码为)utf8编码(当然也可以是别的编码)的字符串。于是,编写unicode相关程序,需要做的事情是 * 获取数据(字符串)时,用unicode(str, "utf8")生成unicode对象 * 在程序中仅使用unicode对象,对程序中出现的字符串常量都以u"字符串"的形式书写 * 输出时,可将unicode对象转换为任意编码输出,使用str.encode("some_encoding")

>>> unicode("你好", "utf8")
       u'\u4f60\u597d'

>>> x = _

>>> type(x)

>>> type("你好")

>>> x.encode("utf8")
       '\xe4\xbd\xa0\xe5\xa5\xbd'

>>> x.encode("gbk")
       '\xc4\xe3\xba\xc3'

>>> x.encode("gb2312")
       '\xc4\xe3\xba\xc3'

>>> print x
       你好

>>> print x.encode("utf8")
       你好

>>> print x.encode("gbk")
       ???

以上是测试结果(Ubuntu 6.06,locale为utf8),注意type(x)和type("你好")的区别。从编码上可以看出utf8编码与gbk不同。在utf8的 locale设置下,打印x按该环境变量编码(我猜我猜我猜猜猜),而打印x.encode("gbk")则是乱码。
分享到:
评论

相关推荐

    全面了解mysql中utf8和utf8mb4的区别

    MySQL中的UTF8与UTF8MB4是两种不同的字符编码方式,它们主要的区别在于对Unicode字符集的支持程度。本文将深入探讨这两种编码的区别,以便更好地理解它们在实际应用中的选择。 一、UTF8与UTF8MB4简介 UTF8是...

    MySQL 编码utf8 与 utf8mb4 utf8mb4_unicode_ci 与 utf8mb4_general_ci

    这里我们将深入探讨UTF8和UTF8MB4两种编码格式,以及它们各自的排序规则`utf8mb4_unicode_ci`和`utf8mb4_general_ci`。 首先,UTF-8是一种广泛使用的Unicode字符编码方案,它允许使用1到4个字节来表示不同的字符。...

    utf8.zip_UTF8_VB6 UTF-8_cutf8.cls_utf8解码在线_vb6

    "utf8.zip"这个压缩包包含了VB6中处理UTF-8所需的相关资源。其中,“cutf8.cls”很可能是一个自定义的类模块,用于实现UTF-8编码和解码功能。类模块是一种封装代码的方式,它将相关的方法和属性组合在一起,方便在多...

    UTF8转16进制工具 Utf8ToHex

    标题中的"UTF8转16进制工具 Utf8ToHex"指的是一个能够将UTF-8编码的字符串转换成16进制表示形式的实用工具。描述中提到的例子,中文的“你好”在UTF-8编码下是"\xE4\xBD\xA0\xE5\xA5\xBD",这个就是将UTF-8编码转换...

    CString转UTF8,UTF8转CString

    int len = MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)str_utf8, -1, NULL, 0); wchar_t *wszMulti = new wchar_t[len + 1]; memset(wszMulti, 0, len * 2 + 2); MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)...

    lua-utf8.zip

    Windows版:lua-utf8.dll(若是用在openresty中,openresty版本需使用32位版本,使用64位版本时会报错“lua-utf8.dll 不是有效的 Win32 应用程序”) 将lua-utf8库放在openresty安装目录下,使用时用require引入。

    批量转UTF8工具-批量转UTF8工具

    UTF8编码是目前互联网上最广泛使用的字符编码标准,它能有效地表示世界上几乎所有的文字系统,包括汉字、拉丁字母、希腊字母等。批量转UTF8工具则是针对那些需要将大量文本文件从其他编码格式(如GBK、BIG5等)转换...

    易语言UTF8解码

    易语言UTF8解码是关于在易语言编程环境中处理UTF-8编码的一种技术。UTF-8是一种广泛使用的Unicode字符编码方案,它可以表示Unicode标准中的所有字符。易语言是中国开发的一款面向初学者和专业开发者的编程语言,其...

    Mysql中的排序规则utf8_unicode_ci、utf8_general_ci的区别总结

    用了这么长时间,发现...那么在utf8_bin中你就找不到 txt = ‘A’ 的那一行, 而 utf8_general_ci 则可以. utf8_general_ci 不区分大小写,这个你在注册用户名和邮箱的时候就要使用。 utf8_general_cs 区分大小写,如果

    UTF8 to excel

    标题“UTF8 to excel”指的是将UTF8编码的文本数据转换为Excel电子表格的过程。在IT领域,UTF8是一种广泛使用的字符编码标准,它能够表示几乎所有的世界语言字符,包括中文。Excel是Microsoft Office套件中的一个...

    JS GB2312转UTF8 支持中英文混合

    JS GB2312TOUTF8 UTF8TOGB2312 编码转换 /* * GB2312转UTF8 * 例: * var xx=new GB2312UTF8(); * var Utf8=xx.Gb2312ToUtf8("你aaa好aaaaa"); * var Gb2312=xx.Utf8ToGb2312(Utf8); * ...

    UTF8-无BOM转为UTF16LE

    UTF8的特点是前几个字节用于识别字符的范围,对于ASCII字符(英文字符和某些符号),UTF8只使用一个字节,这使得UTF8在处理英文文本时非常高效。无BOM的UTF8意味着文件开头没有特定的3字节标识符(0xEF, 0xBB, 0xBF...

    utf8与string的相互转换

    original_string = utf8_bytes.decode('utf-8') ``` 在Java中,转换过程类似,但使用`getBytes`和`new String`方法: ```java // 字符串转UTF-8字节数组 byte[] utf8Bytes = myString.getBytes("UTF-8"); // UTF-...

    c语言gbk、utf8转换编码表及函数

    在C语言中,字符编码是非常重要...通过`utf8gbk.h`和`utf8gbk.c`这两个文件,你可以直接在C程序中实现GBK与UTF-8的转换,从而满足项目的需求。不过,要注意,这些函数可能需要根据具体环境和需求进行适当的修改和优化。

    如何更改MySQL数据库的编码为utf8mb4

    MySQL数据库的编码转换至utf8mb4是为了更好地支持Unicode字符集,尤其是对于包含四字节表情符号和其他特殊字符的数据。utf8mb4是utf8的扩展,它不仅完全兼容utf8,还能处理更多的Unicode字符范围,包括现代社交媒体...

    labview text to utf8

    "labview text to utf8" 这个标题表明我们要探讨的是如何在LabVIEW中将包含汉字的字符串转换成UTF-8编码格式,以便在不同系统或平台之间进行兼容的数据传输。 默认情况下,LabVIEW可能会使用本地的字符编码,如ANSI...

    labview utf8toGBK

    "labview utf8toGBK"这个项目就是为了解决这个问题而设计的。 在计算机世界中,文本的表示方式是通过特定的编码系统来实现的。UTF-8和GBK是两种常见的汉字编码格式。UTF-8(8位统一 Transformation Format)是一种...

    TXT批量转UTF8格式

    "TXT批量转UTF8格式"的主题涉及到的是文件编码转换,特别是针对纯文本文件(TXT)的批量处理,将它们从非UTF-8编码转换为UTF-8编码。UTF-8是一种广泛使用的字符编码标准,支持几乎全球所有的字符,包括中文、英文和...

    UTF8_TO_HEX

    标题“UTF8_TO_HEX”指的是一个程序或功能,它的主要任务是将UTF-8编码的字符串转换成拉丁字母(Latin1)编码表示的形式。在计算机领域,字符编码是用来表示文本的一种方式,不同的编码标准适用于不同的语言和地区。...

    批量utf文件转utf8-bom

    "批量utf文件转utf8-bom"这个主题指的是将一批以UTF编码的文件转换为带有BOM(Byte Order Mark)的UTF-8编码。BOM是一个特殊的字节序列,用于标识文件的编码类型,对于UTF-8编码,BOM的字节序列为0xEF, 0xBB, 0xBF。...

Global site tag (gtag.js) - Google Analytics