Unicode、UTF-8与GB2312等编码之间是如何转换的

合集下载

Python的ASCII,GB2312,Unicode,UTF-8相互转换

Python的ASCII,GB2312,Unicode,UTF-8相互转换

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("你好")的区别。

用php实现gb2312和unicode间的编码转换

用php实现gb2312和unicode间的编码转换

⽤php实现gb2312和unicode间的编码转换gb2312 和 unicode 间的编码转换下⾯的例⼦是将 gb2312 转换为 "&#20840;"这种形式php4.3.1以后的iconv函数很好⽤的,只是需要⾃⼰写⼀个uft8到unicode的转换函数查表(gb2312.txt)也⾏复制代码代码如下:<?$text = "";preg_match_all("/[ 80- ff]?./",$text,$ar);foreach($ar[0] as $v)echo "&#".utf8_unicode(iconv("GB2312","UTF-8",$v)).";";><?// utf8 -> unicodefunction utf8_unicode($c) {switch(strlen($c)) {case 1:return ord($c);case 2:$n = (ord($c[0]) & 0x3f) << 6;$n += ord($c[1]) & 0x3f;return $n;case 3:$n = (ord($c[0]) & 0x1f) << 12;$n += (ord($c[1]) & 0x3f) << 6;$n += ord($c[2]) & 0x3f;return $n;case 4:$n = (ord($c[0]) & 0x0f) << 18;$n += (ord($c[1]) & 0x3f) << 12;$n += (ord($c[2]) & 0x3f) << 6;$n += ord($c[3]) & 0x3f;return $n;}}>下⾯的例⼦是利⽤php将"&#20840;"这中编码转换为gb2312.复制代码代码如下:<?php$str = "TTL&#20840;&#22825;&#20505;&#33258;&#21160;&#32858;&#28966;";$str = preg_replace("|&#([0-9]{1,5});|", "\".u2utf82gb(\\1).\"", $str);$str = "\$str=\"$str\";";eval($str);echo $str;function u2utf82gb($c){$str="";if ($c < 0x80) {$str.=$c;} else if ($c < 0x800) {$str.=chr(0xC0 | $c>>6);$str.=chr(0x80 | $c & 0x3F);} else if ($c < 0x10000) {$str.=chr(0xE0 | $c>>12);$str.=chr(0x80 | $c>>6 & 0x3F);$str.=chr(0x80 | $c & 0x3F);} else if ($c < 0x200000) {$str.=chr(0xF0 | $c>>18);$str.=chr(0x80 | $c>>12 & 0x3F);$str.=chr(0x80 | $c>>6 & 0x3F);$str.=chr(0x80 | $c & 0x3F);}return iconv('UTF-8', 'GB2312', $str);}>或者是复制代码代码如下:function unescape($str) {$str = rawurldecode($str);preg_match_all("/(?:%u.{4})|&#x.{4};|&#\d+;|.+/U",$str,$r);$ar = $r[0];print_r($ar);foreach($ar as $k=>$v) {if(substr($v,0,2) == "%u")$ar[$k] = iconv("UCS-2","GB2312",pack("H4",substr($v,-4)));elseif(substr($v,0,3) == "&#x")$ar[$k] = iconv("UCS-2","GB2312",pack("H4",substr($v,3,-1)));elseif(substr($v,0,2) == "&#") {echo substr($v,2,-1)."<br>";$ar[$k] = iconv("UCS-2","GB2312",pack("n",substr($v,2,-1)));}}return join("",$ar);}$str = "TTL&#20840;&#22825;&#20505;&#33258;&#21160;&#32858;&#28966;";echo unescape($str); //out TTL全天候⾃动聚焦利⽤javascript来转换复制代码代码如下:<style>BODY {FONT-SIZE: 9pt; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px; }input {FONT-SIZE: 9pt; height: 13pt;}</style><script language="JavaScript1.2">/*ThisfollowingcodearedesignedandwritenbyWindy_sk<***************>You can use it freely, but u must held all the copyright items!*/function Str2Unicode(str){var arr = new Array();for(var i=0;i<str.length;i++){arr[i]="&#" + str.charCodeAt(i) + ";";}return(arr.toString().replace(/,/g,""));}function Unicode2oStr(str){var re=/&#[\da-fA-F]{1,5};/ig;var arr=str.match(re);if(arr==null)return("");for(var i=0;i<arr.length;i++){arr[i]=String.fromCharCode(arr[i].replace(/[&#;]/g,""));}return(arr.toString().replace(/,/g,""))}function modi_str(){if(document.all.text.method.checked){if(document.all.text.decode.value!=""){document.all.text.encode.value = Str2Unicode(document.all.text.decode.value);}else{document.all.text.decode.value = Unicode2oStr(document.all.text.encode.value);}}else{if(document.all.text.encode.value!=""){document.all.text.decode.value = Unicode2oStr(document.all.text.encode.value);}else{document.all.text.encode.value = Str2Unicode(document.all.text.decode.value);}}}</script><title>Unicode</title><form name=text>⽂本原型:<br><textarea name="decode" cols="100" rows="10"></textarea><br>转换代码:<br><textarea name="encode" cols="100" rows="10"></textarea><br><input type="checkbox" name="method" checked> 正向转换<input type=button onclick="modi_str()" value=" 确定 "><input type=reset value=" 清空 "><input type=button onclick="document.all.text.method.checked?document.all.text.encode.select():document.all.text.decode.select()" value=" 全选 "></form>下⾯是⼀个显⽰所有全⾓半⾓的字体的查看例⼦复制代码代码如下:<style>BODY {FONT-SIZE: 9pt; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px; }input {FONT-SIZE: 9pt; height: 13pt;}</style><script>function showUni(min,max){show.document.open();show.document.writeln("<style>body{font-size:9pt;word-break:break-all;}</style>");show.document.writeln(min + " - " + max + "<br><br>");var i=0;for(i=min;i<=max;i++){show.document.write("&#" + i + ";");}show.document.close();}</script><input type=button value="半⾓" onclick=showUni(32,126)><input type=button value="全⾓" onclick=showUni(65281,65374)><input type=button value="中⽂1" onclick=showUni(19968,40869)><input type=button value="中⽂2" onclick=showUni(63744,64045)><input type=button value="⽇⽂平" onclick=showUni(12353,12435)><input type=button value="⽇⽂⽚" onclick=showUni(12449,12534)><input type=button value="韩⽂" onclick=showUni(44032,55203)><br>⾃定义:<input name=min> - <input name=max><input type=button value="察看" onclick=showUni(parseInt(document.all.min.value),parseInt(document.all.max.value))> <br><iframe src="about:blank" id=show width=100% height=70% scroll=no></iframe>下⾯是⼀个查表(gb2312),转换gb2312到utf8的例⼦, 现在有iconv函数,这个已经没有太⼤的意义了,复制代码代码如下:<?function gb2utf8($gb){if(!trim($gb)) return $gb;$filename="gb2312.txt";$tmp=file($filename);$codetable=array();while(list($key,$value)=each($tmp))$codetable[hexdec(substr($value,0,6))]=substr($value,7,6);$utf8="";while($gb) {if (ord(substr($gb,0,1))>127) {$this=substr($gb,0,2);$gb=substr($gb,2,strlen($gb)-2);$utf8.=u2utf8(hexdec($codetable[hexdec(bin2hex($this))-0x8080]));}else{$this=substr($gb,0,1);$gb=substr($gb,1,strlen($gb)-1);$utf8.=u2utf8($this);}}return $utf8;}function u2utf8($c){$str="";if ($c < 0x80) {$str.=$c;} else if ($c < 0x800) {$str.=chr(0xC0 | $c>>6);$str.=chr(0x80 | $c & 0x3F);} else if ($c < 0x10000) {$str.=chr(0xE0 | $c>>12);$str.=chr(0x80 | $c>>6 & 0x3F);$str.=chr(0x80 | $c & 0x3F);} else if ($c < 0x200000) {$str.=chr(0xF0 | $c>>18);$str.=chr(0x80 | $c>>12 & 0x3F);$str.=chr(0x80 | $c>>6 & 0x3F);$str.=chr(0x80 | $c & 0x3F);}return $str;}>。

汉字机内码转换算法

汉字机内码转换算法

汉字机内码转换算法汉字机内码通常指的是汉字在计算机中的字符编码,常见的编码方式包括GB2312、GBK、UTF-8等。

不同的编码方式使用不同的算法来进行字符的编码和解码。

下面简要介绍一下常见的几种编码方式的算法:1. GB2312编码:- GB2312是一种双字节的编码方式,其中每个字节的范围是0xA1-0xF7,每个字可以用两个字节表示。

-汉字的GB2312编码是通过取得汉字的区位码(高字节是区码,低字节是位码)来确定的。

2. GBK编码:- GBK是对GB2312的扩展,支持更多的汉字字符。

同样是双字节编码,其中有一部分字符的编码与GB2312相同,而其他字符使用了扩展区。

- GBK编码同样通过区位码来表示汉字的位置。

3. UTF-8编码:- UTF-8是一种可变长度的编码方式,用1到4个字节表示一个字符。

ASCII字符使用一个字节表示,而汉字通常使用三个字节表示。

-UTF-8编码的算法是根据字符的Unicode码来确定的,不同的Unicode码对应不同长度的字节序列。

4. UTF-16编码:-UTF-16也是一种可变长度的编码方式,使用2个字节或4个字节表示一个字符,根据字符的Unicode码来确定字节序列。

-对于常见的字符,使用两个字节表示,而罕见字符使用四个字节。

5. UTF-32编码:-UTF-32是一种固定长度的编码方式,使用4个字节表示一个字符,直接使用Unicode 码。

在实际编程中,通常使用现代编程语言提供的库函数来进行字符编码和解码,而不需要手动实现这些算法。

例如,在Python中,可以使用`encode`和`decode`方法来进行字符编码和解码。

在其他语言中也有类似的函数和库。

python中unicode、utf8、gbk等编码问题

python中unicode、utf8、gbk等编码问题

python中unicode、utf8、gbk等编码问题为什么会报错“UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)”?本⽂就来研究⼀下这个问题。

字符串在Python内部的表⽰是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另⼀种编码。

decode的作⽤是将其他编码的字符串转换成unicode编码,如str1.decode('gb2312'),表⽰将gb2312编码的字符串str1转换成unicode编码。

encode的作⽤是将unicode编码转换成其他编码的字符串,如str2.encode('gb2312'),表⽰将unicode编码的字符串str2转换成gb2312编码。

因此,转码的时候⼀定要先搞明⽩,字符串str是什么编码,然后decode成unicode,然后再encode成其他编码代码中字符串的默认编码与代码⽂件本⾝的编码⼀致。

如:s='中⽂'如果是在utf8的⽂件中,该字符串就是utf8编码,如果是在gb2312的⽂件中,则其编码为gb2312。

这种情况下,要进⾏编码转换,都需要先⽤decode⽅法将其转换成unicode编码,再使⽤encode⽅法将其转换成其他编码。

通常,在没有指定特定的编码⽅式时,都是使⽤的系统默认编码创建的代码⽂件。

如果字符串是这样定义:s=u'中⽂'则该字符串的编码就被指定为unicode了,即python的内部编码,⽽与代码⽂件本⾝的编码⽆关。

因此,对于这种情况做编码转换,只需要直接使⽤encode⽅法将其转换成指定编码即可。

ASP UTF-8页面乱码+GB2312转UTF-8 +生成UTF-8格式的文件(编码)

ASP UTF-8页面乱码+GB2312转UTF-8 +生成UTF-8格式的文件(编码)
end if
next
if mysign=-1 then c10to2="-" & c10to2
end function
GB2312转UTF-8
'个人代码风格注释(变量名中第一个小写字母表表示变量类型)
'i:为Integer型;
's:为String;
Function U2UTF8(Byval a_iNum)
以前做网页都是用的GB2312,因为刚开始不太了解,也就没注意这些。Dreamweaver中文版默认的就是简体中文,不写编码类型的话也是如此。然而,现在越来越多的网站采用unicode编码,这样做的好处自然不必多说。但是,要想真正用好utf-8并不是那么容易。下面我就总结一下自己遇到的问题。
首先,要把meta区的charset由gb2312改为utf-8,这点应该没有人不知道吧。在dreamweaver里可以直接设置[页面属性]中的[编码],然后会发现编辑器里的字体已经变了。但仅仅这样做是远远不够的,重要的还在下面。
Dim sResult,sUTF8
Dim iTemp,iHexNum,i
iHexNum = Trim(a_iNum)
If iHexNum = "" Then
Exit Function
End If
sResult = ""
If (iHexNum < 128) Then
sResult = sResult & iHexNum
i=0
for i=ቤተ መጻሕፍቲ ባይዱ0 to len(x) -1
if mid(x,len(x)-i,1)="1" then c2to10=c2to10+2^(i)

UTF-8与GB2312互转方法

UTF-8与GB2312互转方法

第二步:把所有的 <meta http-equiv=Content-Type content=text/html; charset=UTF-8 /> 改成 <meta http-equiv=Content-Type content=text/html; charset=GB2312 /> 再另存为ANSI GB2312
GB2312转UTF-8
第一步:修改 commond.asp 文件,将文件的前4行,也就是 定义 Cookie,Application 域 前面的代码用以下代码替换:<%@LANGUAGE=VBSCRIPT CODEPAGE=65001%> <% Option Explicit Response.Buffer=True Session.CodePage=65001 Server.ScriptTimeOut = 90 然后修改 header.asp 和 admincp.asp 还有 attachment.asp 文件,找到:程序代码:<meta http-equiv=Content-Type content=text/html; charset=GB2312 /> 修改为:程序代码:<meta http-equiv=Content-Type content=text/html; charset=UTF-8 />
UTF-8转GB2sp 文件,将文件的前4行,也就是 定义 Cookie,Application 域 前面的代码用以下代码替换:<%@LANGUAGE=VBSCRIPT CODEPAGE=936%> <% Option Explicit Response.Buffer = True Server.ScriptTimeOut = 90 Session.CodePage=936 参考的是:如果制作的网页脚本与WEB服务端的默认代码页不同,则必须指明代码页:codepage=936 简体中文GBK codepage=950 繁体中文BIG5 codepage=437 美国/加拿大英语 codepage=932 日文 codepage=949 韩文 codepage=866 俄文 codepage=65001 unicode UFT-8

c++字符集之间转换(UTF-8,UNICODE,Gb2312)

c++字符集之间转换(UTF-8,UNICODE,Gb2312)
tmp = rst[j+2] = buf[2];
j += 3;
i += 2;
}
}
rst[j] = ’’;
//返回结果
pOut = rst;
delete[]rst;
return;
}
voidCChineseCode::UTF_8ToGB2312(string &pOut, char*pText, intpLen){
return;
}
voidCChineseCode::UnicodeToGB2312(char* pOut,wchar_tuData){
WideCharToMultiByte(CP_ACP,NULULL,NULL);
return;
}
voidCChineseCode::Gb2312ToUnicode(wchar_t* pOut,char*gbBuffer){
}else{
wchar_tpbuffer;
Gb2312ToUnicode(&pbuffer,pText+i);
UnicodeToUTF_8(buf,&pbuffer);
unsigned shortinttmp = 0;
tmp = rst[j] = buf[0];
tmp = rst[j+1] = buf[1];
};
//类实现
voidCChineseCode::UTF_8ToUnicode(wchar_t* pOut,char*pText){
char* uchar = (char*)pOut;
uchar[1] = ((pText[0] & 0x0F) << 4) + ((pText[1] >> 2) & 0x0F);

【转】【Python】python中的编码问题报错asciicodeccantdecode。。。

【转】【Python】python中的编码问题报错asciicodeccantdecode。。。

【转】【Python】python中的编码问题报错asciicodeccantdecode。

1.unicode、gbk、gb2312、utf-8的关系2.python中的中⽂编码问题2.1 .py⽂件中的编码 Python 默认脚本⽂件都是 ANSCII 编码的,当⽂件中有⾮ ANSCII 编码范围内的字符的时候就要使⽤"编码指⽰"来修正。

⼀个module 的定义中,如果.py⽂件中包含中⽂字符(严格的说是含有⾮anscii字符),则需要在第⼀⾏或第⼆⾏指定编码声明:2.2 python中的编码与解码 先说⼀下python中的字符串类型,在python中有两种字符串类型,分别是str和unicode,他们都是basestring的派⽣类;str类型是⼀个包含Characters represent (at least) 8-bit bytes的序列;unicode的每个unit是⼀个unicode obj;所以:len(u'中国')的值是2;len('ab')的值也是2; 在str的⽂档中有这样的⼀句话:The string data type is also used to represent arrays of bytes, e.g., to hold data read from a file. 也就是说在读取⼀个⽂件的内容,或者从⽹络上读取到内容时,保持的对象为str类型;如果想把⼀个str转换成特定编码类型,需要把str转为Unicode,然后从unicode转为特定的编码类型如:utf-8、gb2312等;python中提供的转换函数:unicode转为 gb2312,utf-8等# -*- coding=UTF-8 -*-if __name__ == '__main__':s = u'中国's_gb = s.encode('gb2312')utf-8,GBK转换为unicode 使⽤函数unicode(s,encoding) 或者s.decode(encoding)# -*- coding=UTF-8 -*-if __name__ == '__main__':s = u'中国'#s为unicode先转为utf-8s_utf8 = s.encode('UTF-8')assert(s_utf8.decode('utf-8') == s)普通的str转为unicode# -*- coding=UTF-8 -*-if __name__ == '__main__':s = '中国'su = u'中国''#s为unicode先转为utf-8#因为s为所在的.py(# -*- coding=UTF-8 -*-)编码为utf-8s_unicode = s.decode('UTF-8')assert(s_unicode == su)#s转为gb2312,先转为unicode再转为gb2312s.decode('utf-8').encode('gb2312')#如果直接执⾏s.encode('gb2312')会发⽣什么?s.encode('gb2312')# -*- coding=UTF-8 -*-if __name__ == '__main__':s = '中国'#如果直接执⾏s.encode('gb2312')会发⽣什么?s.encode('gb2312')这⾥会发⽣⼀个异常:Python 会⾃动的先将 s 解码为 unicode ,然后再编码成 gb2312。

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"的数⽬就是整个串中字节的数⽬。

将编码从GB2312转成UTF-8的方法汇总

将编码从GB2312转成UTF-8的方法汇总

将编码从GB2312转成UTF-8的方法汇总一个网站如果需要国际化,就需要将编码从GB2312转成UTF-8,其中有很多的问题需要注意,如果没有转换彻底,将会有很多的编码问题出现!主要有五个方面:一..HTML页面转UTF-8编码问题二.PHP页面转UTF-8编码问题三.MYSQL数据库使用UTF-8编码的问题四.JS相关的UTF-8编码问题五.FLASH相关的UTF-8编码问题一.HTML页面转UTF-8编码问题1.在后,之间有中文字符的话,显示的标题有可能是乱码!2.html文件编码问题:点击编辑器的菜单:“文件”->“另存为”,可以看到当前文件的编码,确保文件编码为:UTF-8,如果是ANSI,需要将编码改成:UTF-8。

3.HTML文件头BOM问题:将文件从其他的编码转换成UTF-8编码时,有时候会在文件的最开始加上一个BOM标签,在个BOM标签可能会导致浏览器在显示中文的时候出现乱码。

删除这个BOM标签的方法:1.可以用Dreamweaver打开文件,并重新保存,即可以去除BOM标签!2.可以用EditPlus打开文件,并在菜单“首选项”->“文件”->"UTF-8标识",设置为:“总是删除签名”,然后保存文件,即可以去除BOM标签!4.WEB服务器UTF-8编码问题:如果你按以上所列的步骤做了,还是有中文乱码问题,请检查你的所使用的WEB服务器的编码问题如果你使用的是Apache,请将配置文件里的:charset 设成:utf-8(这里仅列出方法,具体格式请参考apache的配置文件)。

如果你使用的是Nginx,请将nginx.conf里的:charset 设成utf-8,具体找到"charset gb2312;"或者类似的语句,改成:“charset utf-8;”。

二.PHP页面转UTF-8编码问题1.在代码开始出加入一行:header("Content-Type: text/html;charset=utf-8");2.PHP文件编码问题点击编辑器的菜单:“文件”->“另存为”,可以看到当前文件的编码,确保文件编码为:UTF-8,如果是ANSI,需要将编码改成:UTF-8。

UTF8转成GB2312乱码问题解决方案

UTF8转成GB2312乱码问题解决方案

最近做了一个小项目,遇到此类问题,记录一下,也算是一个总结。

此项目分为两部分,一个是新闻数据采集,一个是采集信息的审核,最后生成XML文件。

数据采集后的数据经过用户编辑完之后,要导出一个ACCESS文件,然后把这个文件导入到信息审核系统。

在ACCESS库中存储新闻信息的字段类型是ntext类型,而审核系统库中对应的是varchar(max)类型的字段,导入之后,发现有的空白字符会出现乱码,表现为问号(?),其实经过后面的测试,这不是空白(空格)字符,而一个特殊字符,怎么办?经过几番测试后发现,varchar(max)类型要改成nvarchar(max)类型,这样导入的数据就不会再有此类问题了。

但后面的测试过程中,又会发现对导入后的采集信息更改(通过.net程序编辑功能)后,数据库中此条信息又出现了乱码问题,研究后发现在插入语句中这样写就不会出现此类问题了,如insert into 表名(news)values(N'"+更新后的值+""),为什么加N?去百度一下就明白了。

到此,心中总算得到安慰,但后面的问题又让人陷入郁闷之中。

审核完的信息要生成XML类型的文件,并且XML要采用GB2312编码,因为采集的新闻网站,有很多网站采用的是UTF8编码,这样在转化的过程中又出现乱码(还是那个“空白”特殊字符搞的),怎么办?网上介绍的把UTF8转化成GB2312就可以了,但实际发现,还是解决不了问题,这下弄的一上午为了解决这个问题,最后还是没有办法,正郁闷之时,突然想到通过VS的调试功能来看看这个特殊字符究竟是什么玩意,最后通过把数据库的此字段值读取出来之后,然后转化成字符数组,content.ToCharArray(); 一个一个的看,发现,导致乱码的这个字符是' '注意引号中的空白,这不是一个空格,而是一个在GB2312中无法识别的特殊字符,此时突然想到,能不能把这个字符的值直接用空格替换呢?马上行动,果然,解决了乱码问题。

utf8编码互相转换 -回复

utf8编码互相转换 -回复

utf8编码互相转换-回复UTF-8编码互相转换是指将文本从UTF-8编码转换为其他编码,或从其他编码转换为UTF-8编码。

UTF-8是一种变长的编码方式,能够表示全球范围内的字符,它在网络传输和存储中被广泛使用。

本文将以UTF-8编码互相转换为主题,一步一步地回答如何进行转换的方法。

首先,我们需要先了解UTF-8编码的基本知识。

UTF-8编码是用于表示Unicode字符的一种变长编码方式,它能够表示从U+0000到U+10FFFF的所有字符。

UTF-8编码使用1到4个字节来表示一个字符,其中ASCII字符(U+0000到U+007F)使用1个字节表示,而其他字符使用2到4个字节表示。

一、将文本从UTF-8编码转换为其他编码:1. 确定目标编码:首先,我们需要确定要将UTF-8编码转换为的目标编码。

常见的目标编码包括UTF-16、UTF-32、GB2312、GBK等。

2. 使用编程语言提供的函数或库:大多数编程语言都提供了函数或库来进行编码转换。

例如,在Python中,可以使用`decode`函数将UTF-8编码的文本转换为其他编码,如下所示:pythonutf8_text = b'\xe4\xbd\xa0\xe5\xa5\xbd' # UTF-8编码的文本target_encoding = 'GBK' # 目标编码decoded_text = utf8_text.decode('utf-8').encode(target_encoding)这里首先使用`decode`函数将UTF-8编码的文本解码为Unicode字符串,然后再使用`encode`函数将Unicode字符串编码为目标编码。

3. 确认转换结果:转换完成后,可以使用目标编码来确认转换结果是否正确。

例如,可以将转换后的文本写入文件或发送到其他系统中,并确保目标系统能够正确解析该文本。

二、将文本从其他编码转换为UTF-8编码:1. 确定原始编码:首先,我们需要确定要将其他编码转换为UTF-8编码的原始编码。

汉字编码对照表(gb2312unicodeutf8)

汉字编码对照表(gb2312unicodeutf8)

汉字编码对照表(gb2312unicodeutf8)⼀、汉字编码的种类汉字编码中现在主要⽤到的有三类,包括GBK,GB2312和Big5。

1、GB2312⼜称国标码,由国家标准总局发布,1981年5⽉1⽇实施,通⾏于⼤陆。

新加坡等地也使⽤此编码。

它是⼀个简化字的编码规范,当然也包括其他的符号、字母、⽇⽂假名等,共7445个图形字符,其中汉字占6763个。

我们平时说6768个汉字,实际上⾥边有5个编码为空⽩,所以总共有6763个汉字。

GB2312规定“对任意⼀个图形字符都采⽤两个字节表⽰,每个字节均采⽤七位编码表⽰”,习惯上称第⼀个字节为“⾼字节”,第⼆个字节为“低字节”。

GB2312中汉字的编码范围为,第⼀字节0xB0-0xF7(对应⼗进制为176-247),第⼆个字节0xA0-0xFE(对应⼗进制为160-254)。

GB2312将代码表分为94个区,对应第⼀字节(0xa1-0xfe);每个区94个位(0xa1-0xfe),对应第⼆字节,两个字节的值分别为区号值和位号值加32(2OH),因此也称为区位码。

01-09区为符号、数字区,16-87区为汉字区(0xb0-0xf7),10-15区、88-94区是有待进⼀步标准化的空⽩区。

2、Big5⼜称⼤五码,主要为⾹港与台湾使⽤,即是⼀个繁体字编码。

每个汉字由两个字节构成,第⼀个字节的范围从0X81-0XFE(即129-255),共126种。

第⼆个字节的范围不连续,分别为0X40-0X7E(即64-126),0XA1-0XFE(即161-254),共157种。

3、GBK是GB2312的扩展,是向上兼容的,因此GB2312中的汉字的编码与GBK中汉字的相同。

另外,GBK中还包含繁体字的编码,它与Big5编码之间的关系我还没有弄明⽩,好像是不⼀致的。

GBK中每个汉字仍然包含两个字节,第⼀个字节的范围是0x81-0xFE(即129-254),第⼆个字节的范围是0x40-0xFE(即64-254)。

MySQL字符集GBK、GB2312、UTF8区别解决MYSQL中文乱码问题

MySQL字符集GBK、GB2312、UTF8区别解决MYSQL中文乱码问题

MySQL字符集GBK、GB2312、UTF8区别解决MYSQL中⽂乱码问题character-set-server/default-character-set:服务器字符集,默认情况下所采⽤的。

character-set-database:数据库字符集。

character-set-table:数据库表字符集。

优先级依次增加。

所以⼀般情况下只需要设置character-set-server,⽽在创建数据库和表时不特别指定字符集,这样统⼀采⽤character-set-server字符集。

character-set-client:客户端的字符集。

客户端默认字符集。

当客户端向服务器发送请求时,请求以该字符集进⾏编码。

character-set-results:结果字符集。

服务器向客户端返回结果或者信息时,结果以该字符集进⾏编码。

在客户端,如果没有定义character-set-results,则采⽤character-set-client字符集作为默认的字符集。

所以只需要设置character-set-client字符集。

要处理中⽂,则可以将character-set-server和character-set-client均设置为GB2312,如果要同时处理多国语⾔,则设置为UTF8。

解决乱码的⽅法是,在执⾏SQL语句之前,将MySQL以下三个系统参数设置为与服务器字符集character-set-server相同的字符集。

character_set_client:客户端的字符集。

character_set_results:结果字符集。

character_set_connection:连接字符集。

设置这三个系统参数通过向MySQL发送语句:set names gb2312UTF-8:Unicode Transformation Format-8bit,允许含BOM,但通常不含BOM。

是⽤以解决国际上字符的⼀种多字节编码,它对英⽂使⽤8位(即⼀个字节),中⽂使⽤24为(三个字节)来编码。

Unicode、UTF-8与GB2312等编码之间是如何转换的

Unicode、UTF-8与GB2312等编码之间是如何转换的

Unicode、UTF-8与GB2312等编码之间是如何转换的字符编码是运算机技术的基石,想要熟练使用运算机,就必须明白得字符编码的知识。

不注意的人可能对那个不在意,但这些名词有时候实在让人困惑,对想学习运算机知识的人来说,搞明白它也十分重要,我也是在学习中慢慢了解了一些这方面的知识。

1. ASCII码在运算机内部,所有的信息最终都表示为一个二进制的字符串。

每一个二进制位〔bit〕有0和1两种状态,因此八个二进制位就能够组合出256种状态,这被称为一个字节〔byte〕。

也确实是说,一个字节一共能够用来表示256种不同的状态,每一个状态对应一个符号,确实是256个符号,从0000000到11111111。

上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。

这被称为ASCII码,一直沿用至今。

ASCII码一共规定了128个字符的编码,比如空格〝SPACE〞是32〔十进制的32,用二进制表示确实是00100000〕,大写的字母A是65〔二进制01000001〕。

这128个符号〔包括32个不能打印出来的操纵符号〕,只占用了一个字节的后面7位,最前面的1位统一规定为0。

下面是截图:具体的能够到那个网页上去查下:2、非ASCII编码英语用128个符号编码就够了,然而用来表示其他语言,128个符号是不够的。

比如,在法语中,字母上方有注音符号,它就无法用ASCII码表示。

因此,一些欧洲国家就决定,利用字节中闲置的最高位编入新的符号。

比如,法语中的é的编码为130〔二进制10000010〕。

如此一来,这些欧洲国家使用的编码体系,能够表示最多256个符号。

然而,那个地点又显现了新的问题。

不同的国家有不同的字母,因此,哪怕它们都使用256个符号的编码方式,代表的字母却不一样。

比如,130在法语编码中代表了é,在希伯来语编码中却代表了字母Gimel (ג),在俄语编码中又会代表另一个符号。

UTF8与GB2312之间的转换

UTF8与GB2312之间的转换

UTF8 与GB2312 之间的转换相信一定有不少的程序开发人员时常会遇到字符编码的问题,而这个问题也是非常让人头痛的。

因为这些都是潜在的错误,要找出这些错误也得要有这方面的开发经验才行。

特别是在处理xml 文档时,该问题的出现就更加的频繁了,有一次用java 写服务器端程序,用vc 写客户端与之交互。

交互的协议都是用xml 写的。

结果在通讯时老是发现数据接受不正确。

纳闷!于是用抓取网络数据包工具抓取数据,后来才发现原来是java 上xml 的头是这样的,而vc 上默认的是GB2312 。

所以一遇到汉字数据就不正确了。

去网上找资料,这方面的文章好象特别少,针对像这样的问题,下面我介绍一下我自己写的一个转换程序。

当然,程序很简单。

如果有画蛇添足的地方,还望各位高手一笑了之。

如果您对UTF-8 、Unicode 、GB2312 等还是很陌生的话,请查看/books/UTF-8-Unicode.html 我这里就不浪费口舌了。

下面介绍一下WinAPI 的两个函数:WideCharToMultiByte 、MultiByteToWideChar 。

函数原型:int WideCharToMultiByte(UINT CodePage, // code pageDWORD dwFlags, // performance and mapping flagsLPCWSTR lpWideCharStr, // wide-character stringint cchWideChar, // number of chars in stringLPSTR lpMultiByteStr, // buffer for new stringint cbMultiByte, // size of bufferLPCSTR lpDefaultChar, // default for unmappable charsLPBOOL lpUsedDefaultChar // set when default char used ); //将宽字符转换成多个窄字符int MultiByteToWideChar( UINT CodePage, // code pageDWORD dwFlags, // character-type optionsLPCSTR lpMultiByteStr, // string to mapint cbMultiByte, // number of bytes in stringLPWSTR lpWideCharStr, // wide-character bufferint cchWideChar // size of buffer);// 将多个窄字符转换成宽字符需要用到的一些函数:CString CXmlProcess::HexToBin(CString string)// 将16 进制数转换成2 进制{if( string == "0") return "0000";if( string == "1") return "0001";if( string == "2") return "0010";if( string = = "3") return "0011";if( string = = "4") return "0100";if( string = = "5") return "0101";if( string = = "6") return "0110";if( string = = "7") return "0111";if( string = = "8") return "1000";if( string = = "9") return "1001";if( string = = "a") return "1010";if( string = = "b") return "1011";if( string = = "c") return "1100";if( string = = "d") return "1101";if( string = = "e") return "1110";if( string = = "f") return "1111";return "";CString CXmlProcess::BinToHex(CString BinString)// 将2 进制数转换成16 进制{if( BinString == "0000") return "0";if( BinString == "0001") return "1";if( BinString == "0010") return "2"; if( BinString == "0011") return "3"; if( BinString == "0100") return "4";if( BinString = = "0101") return "5";if( BinString = = "0110") return "6";if( BinString = = "0111") return "7";if( BinString = = "1000") return "8";if( BinString = = "1001") return "9";if( BinString = = "1010") return "a";if( BinString = = "1011") return "b";if( BinString = = "1100") return "c";if( BinString = = "1101") return "d";if( BinString = = "1110") return "e";if( BinString = = "1111") return "f";return ""}int CXmlProcess::BinToInt(CString string)//2进制字符数据转换成10 进制整型{int len =0;int tempInt = 0;infs =r -n f H 0 八fo 「(infiH o 二 Asmng.GaLengfho二 ++) 宀CD m p -n f 丄八s =r -n f H(inoss.ng.GefAs —48」 foanfkH o 八 k A 7—i八 k ++)宀D m p -n f H 2*Drefum -e p) U T F OO >旃注GB2312出m U T F OO >旃注Unicode•^可囲瞥Unicode 镒ff 因選widechaHOMU-HByCDM旃注GB2312WCHAR* cxm-p「ocessxuTF —8Tounicode(cha「*u s 5r l i ) lm U T F OO >旃注Unicode宀charchar —one八charchar —fwpcharcha 匚hree八infHchanint Lchar;char uchar[2];WCHAR *unicode;CString string_one;CString string_two;CString string_three;CString combiString;char_one = *ustart;char_two = *(ustart+1);char_three = *(ustart+2);string_one.Format("%x",char_one);string_two.Format("%x",char_two);string_three.Format("%x",char_three); string_three =string_three.Right(2);string_two = string_two.Right(2);string_one = string_one.Right(2);string_three =HexToBin(string_three.Left(1))+HexToBin(string_three.Right(1 ));string_two =HexToBin(string_two.Left(1))+HexToBin(string_two.Right(1));string_one =HexToBin(string_one.Left(1))+HexToBin(string_one.Right(1));combiString = string_one +string_two +string_three;combiString = combiString.Right(20);combiString.Delete(4,2);combiString.Delete(10,2);Hchar = BinToInt(combiString.Left(8));Lchar = BinToInt(combiString.Right(8));uchar[1] = (char)Hchar;uchar[0] = (char)Lchar;unicode = (WCHAR *)uchar;return unicode;}char * CXmlProcess::UnicodeToGB2312(unsigned short uData) //把Unicode 转换成GB2312{char *buffer ;buffer = new char[sizeof(WCHAR)];WideCharToMultiByte(CP_ACP,NULL,&uData,1,buffer,size of(WCHAR),NULL,NULL);return buffer;GB2312 转换成UTF-8 :先把GB2312 通过函数MultiByteToWideChar 转换成Unicode. 然后再把Unicode 通过拆开Unicode 后拼装成UTF-8。

网页编码之GB2312、GBK与UTF-8的区别

网页编码之GB2312、GBK与UTF-8的区别

⽹页编码之GB2312、GBK与UTF-8的区别⾸先,我们要明⽩,GB2312、GBK和UTF-8都是⼀种字符编码,除此之外,还有好多字符编码。

只是对于我们中国⼈的⽹站来说,⽤这三种编码⽐较多。

简单的说⼀下,为什么要⽤编码,在计算机内,储存⽂本信息⽤ASC II码,每⼀个字符对应着唯⼀的ASCII码。

最初计算机是由美国发明的,他们也⽤的是键盘和上⾯的字母,所以他们的字符ASCII好解决。

但是我们中国的就不同了,每个汉字要对应唯⼀的ASCII码。

这样,就出来了国家制定的字符编码标准:GB2312、GBK等。

其他国家,其他语⾔也有他们对应的编码标准。

GB 就是国标的意思,GB2312和GBK主要⽤于汉字的编码,⽽UTF-8是全世界通⽤的。

意思就是说,如果你的⽹页主要⾯对使⽤汉语的中国⼈的话,使⽤ GB2312和GBK⾮常好,⽂字储存体积要⼩,有⼀些优点。

如果你的⽹页要⾯向世界的话,你再⽤GB2312和GBK作为⽹页编码的话,有些电脑上的浏览器没有这种编码,你的⽹页汉字内容就会变成⽆法识别的乱码。

它们通常⽤在⽹页的meta标签内,例如:,表⽰这个页⾯使⽤的是GB2312编码。

这个信息是给浏览器看的,浏览器会优先考虑使⽤从⽹页头部提取出来的编码信息对⽹页进⾏解码。

当然,我们也可以强制浏览器使⽤某种编码解释⽹页,这样我们就看到了传说中的乱码。

GBK、GB2312等与UTF8之间都必须通过Unicode编码才能相互转换:GBK、GB2312--Unicode--UTF8UTF8--Unicode--GBK、GB2312对于⼀个⽹站、论坛来说,如果英⽂字符较多,则建议使⽤UTF-8节省空间。

不过现在很多论坛的插件⼀般只⽀持GBK。

如果是中⽂的⽹站推荐GB2312 GBK有时还是有点问题为了避免所有乱码问题,应该采⽤UTF-8,将来要⽀持国际化也⾮常⽅便 UTF-8可以看作是⼤字符集,它包含了⼤部分⽂字的编码。

UTF-8,Unicode,GB2312格式串转换之C语言版

UTF-8,Unicode,GB2312格式串转换之C语言版

UTF-8,Unicode,GB2312格式串转换之C语言版UTF-8, Unicode, GB2312格式串转换之C语言版(申明:此文章属于原创,若转载请表明作者和原处链接)/* author: wu.jian (吴剑) English name: Sword/* date: 2007-12-13/* purpose: 知识共享这几天工作上碰到了UTF-8转GB2312的问题,而且是在嵌入式的环境下,没有API可用,查了很多网上的资料,大多调用VC或者linux下自带的接口。

在这里我将这两天的工作做个总结。

总的来说分为两大步(这里就不介绍基础知识了):一、UTF8 -> Unicode由于UTF8和Unicode存在着联系,所以不需要任何库就可以直接进行转换。

首先要看懂UTF8的编码格式: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 10xxxxxx U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxx xxx前面几个1就代表后面几个字节是属于一起的。

如果要解析一长串UTF8格式的字符串,这点就很有用了。

下面这个函数就是判断前面几个1的(这里有 define APP_PRINT printf,这样当release的时候将这个宏定义为空就行了,不需要一个一个去改,又方便重新调试):int GetUtf8ByteNumForWord(u8 firstCh){u8 temp = 0x80;int num = 0;while (temp & firstCh){num++;temp = (temp >> 1);}APP_PRINT("the num is: %d", num);return num;}利用这个函数可以得到字符串中那几个字节是一起的。

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

字符编码知识:Unicode、UTF-8、ASCII、GB2312等编码之间是如何转换的?(...字符编码是计算机技术的基石,想要熟练使用计算机,就必须懂得字符编码的知识。

不注意的人可能对这个不在意,但这些名词有时候实在让人迷惑,对想学习计算机知识的人来说,搞懂它也十分重要,我也是在学习中慢慢了解了一些这方面的知识。

1. ASCII码在计算机内部,所有的信息最终都表示为一个二进制的字符串。

每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte)。

也就是说,一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从0000000到11111111。

上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。

这被称为ASCII码,一直沿用至今。

ASCII码一共规定了128个字符的编码,比如空格“SPACE”是32(十进制的32,用二进制表示就是00100000),大写的字母A是65(二进制01000001)。

这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的1位统一规定为0。

下面是截图:具体的可以到这个网页上去查下:2、非ASCII编码英语用128个符号编码就够了,但是用来表示其他语言,128个符号是不够的。

比如,在法语中,字母上方有注音符号,它就无法用ASCII码表示。

于是,一些欧洲国家就决定,利用字节中闲置的最高位编入新的符号。

比如,法语中的é的编码为130(二进制10000010)。

这样一来,这些欧洲国家使用的编码体系,可以表示最多256个符号。

但是,这里又出现了新的问题。

不同的国家有不同的字母,因此,哪怕它们都使用256个符号的编码方式,代表的字母却不一样。

比如,130在法语编码中代表了é,在希伯来语编码中却代表了字母Gimel (ג),在俄语编码中又会代表另一个符号。

但是不管怎样,所有这些编码方式中,0—127表示的符号是一样的,不一样的只是128—255的这一段。

至于亚洲国家的文字,使用的符号就更多了,汉字就多达10万左右。

一个字节只能表示256种符号,肯定是不够的,就必须使用多个字节表达一个符号。

比如,简体中文常见的编码方式是GB2312,使用两个字节表示一个汉字,所以理论上最多可以表示256x256=65536个符号。

3.Unicode正如上一节所说,世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。

因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。

为什么电子邮件常常出现乱码?就是因为发信人和收信人使用的编码方式不一样。

解释:同一个文本文件,假设内容是用英语写的,在英语编码的情况下,每个字符会和一个二进制数对应(如00101000类似),然后存到计算机中,这时把这个英语文件发给一个俄语国家的用户,计算机传输的是二进制流,即0101之类的数据,到了俄语用户这方,需要有它的俄语编码方式进行解码,把每个二进制流转为字符显示,由于俄语编码表中对每串二进制流数据的解释方式不同,同一个数据如00101000在英语中可能代表A,而在俄语中则代表B,这样就会产生乱码,这是我个人的理解。

GB2312编码、日文编码等也是非unicode编码,是要通过转换表(codepage)转换成unicode 编码的,要不怎么显示出来呢?可以想象,如果有一种编码,将世界上所有的符号都纳入其中。

每一个符号都给予一个独一无二的编码,那么乱码问题就会消失。

这就是Unicode,就像它的名字都表示的,这是一种所有符号的编码。

Unicode当然是一个很大的集合,现在的规模可以容纳100多万个符号。

每个符号的编码都不一样,比如,U+0639表示阿拉伯字母Ain,U+0041表示英语的大写字母A,U+4E25表示汉字“严”。

具体的符号对应表,可以查询,或者专门的。

4. Unicode的问题需要注意的是,Unicode只是一个符号集,只是一种规范、标准,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储在计算机上。

比如,汉字“严”的unicode是十六进制数4E25,转换成二进制数足足有15位(100111000100101),也就是说这个符号的表示至少需要2个字节。

表示其他更大的符号,可能需要3个字节或者4个字节,甚至更多。

这里就有两个严重的问题,第一个问题是,如何才能区别unicode和ascii?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍,这是无法接受的。

它们造成的结果是:1)出现了unicode的多种存储方式,也就是说有许多种不同的二进制格式,可以用来表示unicode。

2)unicode在很长一段时间内无法推广,直到互联网的出现。

5.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 | 0xxxxxxx0000 0080-0000 07FF | 110xxxxx 10xxxxxx0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx下面,还是以汉字“严”为例,演示如何实现UTF-8编码。

已知“严”的unicode是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800-0000 FFFF),因此“严”的UTF-8编码需要三个字节,即格式是“1110xxxx 10xxxxxx 10xxxxxx”。

然后,从“严”的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。

这样就得到了,“严”的UTF-8编码是“11100100 10111000 10100101”,这是保存在计算机中的实际数据,转换成十六进制就是E4B8A5,转成十六进制的目的为了便于阅读。

6. Unicode与UTF-8之间的转换通过上一节的例子,可以看到“严”的Unicode码是4E25,UTF-8编码是E4B8A5,两者是不一样的。

它们之间的转换可以通过程序实现。

在Windows平台下,有一个最简单的转化方法,就是使用内置的记事本小程序Notepad.exe。

打开文件后,点击“文件”菜单中的“另存为”命令,会跳出一个对话框,在最底部有一个“编码”的下拉条。

里面有四个选项:ANSI,Unicode,Unicode big endian 和 UTF-8。

1)ANSI是默认的编码方式。

对于英文文件是ASCII编码,对于简体中文文件是GB2312编码(只针对Windows简体中文版,如果是繁体中文版会采用Big5码)。

2)Unicode编码指的是UCS-2编码方式,即直接用两个字节存入字符的Unicode码。

这个选项用的little endian格式。

3)Unicode big endian编码与上一个选项相对应。

我在下一节会解释little endian和big endian 的涵义。

4)UTF-8编码,也就是上一节谈到的编码方法。

选择完”编码方式“后,点击”保存“按钮,文件的编码方式就立刻转换好了。

7. Little endian和Big endian上一节已经提到,Unicode码可以采用UCS-2格式直接存储。

以汉字”严“为例,Unicode码是4E25,需要用两个字节存储,一个字节是4E,另一个字节是25。

存储的时候,4E在前,25在后,就是Big endian方式;25在前,4E在后,就是Little endian方式。

那么很自然的,就会出现一个问题:计算机怎么知道某一个文件到底采用哪一种方式编码?Unicode规范中定义,每一个文件的最前面分别加入一个表示编码顺序的字符,这个字符的名字叫做”零宽度非换行空格“(ZERO WIDTH NO-BREAK SPACE),用FEFF表示。

这正好是两个字节,而且FF比FE大1。

如果一个文本文件的头两个字节是FE FF,就表示该文件采用大头方式;如果头两个字节是FF FE,就表示该文件采用小头方式。

8. 实例下面,举一个实例。

打开”记事本“程序Notepad.exe,新建一个文本文件,内容就是一个”严“字,依次采用ANSI,Unicode,Unicode big endian 和 UTF-8编码方式保存。

然后,用文本编辑软件的”十六进制功能“,观察该文件的内部编码方式。

1)ANSI:文件的编码就是两个字节“D1 CF”,这正是“严”的GB2312编码,这也暗示GB2312是采用大头方式存储的。

2)Unicode:编码是四个字节“FF FE 25 4E”,其中“FF FE”表明是小头方式存储,真正的编码是4E25。

3)Unicode big endian:编码是四个字节“FE FF 4E 25”,其中“FE FF”表明是大头方式存储。

4)UTF-8:编码是六个字节“EF BB BF E4 B8 A5”,前三个字节“EF BB BF”表示这是UTF-8编码,后三个“E4B8A5”就是“严”的具体编码,它的存储顺序与编码顺序是一致的。

相关文档
最新文档