20070809 utf8 ef bb bf
http://www.yippeesoft.com
今天人家解析我生成的一个文件死活判断不了EOF
StreamWriter sw = new StreamWriter(strfilelist, false, Encoding.UTF-8);
十六进制一看,多了 EF BB BF三个字节,估计是UTF8的事情
改为ASCII就OK了
资料:
调试一个小程序发现的.
用M$的记事本新建一个文件,输入些东西,然后另存为utf8格式的文件,你就会发现它会自动在文本前面添加EF BB BF这3个字节,这应该是用来标识文件格式的.
在Ultraedit里看到的似乎有些问题 是FF FE.
往标准的txt文件里随意添加标识,这种流氓行为很容易导致兼容性问题,更科学的方法应该是根据文件的内容来判断文件的格式.
呵呵,这个是您理解错了。
unicode 文档前面附加两三个字节的识别码(学名叫BOM)不是M$ Notepad的错。这是unicode的规定。见http://www.unicode.org/faq/utf_bom.html。我试验了一下,. NET、Java、gvim和最新版本的UltraEdit和都认识BOM,会以相应方式处理。但最新版本的Python却不完全认识,它的文件I/O和正则表达式有时会因BOM而出错。
已知 赛迪网 三个汉字用文字编辑器转成 UTF8后是乱码。然后用16进制看为 EF BB BF E8 B5 9B E8 BF AA E7 BD 91
问如何用php直接把这三个汉字转成 这一串16进制。并把 "EF BB…."字符串赋值到函数
最终生成如下的结构:
$str = chr(0xE8).chr(0xB5).chr(0×9B).chr(0xE8).chr(0xBF).chr(0xAA).chr(0xE7).chr(0xBD).chr(0×91)
<?php
$s = "赛迪网";
$u = iconv("GB2312","UTF-8",$s);
$n = bin2hex($u); //e8b59be8bfaae7bd91
preg_match_all("/../",$n,$regs);
print_r($regs[0]); //测试
echo $p = "chr(0x".join(").chr(0x",$regs[0]).")"; //chr(0xe8).chr(0xb5).chr(0×9b).chr(0xe8).chr(0xbf).chr(0xaa).chr(0xe7).chr(0xbd).chr(0×91)
eval("\\$str=$p;");
echo $str;
?>
晚上写了个小程序测试了一下,终于弄懂了UltraEdit弄出来的UTF8格式,和微软弄出来的UTF8格式之间的区别了
比如说一个文本文件内容是“1啊”两个字符:
对于 GBK编码:31 B0 A1
对于unicode UCS-2 编码(不论记事本还是Ultaedit): ff fe 31 00 4a 55 (在Ultraedit二进制下看到的是一样的)
对于UltraEdit的“UTF8(unicode editing)” 的编码: 31 e5 95 8a (在Ultraedit下看到的是 FF FE 31 00 4A 55)
对于微软“记事本”另存为出来的UTF8的编码: ef bb bf 31 e5 95 8a (在Ultraedit下看到的是 FF FE FF FE 31 00 4A 55)
可以看出来,微软的UTF8编码其实是符合标准的,因为 ef bb bf 这三个字节,正好就是 FF FE 的UTF8编码。也就是说,看来是我们冤枉微软了,一直以为是Ultraedit出来的utf8标准而微软“记事本”出来的utf8不标准,其实正好相反。
参见 ultraedit forum
看来我手头的 UE9.0 是个很老的版本了。
现在就剩下一个问题:为什么svn不支持标准utf8,无法识别BOM呢?
什么是UTF8
UTF8并不算是一种电脑编码,而是一种储存和传送的格式,如前所述,每个Unicode/UCS字符都以 2或4个bytes来储存,看看以下的比较:
以"I am Chinese"为例
用ANSI储存:12 Bytes
用Unicode/UCS2储存:24 Bytes + 2 Bytes(header)
用UCS4储存:48 Bytes + 4 Bytes(header)
以"我是中国人"为例
用ANSI储存:10 Bytes
用Unicode/UCS2储存:10 Bytes + 2 Bytes(header)
用UCS4储存:20 Bytes + 4 Bytes(header)
由此可见直接以Unicode/UCS的原始形式来储存是一种极大的浪费,而且也不利于互联网的传输(中文稍为合算一点^_^)。
有见及此,Unicode/UCS的压缩形式--UTF8出现了,套用官方网站的首句话『UTF-8 stands for Unicode Transformation Format-8. It is an octet (8-bit) lossless encoding of Unicode characters.』,由于UTF也适用于编码UCS,故亦可称为『UCS transformation formats (UTF)』
UTF8是以8bits即1Bytes为编码的最基本单位,当然也可以有基于16bits和32bits的形式,分别称为UTF16和UTF32,但目前用得不多,而UTF8则被广泛应用在文件储存和网络传输中。
编码原理
先看这个模板:
UCS-4 range (hex.) UTF-8 octet sequence (binary)
0000 0000-0000 007F 0xxxxxxx
0000 0080-0000 07FF 110xxxxx 10xxxxxx
0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
0400 0000-7FFF FFFF 1111110x 10xxxxxx … 10xxxxxx
编码步骤:
1) 首先确定需要多少个8bits(octets)
2) 按照上述模板填充每个octets的高位bits
3) 把字符的bits填充至x中,字符顺序:低位→高位,UTF8顺序:最后一个octet的最末位x→第一个octet最高位x
4) 解码的原理一样。
实例:(留意每个bit的颜色,粗体字为模板内容)
UCS-4 UTF-8
HEX BIN Bytes BIN HEX Bytes
0000 000A 00001010 4 00001010 0A 1
0000 0099 10011001 4 11000010 10011001 C2 99 2
0000 8D99 10001101 10011001 4 11101000 10110110 10011001 E8 B6 99 3
不知大家看懂了没有,其实不懂也无所谓,反正又不用自己算,程式可以完全代劳。
以UTF8格式储存的文件档首标识为EF BB BF。
效率
从上述编码原理中得出的结论是:
1.每个英文字母、数字所占的空间为1 Byte;
2.泛欧语系、斯拉夫语字母占2 Bytes;
3.汉字占3 Bytes。
由此可见UTF8对英文来说是个非常诱人的方案,但对中文来说则不太合算,无论用ANSI还是 Unicode/UCS2来编码都只用2 Bytes,但用UTF8则需要3 Bytes。
以下是一些统计资料,显示用UTF8来储存文件每个字符所需的平均字节:
1.拉丁语系平均用1.1 Bytes;
2.希腊文、俄文、阿拉伯文和希伯莱文平均用1.7 Bytes;
3.其他大部份文字如中文、日文、韩文、Hindi(北印度语)用约3 Bytes;
4.用超过4 Bytes的都是些非常少用的文字符号。
今天什么事情都不顺利
早上看到居委会的通告:×××还没有办二代身份证
只好跑去派出所办理
结果要求父母身份证号码,晕倒,他们在火车上了
又找警察查询了号码
然后再进去交了表,照相,一看,原来刚才我插队了,好多人
想想算了,赶快去上班吧
结果打的到公司,还是迟到了
下午去接父母,网上查一下,时间差不多
结果我还没到火车站,家里电话就打来了,已经到了
原来火车提速了
郁闷
历史博文
- udp drag drop - 2010
- 20080415 oracle 异构 2 - 2009
- 0801 smtp becky 550 5.7.1 Requested action not taken: message refused - 2007
- 1226 保護個人電腦基本常識 - 2006