关于ANSI 和 Unicode

关于ANSI和Unicode

1.ANSI

  American National Standards Institute(美国国家标准学会),ANSI编码不是一种具体的编码方式,而是一种指定在某些环境下使用某些编码方式的标准。

1.1 ASCII码

  English环境下,ANSI编码标准为ASCII;ASCII码一共规定了128个字符的编码,比如空格"SPACE"是32(二进制00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的1位统一规定为0。

1.2 非ASCII码

  非ASCII码是在ASCII码的基础上进行扩展,通常使用 0x80~0xFF 范围的 2 个字节来表示 1 个字符。

  在中文环境中ANSI的编码标准为GBK;

  在在日文环境下,ANSI 编码标准为JIS ;

  在台湾繁体环境下,ANSI编码标准为Big5,etc.

1.3 ANSI标准的弊端

  不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中,也就是说,ANSI标准是一种统称,当不同环境的ANSI编码汇聚到一起时,还要知道是哪一国的语言才能进行解析。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。为什么电子邮件常常出现乱码?就是因为发信人和收信人使用的编码方式不一样。

2. Unicode

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

  Unicode有多种编码方式,例如:UTF-8UTF-16UTF-32 (UTF是“UCS Transformation Format”的缩写,可以翻译成Unicode字符集转换格式,即怎样将Unicode定义的数字转换成程序数据)

2.1 UTF-8

  互联网的普及,强烈要求出现一种统一的编码方式。UTF-8就是在互联网上使用最广的一种Unicode的实现方式。其他实现方式还包括UTF-16(字符用两个字节或四个字节表示)和UTF-32(字符用四个字节表示),不过在互联网上基本不用。重复一遍,这里的关系是,UTF-8是Unicode的实现方式之一。

   UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。

   UTF-8的编码规则很简单,只有二条:

     1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。

     2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

下表总结了编码规则,字母x表示可用编码的位。

           Unicode符号范围 | UTF-8编码方式
               (十六进制) | (二进制)
--------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx   2个字节,第一个字节的前2位设为1,第3位设为0,后面字节的前2位设为10
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx    3个字节,第一个字节的前3位设为1,第4位设为0,后面字节的前2位设为10
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx    4个字节,第一个字节的前4位设为1,第5位设为0,后面字节的前2位设为10

  跟据上表,解读UTF-8编码非常简单。如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。

下面,还是以汉字"严"为例,演示如何实现UTF-8编码。

已知"严"的unicode是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800-0000 FFFF),因此"严"的UTF-8编码需要三个字节,即格式是"1110xxxx 10xxxxxx 10xxxxxx"。然后,从"严"的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,"严"的UTF-8编码是"11100100 10111000 10100101",转换成十六进制就是E4B8A5。

2.2 UTF-16

  把Unicode字符集的抽象码位映射为16位长的整数(即码元)的序列,用于数据存储或传递。Unicode字符的码位,需要1个或者2个16位长的码元来表示,因此这是一个变长表示。UTF-16的大尾序和小尾序储存形式都在用。一般来说,以Macintosh制作或储存的文字使用大尾序格式,以Microsoft或Linux制作或储存的文字使用小尾序格式。为了弄清楚UTF-16文件的大小尾序,在UTF-16文件的开首,都会放置一个U+FEFF字符作为Byte Order Mark(UTF-16LE以FF FE代表,UTF-16BE以FE FF代表),以显示这个文字档案是以UTF-16编码,其中U+FEFF字符在UNICODE中代表的意义是ZERO WIDTH NO-BREAK SPACE,顾名思义,它是个没有宽度也没有断字的空白。

2.3 UTF-32

  UTF-32 (或 UCS-4)是一种将Unicode字符编码的协定,对每一个Unicode码位使用恰好32位元。其它的Unicode transformation formats则使用不定长度编码。因为UTF-32对每个字符都使用4字节,就空间而言,是非常没有效率的。特别地,非基本多文种平面的字符在大部分文件中通常很罕见,以致于它们通常被认为不存在占用空间大小的讨论,使得UTF-32通常会是其它编码的二到四倍。虽然每一个码位使用固定长定的字节看似方便,它并不如其它Unicode编码使用得广泛。

另外,附上汉字Unicode编码表:http://www.chi2ko.com/tool/CJK.htm

时间: 2024-10-30 10:01:30

关于ANSI 和 Unicode的相关文章

ANSI与Unicode的转换

最近遇到中文路径访问的问题,又重新学习了一遍ansi与Unicode的知识,博文记录下来以供后续参考. ANSI 编码 ANSI是一种字符代码,为使计算机支持更多语 言,通常使用0x80~0xFF 范围的2 个字节来表示1 个字符.不同的国家和地区制定了不同的标准,由此产生了GB2312.GBK.GB18030.Big5.Shift_JIS 等各自的编码标准. 这些使用多个字节来代表一个字符的各种汉字延伸编码方式,称为ANSI 编码. 关于MBCS字符集(Multi Byte Character

Visual C++一定要注意ANSI和UNICODE的区别

最近在学习VC++,下载了VS2013,照着<Visual C++开发实战宝典>的第一个hello例程写了个例子,结果出现编辑框乱码的问题.晚上一直在折腾类型的转化,后来总结才明白了是ANSI和UNICODE的区别.老教程刚出的时候,这些控件接口都是ANSI的格式,而现在都统一成了UNICODE了. void ChelloDlg::OnBnClickedOk() { CString csPlus; //定义字符串变量 CString csSummand; m_PlusNumber.GetWin

关于ASCII、GB231、GBK、UTF-8/UTF8、ANSI、unicode的学习笔记

继续上次的学习内容,写一些自己学习的笔记吧!总是觉得没有笔记的学习总是不那么踏实,我承认自己是个记忆力很差的人,特别羡慕那些可以把自己学过的东西记得很牢靠的人.哎!可惜我不是,那只能做出来点东西,就算以后忘了,回过头来可以看一看,有东西查:毕竟是自己亲手打出来的一个一个字啊 已经一万六千字了!嘿嘿...继续加油! 今天公司网络有问题,说是让在家里上班,skype在线就行了.结果我这自觉性不够,就打酱油了!还是继续学习我的mysql吧!我是刚毕业的大学生,学的和写的都是一些最基础的,如果巧遇大牛,

c++ ANSI、UNICODE、UTF8互转

static std::wstring MBytesToWString(const char* lpcszString);    static std::string WStringToMBytes(const wchar_t* lpwcszWString);    static std::wstring UTF8ToWString(const char* lpcszString);    static std::string WStringToUTF8(const wchar_t* lpwcs

多字符集(ANSI)和UNICODE及字符串处理方式准则

在我们编写程序的时候,使用最多的是字符串的处理,而ANSI和UNICODE的相互转换经常搞的我们头晕眼乱. 应该说UNICODE是一种比较好的编码方式,在我们的程序中应该尽量使用UNICODE编码方式,我们在编写程序的时候,最好能依据下面的准则来进行: 基本准则: 1.将文本字符串想象为字符数组,而非char或字节数组 2.开始使用通用数据类型来表示文本字符和字符串(如TCHAR,PTSTR) 原因是我们可以在WinNT.h的头文件中找到如下定义(代码有删改): [cpp] view plain

ANSI转UNICODE,UNICODE转ANSI

(1)ANSI转UNICODE wchar_t * AnsiToUnicode(const char *pAnsi) {     int nLen = MultiByteToWideChar(CP_ACP,0,pAnsi,strlen(pAnsi),nullptr,0);     wchar_t *pUnicode = new wchar_t[nLen+1];     MultiByteToWideChar(CP_ACP,0,pAnsi,strlen(pAnsi),pUnicode,nLen);

ANSI和UNICODE编程的注意事项

建立UNICODE编码工程 在VC60下,默认方式下建立的是ANSI编码的工程(注:编译的exe内部,其资源字符是以UNICODE保存),建立UNICODE编码工程的方法: 1.为工程添加UNICODE和_UNICODE预处理选项.   具体步骤:打开[工程]->[设置-]对话框,在C/C++标签对话框的"预处理程序定义"中去除_MBCS,加上_UNICODE,UNICODE.(注意中间用逗号隔开). 在没有定义UNICODE和_UNICODE前,所有函数和类型都默认使用ANSI

Visual C++学习笔记1:一定要注意ANSI和UNICODE差额

最近的研究VC++.下载VS2013,根据<Visual C++开发实战系列>首先hello我写了一个常规样品,结果显示乱码编辑框.夜已经折腾型转变.然后总结很明显ANSI和UNICODE差额. 老教程刚出的时候,这些控件接口都是ANSI的格式,而如今都统一成了UNICODE了. 转载请注明:http://blog.csdn.net/sadshen/article/details/46405637 void ChelloDlg::OnBnClickedOk() { CString csPlus

ANSI与Unicode编码,TCHAR | LPSTR | LPCSTR | LPWSTR | LPCWSTR | LPTSTR | LPCTSTR 的含义

一个字符可以用1-byte表示,即ANSI编码: 一个字符也可用2-bytes表示,即Unicode编码(Unicode其实还包含了更多内容,不止2-bytes). Visual C++支持char和wchar_t作为ANSI和Unicode的原始数据类型. 例如 char cResponse; // 'Y' or 'N' char sUsername[64]; // str* functions 以及 wchar_t cResponse; // 'Y' or 'N' wchar_t sUser