转载+整理
打开一些AUTO-Disk中的Autorun.inf,你会发现它的编写格式是:
[AutoRun]
open=……
icon=……
[AutoRun]是针对PC机(机型为386或更高)的自动运行识别标志。除此之外,还有针对其他几种计算机系统的识别标志,它们是:针对MIPS公司MIPS系统的[AutoRun.mips];针对DEC公司Alpha系统的[AutoRun.alpha];针对苹果公司Power PC机的[AutoRun.ppc]。不过,除非你想制作通用的自动运行光盘,否则用不到这些标识。
open一行是告诉操作系统要自动运行的文件名和它的启动全路径。比如,若想自动运行Autorun目录下的Run.exe文件,这一行就写成:
open=Autorun\Run.exe
注意,在目录名的左边不能有反斜线,否则计算机将按“C:\”处理,也就无法启动指定的程序了。icon一行是告诉操作系统该光盘以什么样的图标表示,如果你不想指定,这一行也可以不写。
图标的调用方法有三种:第一种是直接指向图标文件(.ico)。比如要想使用在Autorun目录下的一个图标文件Run.ico,调用格式与open一行相同,即:icon=Autorun\Run.ico
第二种调用方法就是指向带有图标的exe文件,只要是For Windows 9x/NT的exe文件都带有图标。而且,如果该文件带有多个图标还可以用编号进行挑选。比如所选的是Run.exe,它带有5个图标,其第一个也是默认图标的调用格式为:
icon=Autorun\Run.exe或icon=Autorun\Run.exe,0
若想调用第三个图标,格式为:
icon=Autorun\Run.exe,2
因为第一个图标的编号是0,所以第三个图标的编号就是2了。另外,在逗号的两 边都不能有空格,否则就调用默认的图标。而且,若调用的编号大于其最大编号,那光盘的图标就为空,什么也没有。可能有人会问,我怎么知道目标文件带有几个图标?不用着急,跟着我做:用鼠标右键点击任意一个带有图标的exe文件的“快捷方式”——在快捷菜单中选择“属性”——选择“快捷方式”——点击“更改图标…”——用“浏览…”的方式打开你选择的目标文件,现在你就能看到该文件到底有多少个图标了。
至于图标的排列顺序在Windows 95中是从左至右,在Windows 98中则是先上下后左右,不要数错哟。
第三种调用方式就是指向带有图标的DLL文件,也就是动态链接库文件,具体的格式与注意事项都与第二种方法相同,在此就不作介绍了。
到这儿还没有完。大家知道,在一些光盘放入后,我们在其图标上单击鼠标右键,还会产生一个具有特色的目录菜单,如果能对着我们的硬盘点击鼠标右键也产生这样的效果,那将更加的有特色。其实,光盘能有这样的效果也仅仅是因为在AutoRun.inf文件中有如下两条语句:
shell\标志=显示的鼠标右键菜单中内容
shell\标志\command=要执行的文件或命令行
所以,要让硬盘具有特色的目录菜单,在AutoRun.inf文件中加入上述语句即可,示例如下:
shell\1=天若有情天亦老
shell\1\command\=notepad ok.txt
保存完毕,按F5键刷新,然后用鼠标右键单击硬盘图标,在弹出菜单中会发现“天若有情天亦老”,点击它,会自动打开硬盘中的“ok.txt”文件。注意:上面示例假设“ok.txt”文件在硬盘根目录下,notepad为系统自带的记事本程序。如果要执行的文件为直接可执行程序,则在“command\”后直接添加该执行程序文件名即可。
还有一选项是shellexcute,后面跟插入disk后自动运行的程序路径名称,不需要点击
至此,一个完整的Autorun.inf文件就编辑完成了,结合你需要烧录的内容,在确认调用路径无误后,就可以开始烧录了。此时唯一要注意的就是Autorun.inf文件必须放在光盘的根目录下,否则Windows无法找到它,也就不能自动运行了。
下面贴个常见的U盘病毒生成的autorun.inf示例:
[autorun]
open=.\RECYCLER\RECYCLER.exe
shell\1=打开(&O)
shell\1\Command=.\RECYCLER\RECYCLER.exe
shell\2\=浏览(&B)
shell\2\Command=.\RECYCLER\RECYCLER.exe
shellexecute=.\RECYCLER\RECYCLER.exe
最后是一些说明:
说明1:是否执行AutoRun功能其实由注册表来决定。在“开始”菜单的“运行”中输
入Regedit,打开注册表编辑器,展开到HKEY_CURRENT_USER\
Software\Microsoft\Windows\Current- Version\Policies\Exploer主键下,右边窗口中的二
进制值“NoDriveType- AutoRun”决定了是否执行AutoRun功能(包括硬盘和Ramdisk)。
“NoDriveTypeAutoRun”默认键值为95 00 00 00
说明2:Shell32.DLL是一个Windows系统文件,里面包含有很多Windows的系统图标,21表示
显示为编号为21的图标,当然你也可以自己制作一个图标,只需要在“ICON”一行把路径做相应修
改即可。除了可以使用DLL文件中的图标外,还能用EXE文件中的图标,或直接使用ICO文件。
在windows xp使用过程中,在默认情况下,一旦将可移动磁盘接入电脑(将光盘插入光驱,或者接插上U盘、移动硬盘时)Windows XP的自动播放功能就读取驱动器,完成后同时显示一个对话框,要求你选择是否打开其中的视频、音频、图片文件。这项自动功能可能是你不需要的。如果你想关闭的话,可以使用这样的办法:
一、为可移动设备设置属性。
关闭单个移动存储设备的“自动播放”功能,可以通过移动存储设备的属性页来直接关闭着项功能。(这要求该移动存储设备已经存在于计算机上。)
1、在我的电脑或者资源管理器中右键单击需要关闭自动播放功能的移动存储设备。选择属性。
2、在打开的窗口中单击“自动播放”选项卡,在操作框中,选定“选择一个操作来执行”前的单选框,然后选中“不执行操作”。最后“确定”。
这样该设备就不会再自动打开文件夹了。
二、使用组策略一次性全部关闭windows xp的自动播放功能:
如果你想一次全部禁用Windows XP的自动播放功能,可以使用组策略。
1、点击“开始”选择“运行”,键入“gpedit.msc”,并运行,打开“组策略”窗口;
2、在左栏的“本地计算机策略”下,打开“计算机配置_管理模板_系统”,然后在右栏的“设置”标题下,双击“关闭自动播放”;
3、选择“设置”选项卡,勾取“已启用”复选钮,然后在“关闭自动播放”框中选择“所有驱动器”,单击“确定”按钮,退出“组策略”窗口。
在“用户配置”中同样也可以定制这个“关闭自动播放”。但“计算机配置”中的设置比“用户配置”中的设置范围更广。有助于多个用户都使用这样的设置。
提醒:“关闭自动播放”设置是只能使系统不再列出光盘和移动存储的目录,并不能够阻止自动播放音乐CD盘。要阻止音乐CD的自动播放,你就只有更改移动设备的属性了。
Tuesday, January 30, 2007
My Computer has Recovered
Posted by
Tony Su
at
12:57 PM
最后发现的问题:
我的风扇装反了-_-b差点把cpu干掉
电容爆缸了好多,更换之
内存供电芯片不稳定,考虑一下还是换了
cost 100-RMB
目前正常工作
cheers!
我的风扇装反了-_-b差点把cpu干掉
电容爆缸了好多,更换之
内存供电芯片不稳定,考虑一下还是换了
cost 100-RMB
目前正常工作
cheers!
Sunday, January 28, 2007
My Computer is Falling Down
Posted by
Tony Su
at
12:13 AM
今天终于拿去修了……
初始症状:开机时频繁自掉电重启;
后来将主频更改2.0G->1.2G(通过改倍频),问题消失了一段时间,但又一段时间后问题依旧,而且还有点变严重;
再后来有时机器不能启动,风扇正常但没有显示,每次要开几次才能打开机器;
于是……
我把主板拆下来吹了吹土,装上之后连开机都开不了了……开机3秒之后自动掉电
让人家看了一下,说可能是电容坏了好多。现在想想也是,这种不稳定的问题除了温度的原因,也就是电容了。
另外才知道电容的上面鼓一点点就是坏掉了,好像也没有什么好的保养方法,防止受潮吧……
电脑去送修了,期待平安归来,不要太被宰……
初始症状:开机时频繁自掉电重启;
后来将主频更改2.0G->1.2G(通过改倍频),问题消失了一段时间,但又一段时间后问题依旧,而且还有点变严重;
再后来有时机器不能启动,风扇正常但没有显示,每次要开几次才能打开机器;
于是……
我把主板拆下来吹了吹土,装上之后连开机都开不了了……开机3秒之后自动掉电
让人家看了一下,说可能是电容坏了好多。现在想想也是,这种不稳定的问题除了温度的原因,也就是电容了。
另外才知道电容的上面鼓一点点就是坏掉了,好像也没有什么好的保养方法,防止受潮吧……
电脑去送修了,期待平安归来,不要太被宰……
Saturday, January 20, 2007
Friday, January 19, 2007
Another Earthquake...
Posted by
Tony Su
at
12:01 PM
台湾海域又地震了
出国线路刚刚好了一点又要挂掉了
可是台湾已经恢复了95%的网络带宽
香港80%
为什么大陆的出国连接要靠台湾的呢?
受制于人啊
出国线路刚刚好了一点又要挂掉了
可是台湾已经恢复了95%的网络带宽
香港80%
为什么大陆的出国连接要靠台湾的呢?
受制于人啊
Thursday, January 18, 2007
卡巴斯基黑名单解决方法
Posted by
Tony Su
at
7:33 PM
其实我跟本不用卡巴啦……
不过最近电缆的事情,诺顿升级也很难……
12月06日发布,昨天是国内卡巴斯基反病毒软件非授权用户的灰色日子,绝大部分网络上流传的KEY授权已被加入黑名单。卡巴斯基6.0 KEY 在注册表中的位置共有三处信息,只有把这三处的信息全部删除,才能完全清除。我们网站提供的卡巴斯基6.0 KEY 清除文件,使用前关闭卡巴斯基,双击导入即可。这样做的好处:例如某 KEY 到期了,你可以用这种方法重新再用;又如网上的 KEY 被加入黑名单,你清除该 KEY 后换用其它 KEY 即可。在卡巴斯基反病毒软件 6.0 测试成功,卡巴斯基互联网安全套装 6.0 测试成功,欢迎各位朋友反馈结果。请注意,所有 KEY 不能放到中文目录下导入。推荐已无法激活的朋友下载! 使用方法:
1:打开记事本将下面的内容复制进去保存 QUOTE: Windows Registry Editor Version 5.00 [-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates\SPC\Certificates] [-HKEY_LOCAL_MACHINE\SOFTWARE\KasperskyLab\LicStorage] [-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\RNG]
改记事本文件的后缀名.txt为.reg如:KeyRemoval.txt改为KeyRemoval.reg 再双击(双击前一定要关掉卡巴的程序和监控)改后的文件*.reg导入注册表将卡巴的到期授权或列入黑名单授权清除(这样做的好处:例如某 KEY 到期了,你可以用这种方法重新再用)
2:打开卡巴显示无授权,再将你以前的授权导入,这样卡巴又可以用了!
1、只需在您的Kaspersky安全产品的更新服务器列表中添加如下url: ftp://security.thusns.org/Kaspersky/updates 即可与Kaspersky官方更新保持同步(不超过三小时)。 对于Kaspersky AntiVirus 5.x版本,将url设置为: http://security.thusns.org
2、http://free5.ys168.com/?yhaizhu上有...可用到2008年1月
3、 卡巴斯基6被封KEY黑名单解决办法 本文转自剑盟,没有验证 大家有的报卡巴的KEY被封了,无法升级了!其实很简单就可以升级了啊! 三种方法任选吧
1、你的 C:\documents and settings\all users\application data\kaspersky lab\kav for workstations\6.0\bases里面有个black.lst文件,卡巴只是把你的这个文件给你替换了啊!你可以找一个没有被替换,仍然可以升级的卡巴6拷一个覆盖原来的就行了!最后重新启动系统,这样卡巴又能用了。我用的是工作站版,单机版目录将不同,请按照你的系统安装目录和软件版本找到相应的文件,建议你直接搜索吧 !使用我提供的附件覆盖原来的那个黑名单列表文件即可解决!
2、直接下载离线升级包嘛! ftp://ru2f.kaspersky-labs.com/bases/av/avc/i386 端口 21 自己用迅雷拖吧!呵呵!也可以直接输入ftp://ru2f.kaspersky-labs.com:21/bases/av/avc/i386
3、改换升级服务器,目前卡巴俄罗斯服务器已经开始封KEY了,但是国内的服务器还是可以用原来key进行升级的!如果还不行可以打开卡巴-设置-更新-自定义-更新服务器-确定最佳更新地区,改成别的国家。大家可以多试一试啊!也可以点击添加,加入具体升级地址。
http://cn1h.kaspersky-labs.com China http://cn2h.kaspersky-labs.com China http://cn3h.kaspersky-labs.com China http://cn4h.kaspersky-labs.com China http://cn5h.kaspersky-labs.com China http://cn6h.kaspersky-labs.com China ftp://cn1f.kaspersky-labs.com China ftp://cn2f.kaspersky-labs.com China ftp://cn3f.kaspersky-labs.com China ftp://cn4f.kaspersky-labs.com China ftp://cn5f.kaspersky-labs.com China ftp://cn6f.kaspersky-labs.com 再给你个清华大学升级服务器 http://security.thusns.org/html/index.html 4.是奇虎360赠给国人的礼物,里边有一个能用半年的KAV6.0激活码。http://www.360safe.com/kabacode.php 12月06日发布,昨天是国内卡巴斯基反病毒软件非授权用户的灰色日子,绝大部分网络上流传的KEY授权已被加入黑名单。卡巴斯基6.0 KEY 在注册表中的位置共有三处信息,只有把这三处的信息全部删除,才能完全清除。我们网站提供的卡巴斯基6.0 KEY 清除文件,使用前关闭卡巴斯基,双击导入即可。这样做的好处:例如某 KEY 到期了,你可以用这种方法重新再用;又如网上的 KEY 被加入黑名单,你清除该 KEY 后换用其它 KEY 即可。在卡巴斯基反病毒软件 6.0 测试成功,卡巴斯基互联网安全套装 6.0 测试成功,欢迎各位朋友反馈结果。请注意,所有 KEY 不能放到中文目录下导入。推荐已无法激活的朋友下载!
使用方法:
1:打开记事本将下面的内容复制进去保存
QUOTE:
Windows Registry Editor Version 5.00
[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates\SPC\Certificates]
[-HKEY_LOCAL_MACHINE\SOFTWARE\KasperskyLab\LicStorage]
[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\RNG]
改记事本文件的后缀名.txt为.reg如:KeyRemoval.txt改为KeyRemoval.reg
再双击(双击前一定要关掉卡巴的程序和监控)改后的文件*.reg导入注册表将卡巴的到期授权或列入黑名单授权清除(这样做的好处:例如某 KEY 到期了,你可以用这种方法重新再用)
2:打开卡巴显示无授权,再将你以前的授权导入,这样卡巴又可以用了!
1、只需在您的Kaspersky安全产品的更新服务器列表中添加如下url:
ftp://security.thusns.org/Kaspersky/updates
即可与Kaspersky官方更新保持同步(不超过三小时)。
对于Kaspersky AntiVirus 5.x版本,将url设置为:
http://security.thusns.org
2、http://free5.ys168.com/?yhaizhu上有...可用到2008年1月
3、 卡巴斯基6被封KEY黑名单解决办法
本文转自剑盟,没有验证
大家有的报卡巴的KEY被封了,无法升级了!其实很简单就可以升级了啊!
三种方法任选吧
1、你的 C:\documents and settings\all users\application data\kaspersky lab\kav for workstations\6.0\bases里面有个black.lst文件,卡巴只是把你的这个文件给你替换了啊!你可以找一个没有被替换,仍然可以升级的卡巴6拷一个覆盖原来的就行了!最后重新启动系统,这样卡巴又能用了。我用的是工作站版,单机版目录将不同,请按照你的系统安装目录和软件版本找到相应的文件,建议你直接搜索吧 !使用我提供的附件覆盖原来的那个黑名单列表文件即可解决!
2、直接下载离线升级包嘛!
ftp://ru2f.kaspersky-labs.com/bases/av/avc/i386 端口 21 自己用迅雷拖吧!呵呵!也可以直接输入ftp://ru2f.kaspersky-labs.com:21/bases/av/avc/i386
3、改换升级服务器,目前卡巴俄罗斯服务器已经开始封KEY了,但是国内的服务器还是可以用原来key进行升级的!如果还不行可以打开卡巴-设置-更新-自定义-更新服务器-确定最佳更新地区,改成别的国家。大家可以多试一试啊!也可以点击添加,加入具体升级地址。
http://cn1h.kaspersky-labs.com China
http://cn2h.kaspersky-labs.com China
http://cn3h.kaspersky-labs.com China
http://cn4h.kaspersky-labs.com China
http://cn5h.kaspersky-labs.com China
http://cn6h.kaspersky-labs.com China
ftp://cn1f.kaspersky-labs.com China
ftp://cn2f.kaspersky-labs.com China
ftp://cn3f.kaspersky-labs.com China
ftp://cn4f.kaspersky-labs.com China
ftp://cn5f.kaspersky-labs.com China
ftp://cn6f.kaspersky-labs.com
再给你个清华大学升级服务器
http://security.thusns.org/html/index.html
4.是奇虎360赠给国人的礼物,里边有一个能用半年的KAV6.0激活码。http://www.360safe.com/kabacode.php
不过最近电缆的事情,诺顿升级也很难……
12月06日发布,昨天是国内卡巴斯基反病毒软件非授权用户的灰色日子,绝大部分网络上流传的KEY授权已被加入黑名单。卡巴斯基6.0 KEY 在注册表中的位置共有三处信息,只有把这三处的信息全部删除,才能完全清除。我们网站提供的卡巴斯基6.0 KEY 清除文件,使用前关闭卡巴斯基,双击导入即可。这样做的好处:例如某 KEY 到期了,你可以用这种方法重新再用;又如网上的 KEY 被加入黑名单,你清除该 KEY 后换用其它 KEY 即可。在卡巴斯基反病毒软件 6.0 测试成功,卡巴斯基互联网安全套装 6.0 测试成功,欢迎各位朋友反馈结果。请注意,所有 KEY 不能放到中文目录下导入。推荐已无法激活的朋友下载! 使用方法:
1:打开记事本将下面的内容复制进去保存 QUOTE: Windows Registry Editor Version 5.00 [-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates\SPC\Certificates] [-HKEY_LOCAL_MACHINE\SOFTWARE\KasperskyLab\LicStorage] [-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\RNG]
改记事本文件的后缀名.txt为.reg如:KeyRemoval.txt改为KeyRemoval.reg 再双击(双击前一定要关掉卡巴的程序和监控)改后的文件*.reg导入注册表将卡巴的到期授权或列入黑名单授权清除(这样做的好处:例如某 KEY 到期了,你可以用这种方法重新再用)
2:打开卡巴显示无授权,再将你以前的授权导入,这样卡巴又可以用了!
1、只需在您的Kaspersky安全产品的更新服务器列表中添加如下url: ftp://security.thusns.org/Kaspersky/updates 即可与Kaspersky官方更新保持同步(不超过三小时)。 对于Kaspersky AntiVirus 5.x版本,将url设置为: http://security.thusns.org
2、http://free5.ys168.com/?yhaizhu上有...可用到2008年1月
3、 卡巴斯基6被封KEY黑名单解决办法 本文转自剑盟,没有验证 大家有的报卡巴的KEY被封了,无法升级了!其实很简单就可以升级了啊! 三种方法任选吧
1、你的 C:\documents and settings\all users\application data\kaspersky lab\kav for workstations\6.0\bases里面有个black.lst文件,卡巴只是把你的这个文件给你替换了啊!你可以找一个没有被替换,仍然可以升级的卡巴6拷一个覆盖原来的就行了!最后重新启动系统,这样卡巴又能用了。我用的是工作站版,单机版目录将不同,请按照你的系统安装目录和软件版本找到相应的文件,建议你直接搜索吧 !使用我提供的附件覆盖原来的那个黑名单列表文件即可解决!
2、直接下载离线升级包嘛! ftp://ru2f.kaspersky-labs.com/bases/av/avc/i386 端口 21 自己用迅雷拖吧!呵呵!也可以直接输入ftp://ru2f.kaspersky-labs.com:21/bases/av/avc/i386
3、改换升级服务器,目前卡巴俄罗斯服务器已经开始封KEY了,但是国内的服务器还是可以用原来key进行升级的!如果还不行可以打开卡巴-设置-更新-自定义-更新服务器-确定最佳更新地区,改成别的国家。大家可以多试一试啊!也可以点击添加,加入具体升级地址。
http://cn1h.kaspersky-labs.com China http://cn2h.kaspersky-labs.com China http://cn3h.kaspersky-labs.com China http://cn4h.kaspersky-labs.com China http://cn5h.kaspersky-labs.com China http://cn6h.kaspersky-labs.com China ftp://cn1f.kaspersky-labs.com China ftp://cn2f.kaspersky-labs.com China ftp://cn3f.kaspersky-labs.com China ftp://cn4f.kaspersky-labs.com China ftp://cn5f.kaspersky-labs.com China ftp://cn6f.kaspersky-labs.com 再给你个清华大学升级服务器 http://security.thusns.org/html/index.html 4.是奇虎360赠给国人的礼物,里边有一个能用半年的KAV6.0激活码。http://www.360safe.com/kabacode.php 12月06日发布,昨天是国内卡巴斯基反病毒软件非授权用户的灰色日子,绝大部分网络上流传的KEY授权已被加入黑名单。卡巴斯基6.0 KEY 在注册表中的位置共有三处信息,只有把这三处的信息全部删除,才能完全清除。我们网站提供的卡巴斯基6.0 KEY 清除文件,使用前关闭卡巴斯基,双击导入即可。这样做的好处:例如某 KEY 到期了,你可以用这种方法重新再用;又如网上的 KEY 被加入黑名单,你清除该 KEY 后换用其它 KEY 即可。在卡巴斯基反病毒软件 6.0 测试成功,卡巴斯基互联网安全套装 6.0 测试成功,欢迎各位朋友反馈结果。请注意,所有 KEY 不能放到中文目录下导入。推荐已无法激活的朋友下载!
使用方法:
1:打开记事本将下面的内容复制进去保存
QUOTE:
Windows Registry Editor Version 5.00
[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates\SPC\Certificates]
[-HKEY_LOCAL_MACHINE\SOFTWARE\KasperskyLab\LicStorage]
[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\RNG]
改记事本文件的后缀名.txt为.reg如:KeyRemoval.txt改为KeyRemoval.reg
再双击(双击前一定要关掉卡巴的程序和监控)改后的文件*.reg导入注册表将卡巴的到期授权或列入黑名单授权清除(这样做的好处:例如某 KEY 到期了,你可以用这种方法重新再用)
2:打开卡巴显示无授权,再将你以前的授权导入,这样卡巴又可以用了!
1、只需在您的Kaspersky安全产品的更新服务器列表中添加如下url:
ftp://security.thusns.org/Kaspersky/updates
即可与Kaspersky官方更新保持同步(不超过三小时)。
对于Kaspersky AntiVirus 5.x版本,将url设置为:
http://security.thusns.org
2、http://free5.ys168.com/?yhaizhu上有...可用到2008年1月
3、 卡巴斯基6被封KEY黑名单解决办法
本文转自剑盟,没有验证
大家有的报卡巴的KEY被封了,无法升级了!其实很简单就可以升级了啊!
三种方法任选吧
1、你的 C:\documents and settings\all users\application data\kaspersky lab\kav for workstations\6.0\bases里面有个black.lst文件,卡巴只是把你的这个文件给你替换了啊!你可以找一个没有被替换,仍然可以升级的卡巴6拷一个覆盖原来的就行了!最后重新启动系统,这样卡巴又能用了。我用的是工作站版,单机版目录将不同,请按照你的系统安装目录和软件版本找到相应的文件,建议你直接搜索吧 !使用我提供的附件覆盖原来的那个黑名单列表文件即可解决!
2、直接下载离线升级包嘛!
ftp://ru2f.kaspersky-labs.com/bases/av/avc/i386 端口 21 自己用迅雷拖吧!呵呵!也可以直接输入ftp://ru2f.kaspersky-labs.com:21/bases/av/avc/i386
3、改换升级服务器,目前卡巴俄罗斯服务器已经开始封KEY了,但是国内的服务器还是可以用原来key进行升级的!如果还不行可以打开卡巴-设置-更新-自定义-更新服务器-确定最佳更新地区,改成别的国家。大家可以多试一试啊!也可以点击添加,加入具体升级地址。
http://cn1h.kaspersky-labs.com China
http://cn2h.kaspersky-labs.com China
http://cn3h.kaspersky-labs.com China
http://cn4h.kaspersky-labs.com China
http://cn5h.kaspersky-labs.com China
http://cn6h.kaspersky-labs.com China
ftp://cn1f.kaspersky-labs.com China
ftp://cn2f.kaspersky-labs.com China
ftp://cn3f.kaspersky-labs.com China
ftp://cn4f.kaspersky-labs.com China
ftp://cn5f.kaspersky-labs.com China
ftp://cn6f.kaspersky-labs.com
再给你个清华大学升级服务器
http://security.thusns.org/html/index.html
4.是奇虎360赠给国人的礼物,里边有一个能用半年的KAV6.0激活码。http://www.360safe.com/kabacode.php
金山词霸自动取词设置
Posted by
Tony Su
at
7:31 PM
为了效率装了个powerword的老版本2003,原来一直不能取词,也在网上查了解决方法,还是没有试好,没想到今天一试就成了:)
注意在acrobat中取词不是直接运行金山,而是点acrobat工具栏上那个按钮,土了-_-b……
Acrobat Reader 6.0取词:将金山词霸的安装目录下的Xdict32.api复制到Adobe Reader 6.0的安装目录AdobeAcrobat6.0Readerplug_ins 文件夹下即可。
Acrobat 6.0取词:将金山词霸的安装目录下的Xdict32.api复制到Adobe 6.0的安装目录AdobeAcrobat 6.0Acrobatplug_ins文件夹下即可。
如果上述办法仍然无法加入词霸的插件(Acrobat工具栏没有出现词霸的图标),则请到Acrobat6.0的菜单edit>Preference>start up中将"Use only certified plug-ins"(只应用被信任的插件)前面的选项去掉。
【注】Acrobat 6.0在线升级后,会自动加入这个选项,需要手动的去掉。
注意在acrobat中取词不是直接运行金山,而是点acrobat工具栏上那个按钮,土了-_-b……
Acrobat Reader 6.0取词:将金山词霸的安装目录下的Xdict32.api复制到Adobe Reader 6.0的安装目录AdobeAcrobat6.0Readerplug_ins 文件夹下即可。
Acrobat 6.0取词:将金山词霸的安装目录下的Xdict32.api复制到Adobe 6.0的安装目录AdobeAcrobat 6.0Acrobatplug_ins文件夹下即可。
如果上述办法仍然无法加入词霸的插件(Acrobat工具栏没有出现词霸的图标),则请到Acrobat6.0的菜单edit>Preference>start up中将"Use only certified plug-ins"(只应用被信任的插件)前面的选项去掉。
【注】Acrobat 6.0在线升级后,会自动加入这个选项,需要手动的去掉。
世界杯各国进球第一人
Posted by
Tony Su
at
7:27 PM
(按时间顺序排列,以下时间均为当地时间)
1930年乌拉圭世界杯
1.法国:吕西安?劳伦特(Lucien Laurent)
.....1930年7月13日,A组:法国3:1墨西哥.第19分钟
2.墨西哥:胡安?卡雷诺(Juan Carreno)
.....1930年7月13日,A组:墨西哥1:3法国.第70分钟
3.美国:贝尔特?麦克格(Bert McGhee)
.....1930年7月13日,D组:美国3:0比利时.第40分钟
4.南斯拉夫:蒂尔纳尼奇(Aleksandar Tirnanic)
.....1930年7月14日,B组:南斯拉夫2:1巴西.第21分钟
5.巴西:普雷吉尼奥(Preguinho)
.....1930年7月14日,B组:巴西1:2南斯拉夫.第62分钟
6.罗马尼亚:德苏(Adalbert Desu)
.....1930年7月14日,C组:罗马尼亚3:1秘鲁.第1分钟
7.秘鲁:路易斯?索萨(Luis Souza)
.....1930年7月14日,C组:秘鲁1:3罗马尼亚.第63分钟
8.阿根廷:路易斯?蒙蒂(Luis Monti)
.....1930年7月15日,A组:阿根廷1:0法国.第81分钟
9.智利:苏比亚布雷(Guillermo Subiabre)
.....1930年7月16日,A组:智利3:0墨西哥.第4分钟
10.乌拉圭:赫克托?卡斯特罗(Hector Castro)
.....1930年7月18日,C组:乌拉圭1:0秘鲁.第61分钟
11.巴拉圭:路易斯?佩纳(Luis Pena)
.....1930年7月20日,D组:巴拉圭1:0比利时.第40分钟
1934年意大利世界杯
1.瑞典:斯文?乔纳森(Sven Jonasson)
.....1934年5月27日,第一轮:瑞典3:2阿根廷.第8分钟
2.匈牙利:帕尔?特莱基(Pal Teleki)
.....1934年5月27日,第一轮:匈牙利4:2埃及.第12分钟
3.瑞士:基埃霍茨(Leopold Kielholz)
.....1934年5月27日,第一轮:瑞士3:2荷兰.第14分钟
4.意大利:安杰洛?斯奇亚维奥(Angelo Schiavio)
.....1934年5月27日,第一轮:意大利7:1美国.第18分钟
5.西班牙:何塞?伊拉拉格里(Jose Iraragorri)
.....1934年5月27日,第一轮:西班牙3:1巴西.第18分钟
6.荷兰:施密特(Smit)
.....1934年5月27日,第一轮:荷兰2:3瑞士.第22分钟
7.德国:科比尔斯基(Stanislaus Kobierski)
.....1934年5月27日,第一轮:德国5:2比利时.第26分钟
8.比利时:伯纳德?沃尔霍夫(Bernard Voorhoof)
.....1934年5月27日,第一轮:比利时2:5德国.第31分钟
9.埃及:法济(Fawzi)
.....1934年5月27日,第一轮:埃及2:4匈牙利.第38分钟
10.奥地利:马蒂亚斯?辛德拉(Mathias Sindelar)
.....1934年5月27日,第一轮:奥地利3:2法国.第45分钟
11.捷克斯洛伐克:安东尼?普克(Antonin Puc)
.....1934年5月27日,第一轮:捷克斯洛伐克2:1罗马尼亚.第49分钟
1938年法国世界杯
1.波兰:维利莫夫斯基(Ernst Willimowski)
.....1938年6月5日,第一轮:波兰5:6巴西.第22分钟
2.古巴:索科罗(Socorro)
.....1938年6月5日,第一轮:古巴3:3罗马尼亚.第45分钟
3.挪威:阿尔内?布鲁斯塔德(Arne Brustad)
.....1938年6月5日,第一轮:挪威1:2意大利.第83分钟
1950年巴西世界杯
1.英格兰:斯坦?莫藤森(Stan Mortenson)
.....1950年6月25日,A组:英格兰2:0智利.第27分钟
1954年瑞士世界杯
1.土耳其:舒亚特(Suat)
.....1954年6月17日,B组:土耳其1:4德国.第2分钟
1958年瑞典世界杯
1.北爱尔兰:维尔布?库什(Wilbur Cush)
.....1958年6月8日,A组:北爱尔兰1:0捷克斯洛伐克.第20分钟
2.苏格兰:詹姆斯?穆拉伊(James Murray)
.....1958年6月8日,B组:苏格兰1:1南斯拉夫.第48分钟
3.威尔士:约翰?查尔斯(John Charles)
.....1958年6月8日,C组:威尔士1:1匈牙利.第27分钟
4.苏联:尼基塔?西莫尼安(Nikita Simonian)
.....1958年6月8日,D组:苏联2:2英格兰.第13分钟
1962年智利世界杯
1.哥伦比亚:祖鲁加(Francisco Zuluaga)
.....1962年5月30日,A组:哥伦比亚1:2乌拉圭.第20分钟(点球)
2.保加利亚:乔吉?索科洛夫(Georgi Sokolov)
.....1962年6月3日,D组:保加利亚1:6匈牙利.第64分钟
1966年英格兰世界杯
1.葡萄牙:何塞?奥古斯托(Jose Augusto)
.....1966年7月13日,C组:葡萄牙3:1匈牙利.第1分钟
2.朝鲜:朴泽金(Pak Seung-Zin)
.....1966年7月15日,D组:朝鲜1:1西德.第21分钟
1970年墨西哥世界杯
1.以色列:斯皮格莱尔(Spiegler)
.....1970年6月7日,B组:以色列1:1瑞典.第60分钟
2.摩洛哥:穆罕默德?霍马尼(Houmane)
.....1970年7月3日,D组:摩洛哥1:2西德.第21分钟
1974年联邦德国世界杯
1.海地:埃曼努埃尔?萨侬(Emmanuel Sanon)
.....1974年6月15日,D组:海地1:3意大利.第46分钟
2.东德:马丁?霍夫曼(Martin Hoffmann)
.....1974年6月18日,D组:东德1:1智利.第55分钟
1978年阿根廷世界杯
1.突尼斯:阿里?萨比(Ali Kaabi)
.....1978年6月2日,A组:突尼斯3:1墨西哥.第45分钟
2.伊朗:伊拉?达奈法(Iraj Danaifar)
.....1978年6月7日,D组:伊朗1:1苏格兰.第60分钟
(第43分钟埃斯坎达里安攻进乌龙球)
1982年西班牙世界杯
1.萨尔瓦多:路易斯?拉米雷斯(Luis Ramirez)
.....1982年6月15日,C组:萨尔瓦多1:10匈牙利.第64分钟
2.新西兰:斯蒂夫?索内尔(Steve Sumner)
.....1982年6月15日,F组:新西兰2:5苏格兰.第54分钟
3.阿尔及利亚:拉巴赫?马杰尔(Rabah Madjer)
.....1982年6月16日,B组:阿尔及利亚2:1西德.第54分钟
4.洪都拉斯:赫克托?泽拉亚(Hector Zelaya)
.....1982年6月16日,E组:洪都拉斯1:1西班牙.第7分钟
5.科威特:阿尔达克赫尔(Faisal AL-Dakheel)
.....1982年6月17日,D组:科威特1:1捷克斯洛伐克.第58分钟
6.喀麦隆:格雷戈雷?姆比达(Gregoire M'Bida)
.....1982年6月23日,A组:喀麦隆1:1意大利.第61分钟
1986年墨西哥世界杯
1.韩国:(Chang-Seon Park)
.....1986年6月2日,A组:韩国1:3阿根廷.第72分钟
2.丹麦:埃尔克耶尔-拉尔森(Elkjer-Larsen)
.....1986年6月4日,E组:丹麦1:0苏格兰.第58分钟
3.伊拉克:艾哈迈德?阿迈什(Ahmed Amaiesh)
.....1986年6月8日,B组:伊拉克1:2比利时.第57分钟
1990年意大利世界杯
1.哥斯达黎加:胡安?卡亚索(Juan Cayasso)
.....1990年6月11日,C组:哥斯达黎加1:0苏格兰.第57分钟
2.阿联酋:克哈利德?穆巴拉赫(Khalid Mubarak)
.....1990年6月15日,D组:阿联酋1:5西德.第46分钟
1994年美国世界杯
1.沙特阿拉伯:法德?阿明(Fuad Amin)
.....1994年6月20日,F组:沙特阿拉伯1:2荷兰.第19分钟
2.尼日利亚:拉希迪?耶基尼(Rashidi Yekini)
.....1994年6月21日,D组:尼日利亚3:0保加利亚.第21分钟
3.玻利维亚:埃尔文?桑切斯(Erwin Sanchez)
.....1994年6月27日,C组:玻利维亚1:3西班牙.第67分钟
1998年法国世界杯
1.克罗地亚:马里奥?斯塔尼奇(Mario Stanic)
.....1998年6月14日,H组:克罗地亚3:1牙买加.第27分钟
2.牙买加:罗比?埃亚莱(Robbie Earle)
.....1998年6月14日,H组:牙买加1:3克罗地亚.第45分钟
3.南非:贝纳迪?麦卡锡(Benedict McCarthy)
.....1998年6月18日,C组:南非1:1丹麦.第52分钟
4.日本:中山雅史(Masashi Nakayama)
.....1998年6月26日,H组:日本1:2牙买加.第74分钟
2002年韩国、日本世界杯
1.塞内加尔:帕帕?迪奥普(Papa Diop)
.....2002年5月31日,A组:塞内加尔1:0法国.第29分钟
2.斯洛文尼亚:塞米罗蒂奇(Sebastjan Cimirotic)
.....2002年6月2日,B组:斯洛文尼亚1:3西班牙.第81分钟
3.厄瓜多尔:德尔加多(Agustin Delgado)
.....2002年6月9日,G组:厄瓜多尔1:2墨西哥.第4分钟
2006年德国世界杯
1.科特迪瓦:德罗巴(Didier Drogba)
.....2006年6月10日,C组:科特迪瓦1:2阿根廷.第82分钟
2.捷克:科勒(Jan Koller)
.....2006年6月12日,E组:捷克3:0美国.第5分钟
3.多哥:卡德尔(Kader)
.....2006年6月13日,G组:多哥1:2韩国.第31分钟
4.加纳:吉安(Asamoah Gyan)
.....2006年6月17日,E组:加纳2:0捷克.第2分钟
5.乌克兰:鲁索尔(Andriy Rusol)
.....2006年6月19日,H组:乌克兰4:0沙特.第4分钟
6.安哥拉:弗拉维奥(Flavio)
.....2006年6月21日,D组:安哥拉1:1伊朗.第60分钟
7.塞尔维亚和黑山:日吉奇(Nikola Zigic)
.....2006年6月21日,C组:塞尔维亚和黑山2:3科特迪瓦.第10分钟(按时间顺序排列,以下时间均为当地时间)
1930年乌拉圭世界杯
1.法国:吕西安?劳伦特(Lucien Laurent)
.....1930年7月13日,A组:法国3:1墨西哥.第19分钟
2.墨西哥:胡安?卡雷诺(Juan Carreno)
.....1930年7月13日,A组:墨西哥1:3法国.第70分钟
3.美国:贝尔特?麦克格(Bert McGhee)
.....1930年7月13日,D组:美国3:0比利时.第40分钟
4.南斯拉夫:蒂尔纳尼奇(Aleksandar Tirnanic)
.....1930年7月14日,B组:南斯拉夫2:1巴西.第21分钟
5.巴西:普雷吉尼奥(Preguinho)
.....1930年7月14日,B组:巴西1:2南斯拉夫.第62分钟
6.罗马尼亚:德苏(Adalbert Desu)
.....1930年7月14日,C组:罗马尼亚3:1秘鲁.第1分钟
7.秘鲁:路易斯?索萨(Luis Souza)
.....1930年7月14日,C组:秘鲁1:3罗马尼亚.第63分钟
8.阿根廷:路易斯?蒙蒂(Luis Monti)
.....1930年7月15日,A组:阿根廷1:0法国.第81分钟
9.智利:苏比亚布雷(Guillermo Subiabre)
.....1930年7月16日,A组:智利3:0墨西哥.第4分钟
10.乌拉圭:赫克托?卡斯特罗(Hector Castro)
.....1930年7月18日,C组:乌拉圭1:0秘鲁.第61分钟
11.巴拉圭:路易斯?佩纳(Luis Pena)
.....1930年7月20日,D组:巴拉圭1:0比利时.第40分钟
1934年意大利世界杯
1.瑞典:斯文?乔纳森(Sven Jonasson)
.....1934年5月27日,第一轮:瑞典3:2阿根廷.第8分钟
2.匈牙利:帕尔?特莱基(Pal Teleki)
.....1934年5月27日,第一轮:匈牙利4:2埃及.第12分钟
3.瑞士:基埃霍茨(Leopold Kielholz)
.....1934年5月27日,第一轮:瑞士3:2荷兰.第14分钟
4.意大利:安杰洛?斯奇亚维奥(Angelo Schiavio)
.....1934年5月27日,第一轮:意大利7:1美国.第18分钟
5.西班牙:何塞?伊拉拉格里(Jose Iraragorri)
.....1934年5月27日,第一轮:西班牙3:1巴西.第18分钟
6.荷兰:施密特(Smit)
.....1934年5月27日,第一轮:荷兰2:3瑞士.第22分钟
7.德国:科比尔斯基(Stanislaus Kobierski)
.....1934年5月27日,第一轮:德国5:2比利时.第26分钟
8.比利时:伯纳德?沃尔霍夫(Bernard Voorhoof)
.....1934年5月27日,第一轮:比利时2:5德国.第31分钟
9.埃及:法济(Fawzi)
.....1934年5月27日,第一轮:埃及2:4匈牙利.第38分钟
10.奥地利:马蒂亚斯?辛德拉(Mathias Sindelar)
.....1934年5月27日,第一轮:奥地利3:2法国.第45分钟
11.捷克斯洛伐克:安东尼?普克(Antonin Puc)
.....1934年5月27日,第一轮:捷克斯洛伐克2:1罗马尼亚.第49分钟
1938年法国世界杯
1.波兰:维利莫夫斯基(Ernst Willimowski)
.....1938年6月5日,第一轮:波兰5:6巴西.第22分钟
2.古巴:索科罗(Socorro)
.....1938年6月5日,第一轮:古巴3:3罗马尼亚.第45分钟
3.挪威:阿尔内?布鲁斯塔德(Arne Brustad)
.....1938年6月5日,第一轮:挪威1:2意大利.第83分钟
1950年巴西世界杯
1.英格兰:斯坦?莫藤森(Stan Mortenson)
.....1950年6月25日,A组:英格兰2:0智利.第27分钟
1954年瑞士世界杯
1.土耳其:舒亚特(Suat)
.....1954年6月17日,B组:土耳其1:4德国.第2分钟
1958年瑞典世界杯
1.北爱尔兰:维尔布?库什(Wilbur Cush)
.....1958年6月8日,A组:北爱尔兰1:0捷克斯洛伐克.第20分钟
2.苏格兰:詹姆斯?穆拉伊(James Murray)
.....1958年6月8日,B组:苏格兰1:1南斯拉夫.第48分钟
3.威尔士:约翰?查尔斯(John Charles)
.....1958年6月8日,C组:威尔士1:1匈牙利.第27分钟
4.苏联:尼基塔?西莫尼安(Nikita Simonian)
.....1958年6月8日,D组:苏联2:2英格兰.第13分钟
1962年智利世界杯
1.哥伦比亚:祖鲁加(Francisco Zuluaga)
.....1962年5月30日,A组:哥伦比亚1:2乌拉圭.第20分钟(点球)
2.保加利亚:乔吉?索科洛夫(Georgi Sokolov)
.....1962年6月3日,D组:保加利亚1:6匈牙利.第64分钟
1966年英格兰世界杯
1.葡萄牙:何塞?奥古斯托(Jose Augusto)
.....1966年7月13日,C组:葡萄牙3:1匈牙利.第1分钟
2.朝鲜:朴泽金(Pak Seung-Zin)
.....1966年7月15日,D组:朝鲜1:1西德.第21分钟
1970年墨西哥世界杯
1.以色列:斯皮格莱尔(Spiegler)
.....1970年6月7日,B组:以色列1:1瑞典.第60分钟
2.摩洛哥:穆罕默德?霍马尼(Houmane)
.....1970年7月3日,D组:摩洛哥1:2西德.第21分钟
1974年联邦德国世界杯
1.海地:埃曼努埃尔?萨侬(Emmanuel Sanon)
.....1974年6月15日,D组:海地1:3意大利.第46分钟
2.东德:马丁?霍夫曼(Martin Hoffmann)
.....1974年6月18日,D组:东德1:1智利.第55分钟
1978年阿根廷世界杯
1.突尼斯:阿里?萨比(Ali Kaabi)
.....1978年6月2日,A组:突尼斯3:1墨西哥.第45分钟
2.伊朗:伊拉?达奈法(Iraj Danaifar)
.....1978年6月7日,D组:伊朗1:1苏格兰.第60分钟
(第43分钟埃斯坎达里安攻进乌龙球)
1982年西班牙世界杯
1.萨尔瓦多:路易斯?拉米雷斯(Luis Ramirez)
.....1982年6月15日,C组:萨尔瓦多1:10匈牙利.第64分钟
2.新西兰:斯蒂夫?索内尔(Steve Sumner)
.....1982年6月15日,F组:新西兰2:5苏格兰.第54分钟
3.阿尔及利亚:拉巴赫?马杰尔(Rabah Madjer)
.....1982年6月16日,B组:阿尔及利亚2:1西德.第54分钟
4.洪都拉斯:赫克托?泽拉亚(Hector Zelaya)
.....1982年6月16日,E组:洪都拉斯1:1西班牙.第7分钟
5.科威特:阿尔达克赫尔(Faisal AL-Dakheel)
.....1982年6月17日,D组:科威特1:1捷克斯洛伐克.第58分钟
6.喀麦隆:格雷戈雷?姆比达(Gregoire M'Bida)
.....1982年6月23日,A组:喀麦隆1:1意大利.第61分钟
1986年墨西哥世界杯
1.韩国:(Chang-Seon Park)
.....1986年6月2日,A组:韩国1:3阿根廷.第72分钟
2.丹麦:埃尔克耶尔-拉尔森(Elkjer-Larsen)
.....1986年6月4日,E组:丹麦1:0苏格兰.第58分钟
3.伊拉克:艾哈迈德?阿迈什(Ahmed Amaiesh)
.....1986年6月8日,B组:伊拉克1:2比利时.第57分钟
1990年意大利世界杯
1.哥斯达黎加:胡安?卡亚索(Juan Cayasso)
.....1990年6月11日,C组:哥斯达黎加1:0苏格兰.第57分钟
2.阿联酋:克哈利德?穆巴拉赫(Khalid Mubarak)
.....1990年6月15日,D组:阿联酋1:5西德.第46分钟
1994年美国世界杯
1.沙特阿拉伯:法德?阿明(Fuad Amin)
.....1994年6月20日,F组:沙特阿拉伯1:2荷兰.第19分钟
2.尼日利亚:拉希迪?耶基尼(Rashidi Yekini)
.....1994年6月21日,D组:尼日利亚3:0保加利亚.第21分钟
3.玻利维亚:埃尔文?桑切斯(Erwin Sanchez)
.....1994年6月27日,C组:玻利维亚1:3西班牙.第67分钟
1998年法国世界杯
1.克罗地亚:马里奥?斯塔尼奇(Mario Stanic)
.....1998年6月14日,H组:克罗地亚3:1牙买加.第27分钟
2.牙买加:罗比?埃亚莱(Robbie Earle)
.....1998年6月14日,H组:牙买加1:3克罗地亚.第45分钟
3.南非:贝纳迪?麦卡锡(Benedict McCarthy)
.....1998年6月18日,C组:南非1:1丹麦.第52分钟
4.日本:中山雅史(Masashi Nakayama)
.....1998年6月26日,H组:日本1:2牙买加.第74分钟
2002年韩国、日本世界杯
1.塞内加尔:帕帕?迪奥普(Papa Diop)
.....2002年5月31日,A组:塞内加尔1:0法国.第29分钟
2.斯洛文尼亚:塞米罗蒂奇(Sebastjan Cimirotic)
.....2002年6月2日,B组:斯洛文尼亚1:3西班牙.第81分钟
3.厄瓜多尔:德尔加多(Agustin Delgado)
.....2002年6月9日,G组:厄瓜多尔1:2墨西哥.第4分钟
2006年德国世界杯
1.科特迪瓦:德罗巴(Didier Drogba)
.....2006年6月10日,C组:科特迪瓦1:2阿根廷.第82分钟
2.捷克:科勒(Jan Koller)
.....2006年6月12日,E组:捷克3:0美国.第5分钟
3.多哥:卡德尔(Kader)
.....2006年6月13日,G组:多哥1:2韩国.第31分钟
4.加纳:吉安(Asamoah Gyan)
.....2006年6月17日,E组:加纳2:0捷克.第2分钟
5.乌克兰:鲁索尔(Andriy Rusol)
.....2006年6月19日,H组:乌克兰4:0沙特.第4分钟
6.安哥拉:弗拉维奥(Flavio)
.....2006年6月21日,D组:安哥拉1:1伊朗.第60分钟
7.塞尔维亚和黑山:日吉奇(Nikola Zigic)
.....2006年6月21日,C组:塞尔维亚和黑山2:3科特迪瓦.第10分钟
1930年乌拉圭世界杯
1.法国:吕西安?劳伦特(Lucien Laurent)
.....1930年7月13日,A组:法国3:1墨西哥.第19分钟
2.墨西哥:胡安?卡雷诺(Juan Carreno)
.....1930年7月13日,A组:墨西哥1:3法国.第70分钟
3.美国:贝尔特?麦克格(Bert McGhee)
.....1930年7月13日,D组:美国3:0比利时.第40分钟
4.南斯拉夫:蒂尔纳尼奇(Aleksandar Tirnanic)
.....1930年7月14日,B组:南斯拉夫2:1巴西.第21分钟
5.巴西:普雷吉尼奥(Preguinho)
.....1930年7月14日,B组:巴西1:2南斯拉夫.第62分钟
6.罗马尼亚:德苏(Adalbert Desu)
.....1930年7月14日,C组:罗马尼亚3:1秘鲁.第1分钟
7.秘鲁:路易斯?索萨(Luis Souza)
.....1930年7月14日,C组:秘鲁1:3罗马尼亚.第63分钟
8.阿根廷:路易斯?蒙蒂(Luis Monti)
.....1930年7月15日,A组:阿根廷1:0法国.第81分钟
9.智利:苏比亚布雷(Guillermo Subiabre)
.....1930年7月16日,A组:智利3:0墨西哥.第4分钟
10.乌拉圭:赫克托?卡斯特罗(Hector Castro)
.....1930年7月18日,C组:乌拉圭1:0秘鲁.第61分钟
11.巴拉圭:路易斯?佩纳(Luis Pena)
.....1930年7月20日,D组:巴拉圭1:0比利时.第40分钟
1934年意大利世界杯
1.瑞典:斯文?乔纳森(Sven Jonasson)
.....1934年5月27日,第一轮:瑞典3:2阿根廷.第8分钟
2.匈牙利:帕尔?特莱基(Pal Teleki)
.....1934年5月27日,第一轮:匈牙利4:2埃及.第12分钟
3.瑞士:基埃霍茨(Leopold Kielholz)
.....1934年5月27日,第一轮:瑞士3:2荷兰.第14分钟
4.意大利:安杰洛?斯奇亚维奥(Angelo Schiavio)
.....1934年5月27日,第一轮:意大利7:1美国.第18分钟
5.西班牙:何塞?伊拉拉格里(Jose Iraragorri)
.....1934年5月27日,第一轮:西班牙3:1巴西.第18分钟
6.荷兰:施密特(Smit)
.....1934年5月27日,第一轮:荷兰2:3瑞士.第22分钟
7.德国:科比尔斯基(Stanislaus Kobierski)
.....1934年5月27日,第一轮:德国5:2比利时.第26分钟
8.比利时:伯纳德?沃尔霍夫(Bernard Voorhoof)
.....1934年5月27日,第一轮:比利时2:5德国.第31分钟
9.埃及:法济(Fawzi)
.....1934年5月27日,第一轮:埃及2:4匈牙利.第38分钟
10.奥地利:马蒂亚斯?辛德拉(Mathias Sindelar)
.....1934年5月27日,第一轮:奥地利3:2法国.第45分钟
11.捷克斯洛伐克:安东尼?普克(Antonin Puc)
.....1934年5月27日,第一轮:捷克斯洛伐克2:1罗马尼亚.第49分钟
1938年法国世界杯
1.波兰:维利莫夫斯基(Ernst Willimowski)
.....1938年6月5日,第一轮:波兰5:6巴西.第22分钟
2.古巴:索科罗(Socorro)
.....1938年6月5日,第一轮:古巴3:3罗马尼亚.第45分钟
3.挪威:阿尔内?布鲁斯塔德(Arne Brustad)
.....1938年6月5日,第一轮:挪威1:2意大利.第83分钟
1950年巴西世界杯
1.英格兰:斯坦?莫藤森(Stan Mortenson)
.....1950年6月25日,A组:英格兰2:0智利.第27分钟
1954年瑞士世界杯
1.土耳其:舒亚特(Suat)
.....1954年6月17日,B组:土耳其1:4德国.第2分钟
1958年瑞典世界杯
1.北爱尔兰:维尔布?库什(Wilbur Cush)
.....1958年6月8日,A组:北爱尔兰1:0捷克斯洛伐克.第20分钟
2.苏格兰:詹姆斯?穆拉伊(James Murray)
.....1958年6月8日,B组:苏格兰1:1南斯拉夫.第48分钟
3.威尔士:约翰?查尔斯(John Charles)
.....1958年6月8日,C组:威尔士1:1匈牙利.第27分钟
4.苏联:尼基塔?西莫尼安(Nikita Simonian)
.....1958年6月8日,D组:苏联2:2英格兰.第13分钟
1962年智利世界杯
1.哥伦比亚:祖鲁加(Francisco Zuluaga)
.....1962年5月30日,A组:哥伦比亚1:2乌拉圭.第20分钟(点球)
2.保加利亚:乔吉?索科洛夫(Georgi Sokolov)
.....1962年6月3日,D组:保加利亚1:6匈牙利.第64分钟
1966年英格兰世界杯
1.葡萄牙:何塞?奥古斯托(Jose Augusto)
.....1966年7月13日,C组:葡萄牙3:1匈牙利.第1分钟
2.朝鲜:朴泽金(Pak Seung-Zin)
.....1966年7月15日,D组:朝鲜1:1西德.第21分钟
1970年墨西哥世界杯
1.以色列:斯皮格莱尔(Spiegler)
.....1970年6月7日,B组:以色列1:1瑞典.第60分钟
2.摩洛哥:穆罕默德?霍马尼(Houmane)
.....1970年7月3日,D组:摩洛哥1:2西德.第21分钟
1974年联邦德国世界杯
1.海地:埃曼努埃尔?萨侬(Emmanuel Sanon)
.....1974年6月15日,D组:海地1:3意大利.第46分钟
2.东德:马丁?霍夫曼(Martin Hoffmann)
.....1974年6月18日,D组:东德1:1智利.第55分钟
1978年阿根廷世界杯
1.突尼斯:阿里?萨比(Ali Kaabi)
.....1978年6月2日,A组:突尼斯3:1墨西哥.第45分钟
2.伊朗:伊拉?达奈法(Iraj Danaifar)
.....1978年6月7日,D组:伊朗1:1苏格兰.第60分钟
(第43分钟埃斯坎达里安攻进乌龙球)
1982年西班牙世界杯
1.萨尔瓦多:路易斯?拉米雷斯(Luis Ramirez)
.....1982年6月15日,C组:萨尔瓦多1:10匈牙利.第64分钟
2.新西兰:斯蒂夫?索内尔(Steve Sumner)
.....1982年6月15日,F组:新西兰2:5苏格兰.第54分钟
3.阿尔及利亚:拉巴赫?马杰尔(Rabah Madjer)
.....1982年6月16日,B组:阿尔及利亚2:1西德.第54分钟
4.洪都拉斯:赫克托?泽拉亚(Hector Zelaya)
.....1982年6月16日,E组:洪都拉斯1:1西班牙.第7分钟
5.科威特:阿尔达克赫尔(Faisal AL-Dakheel)
.....1982年6月17日,D组:科威特1:1捷克斯洛伐克.第58分钟
6.喀麦隆:格雷戈雷?姆比达(Gregoire M'Bida)
.....1982年6月23日,A组:喀麦隆1:1意大利.第61分钟
1986年墨西哥世界杯
1.韩国:(Chang-Seon Park)
.....1986年6月2日,A组:韩国1:3阿根廷.第72分钟
2.丹麦:埃尔克耶尔-拉尔森(Elkjer-Larsen)
.....1986年6月4日,E组:丹麦1:0苏格兰.第58分钟
3.伊拉克:艾哈迈德?阿迈什(Ahmed Amaiesh)
.....1986年6月8日,B组:伊拉克1:2比利时.第57分钟
1990年意大利世界杯
1.哥斯达黎加:胡安?卡亚索(Juan Cayasso)
.....1990年6月11日,C组:哥斯达黎加1:0苏格兰.第57分钟
2.阿联酋:克哈利德?穆巴拉赫(Khalid Mubarak)
.....1990年6月15日,D组:阿联酋1:5西德.第46分钟
1994年美国世界杯
1.沙特阿拉伯:法德?阿明(Fuad Amin)
.....1994年6月20日,F组:沙特阿拉伯1:2荷兰.第19分钟
2.尼日利亚:拉希迪?耶基尼(Rashidi Yekini)
.....1994年6月21日,D组:尼日利亚3:0保加利亚.第21分钟
3.玻利维亚:埃尔文?桑切斯(Erwin Sanchez)
.....1994年6月27日,C组:玻利维亚1:3西班牙.第67分钟
1998年法国世界杯
1.克罗地亚:马里奥?斯塔尼奇(Mario Stanic)
.....1998年6月14日,H组:克罗地亚3:1牙买加.第27分钟
2.牙买加:罗比?埃亚莱(Robbie Earle)
.....1998年6月14日,H组:牙买加1:3克罗地亚.第45分钟
3.南非:贝纳迪?麦卡锡(Benedict McCarthy)
.....1998年6月18日,C组:南非1:1丹麦.第52分钟
4.日本:中山雅史(Masashi Nakayama)
.....1998年6月26日,H组:日本1:2牙买加.第74分钟
2002年韩国、日本世界杯
1.塞内加尔:帕帕?迪奥普(Papa Diop)
.....2002年5月31日,A组:塞内加尔1:0法国.第29分钟
2.斯洛文尼亚:塞米罗蒂奇(Sebastjan Cimirotic)
.....2002年6月2日,B组:斯洛文尼亚1:3西班牙.第81分钟
3.厄瓜多尔:德尔加多(Agustin Delgado)
.....2002年6月9日,G组:厄瓜多尔1:2墨西哥.第4分钟
2006年德国世界杯
1.科特迪瓦:德罗巴(Didier Drogba)
.....2006年6月10日,C组:科特迪瓦1:2阿根廷.第82分钟
2.捷克:科勒(Jan Koller)
.....2006年6月12日,E组:捷克3:0美国.第5分钟
3.多哥:卡德尔(Kader)
.....2006年6月13日,G组:多哥1:2韩国.第31分钟
4.加纳:吉安(Asamoah Gyan)
.....2006年6月17日,E组:加纳2:0捷克.第2分钟
5.乌克兰:鲁索尔(Andriy Rusol)
.....2006年6月19日,H组:乌克兰4:0沙特.第4分钟
6.安哥拉:弗拉维奥(Flavio)
.....2006年6月21日,D组:安哥拉1:1伊朗.第60分钟
7.塞尔维亚和黑山:日吉奇(Nikola Zigic)
.....2006年6月21日,C组:塞尔维亚和黑山2:3科特迪瓦.第10分钟(按时间顺序排列,以下时间均为当地时间)
1930年乌拉圭世界杯
1.法国:吕西安?劳伦特(Lucien Laurent)
.....1930年7月13日,A组:法国3:1墨西哥.第19分钟
2.墨西哥:胡安?卡雷诺(Juan Carreno)
.....1930年7月13日,A组:墨西哥1:3法国.第70分钟
3.美国:贝尔特?麦克格(Bert McGhee)
.....1930年7月13日,D组:美国3:0比利时.第40分钟
4.南斯拉夫:蒂尔纳尼奇(Aleksandar Tirnanic)
.....1930年7月14日,B组:南斯拉夫2:1巴西.第21分钟
5.巴西:普雷吉尼奥(Preguinho)
.....1930年7月14日,B组:巴西1:2南斯拉夫.第62分钟
6.罗马尼亚:德苏(Adalbert Desu)
.....1930年7月14日,C组:罗马尼亚3:1秘鲁.第1分钟
7.秘鲁:路易斯?索萨(Luis Souza)
.....1930年7月14日,C组:秘鲁1:3罗马尼亚.第63分钟
8.阿根廷:路易斯?蒙蒂(Luis Monti)
.....1930年7月15日,A组:阿根廷1:0法国.第81分钟
9.智利:苏比亚布雷(Guillermo Subiabre)
.....1930年7月16日,A组:智利3:0墨西哥.第4分钟
10.乌拉圭:赫克托?卡斯特罗(Hector Castro)
.....1930年7月18日,C组:乌拉圭1:0秘鲁.第61分钟
11.巴拉圭:路易斯?佩纳(Luis Pena)
.....1930年7月20日,D组:巴拉圭1:0比利时.第40分钟
1934年意大利世界杯
1.瑞典:斯文?乔纳森(Sven Jonasson)
.....1934年5月27日,第一轮:瑞典3:2阿根廷.第8分钟
2.匈牙利:帕尔?特莱基(Pal Teleki)
.....1934年5月27日,第一轮:匈牙利4:2埃及.第12分钟
3.瑞士:基埃霍茨(Leopold Kielholz)
.....1934年5月27日,第一轮:瑞士3:2荷兰.第14分钟
4.意大利:安杰洛?斯奇亚维奥(Angelo Schiavio)
.....1934年5月27日,第一轮:意大利7:1美国.第18分钟
5.西班牙:何塞?伊拉拉格里(Jose Iraragorri)
.....1934年5月27日,第一轮:西班牙3:1巴西.第18分钟
6.荷兰:施密特(Smit)
.....1934年5月27日,第一轮:荷兰2:3瑞士.第22分钟
7.德国:科比尔斯基(Stanislaus Kobierski)
.....1934年5月27日,第一轮:德国5:2比利时.第26分钟
8.比利时:伯纳德?沃尔霍夫(Bernard Voorhoof)
.....1934年5月27日,第一轮:比利时2:5德国.第31分钟
9.埃及:法济(Fawzi)
.....1934年5月27日,第一轮:埃及2:4匈牙利.第38分钟
10.奥地利:马蒂亚斯?辛德拉(Mathias Sindelar)
.....1934年5月27日,第一轮:奥地利3:2法国.第45分钟
11.捷克斯洛伐克:安东尼?普克(Antonin Puc)
.....1934年5月27日,第一轮:捷克斯洛伐克2:1罗马尼亚.第49分钟
1938年法国世界杯
1.波兰:维利莫夫斯基(Ernst Willimowski)
.....1938年6月5日,第一轮:波兰5:6巴西.第22分钟
2.古巴:索科罗(Socorro)
.....1938年6月5日,第一轮:古巴3:3罗马尼亚.第45分钟
3.挪威:阿尔内?布鲁斯塔德(Arne Brustad)
.....1938年6月5日,第一轮:挪威1:2意大利.第83分钟
1950年巴西世界杯
1.英格兰:斯坦?莫藤森(Stan Mortenson)
.....1950年6月25日,A组:英格兰2:0智利.第27分钟
1954年瑞士世界杯
1.土耳其:舒亚特(Suat)
.....1954年6月17日,B组:土耳其1:4德国.第2分钟
1958年瑞典世界杯
1.北爱尔兰:维尔布?库什(Wilbur Cush)
.....1958年6月8日,A组:北爱尔兰1:0捷克斯洛伐克.第20分钟
2.苏格兰:詹姆斯?穆拉伊(James Murray)
.....1958年6月8日,B组:苏格兰1:1南斯拉夫.第48分钟
3.威尔士:约翰?查尔斯(John Charles)
.....1958年6月8日,C组:威尔士1:1匈牙利.第27分钟
4.苏联:尼基塔?西莫尼安(Nikita Simonian)
.....1958年6月8日,D组:苏联2:2英格兰.第13分钟
1962年智利世界杯
1.哥伦比亚:祖鲁加(Francisco Zuluaga)
.....1962年5月30日,A组:哥伦比亚1:2乌拉圭.第20分钟(点球)
2.保加利亚:乔吉?索科洛夫(Georgi Sokolov)
.....1962年6月3日,D组:保加利亚1:6匈牙利.第64分钟
1966年英格兰世界杯
1.葡萄牙:何塞?奥古斯托(Jose Augusto)
.....1966年7月13日,C组:葡萄牙3:1匈牙利.第1分钟
2.朝鲜:朴泽金(Pak Seung-Zin)
.....1966年7月15日,D组:朝鲜1:1西德.第21分钟
1970年墨西哥世界杯
1.以色列:斯皮格莱尔(Spiegler)
.....1970年6月7日,B组:以色列1:1瑞典.第60分钟
2.摩洛哥:穆罕默德?霍马尼(Houmane)
.....1970年7月3日,D组:摩洛哥1:2西德.第21分钟
1974年联邦德国世界杯
1.海地:埃曼努埃尔?萨侬(Emmanuel Sanon)
.....1974年6月15日,D组:海地1:3意大利.第46分钟
2.东德:马丁?霍夫曼(Martin Hoffmann)
.....1974年6月18日,D组:东德1:1智利.第55分钟
1978年阿根廷世界杯
1.突尼斯:阿里?萨比(Ali Kaabi)
.....1978年6月2日,A组:突尼斯3:1墨西哥.第45分钟
2.伊朗:伊拉?达奈法(Iraj Danaifar)
.....1978年6月7日,D组:伊朗1:1苏格兰.第60分钟
(第43分钟埃斯坎达里安攻进乌龙球)
1982年西班牙世界杯
1.萨尔瓦多:路易斯?拉米雷斯(Luis Ramirez)
.....1982年6月15日,C组:萨尔瓦多1:10匈牙利.第64分钟
2.新西兰:斯蒂夫?索内尔(Steve Sumner)
.....1982年6月15日,F组:新西兰2:5苏格兰.第54分钟
3.阿尔及利亚:拉巴赫?马杰尔(Rabah Madjer)
.....1982年6月16日,B组:阿尔及利亚2:1西德.第54分钟
4.洪都拉斯:赫克托?泽拉亚(Hector Zelaya)
.....1982年6月16日,E组:洪都拉斯1:1西班牙.第7分钟
5.科威特:阿尔达克赫尔(Faisal AL-Dakheel)
.....1982年6月17日,D组:科威特1:1捷克斯洛伐克.第58分钟
6.喀麦隆:格雷戈雷?姆比达(Gregoire M'Bida)
.....1982年6月23日,A组:喀麦隆1:1意大利.第61分钟
1986年墨西哥世界杯
1.韩国:(Chang-Seon Park)
.....1986年6月2日,A组:韩国1:3阿根廷.第72分钟
2.丹麦:埃尔克耶尔-拉尔森(Elkjer-Larsen)
.....1986年6月4日,E组:丹麦1:0苏格兰.第58分钟
3.伊拉克:艾哈迈德?阿迈什(Ahmed Amaiesh)
.....1986年6月8日,B组:伊拉克1:2比利时.第57分钟
1990年意大利世界杯
1.哥斯达黎加:胡安?卡亚索(Juan Cayasso)
.....1990年6月11日,C组:哥斯达黎加1:0苏格兰.第57分钟
2.阿联酋:克哈利德?穆巴拉赫(Khalid Mubarak)
.....1990年6月15日,D组:阿联酋1:5西德.第46分钟
1994年美国世界杯
1.沙特阿拉伯:法德?阿明(Fuad Amin)
.....1994年6月20日,F组:沙特阿拉伯1:2荷兰.第19分钟
2.尼日利亚:拉希迪?耶基尼(Rashidi Yekini)
.....1994年6月21日,D组:尼日利亚3:0保加利亚.第21分钟
3.玻利维亚:埃尔文?桑切斯(Erwin Sanchez)
.....1994年6月27日,C组:玻利维亚1:3西班牙.第67分钟
1998年法国世界杯
1.克罗地亚:马里奥?斯塔尼奇(Mario Stanic)
.....1998年6月14日,H组:克罗地亚3:1牙买加.第27分钟
2.牙买加:罗比?埃亚莱(Robbie Earle)
.....1998年6月14日,H组:牙买加1:3克罗地亚.第45分钟
3.南非:贝纳迪?麦卡锡(Benedict McCarthy)
.....1998年6月18日,C组:南非1:1丹麦.第52分钟
4.日本:中山雅史(Masashi Nakayama)
.....1998年6月26日,H组:日本1:2牙买加.第74分钟
2002年韩国、日本世界杯
1.塞内加尔:帕帕?迪奥普(Papa Diop)
.....2002年5月31日,A组:塞内加尔1:0法国.第29分钟
2.斯洛文尼亚:塞米罗蒂奇(Sebastjan Cimirotic)
.....2002年6月2日,B组:斯洛文尼亚1:3西班牙.第81分钟
3.厄瓜多尔:德尔加多(Agustin Delgado)
.....2002年6月9日,G组:厄瓜多尔1:2墨西哥.第4分钟
2006年德国世界杯
1.科特迪瓦:德罗巴(Didier Drogba)
.....2006年6月10日,C组:科特迪瓦1:2阿根廷.第82分钟
2.捷克:科勒(Jan Koller)
.....2006年6月12日,E组:捷克3:0美国.第5分钟
3.多哥:卡德尔(Kader)
.....2006年6月13日,G组:多哥1:2韩国.第31分钟
4.加纳:吉安(Asamoah Gyan)
.....2006年6月17日,E组:加纳2:0捷克.第2分钟
5.乌克兰:鲁索尔(Andriy Rusol)
.....2006年6月19日,H组:乌克兰4:0沙特.第4分钟
6.安哥拉:弗拉维奥(Flavio)
.....2006年6月21日,D组:安哥拉1:1伊朗.第60分钟
7.塞尔维亚和黑山:日吉奇(Nikola Zigic)
.....2006年6月21日,C组:塞尔维亚和黑山2:3科特迪瓦.第10分钟
UTF-8 字符集基础
Posted by
Tony Su
at
7:24 PM
UTF-8 字符集基础
字符集简史
在所有字符集中,最知名可能要数被称为ASCII的7位字符集了。它是美国信息交换标准委员会
(American Standards Committee for Information Interchange)的缩写, 为美国英语通信所设计。它由128个字符
组成,包括大小写字母、数字0-9、标点符号、非打印字符(换行符、制表符等4个)以及控制字符(
退格、响铃等)组成。
但是,由于他是针对英语设计的,当处理带有音调标号(形如汉语的拼音)的欧洲文字时就会出现问
题。因此,创建出了一些包括255个字符的由ASCII扩展的字符集。其中有一种通常被成为IBM字符集,
它把值为128-255之间的字符用于画图和画线,以及一些特殊的欧洲字符。另一种8位字符集是ISO 8859
-1 Latin 1,也简称为ISO Latin-1。它把位于128-255之间的字符用于拉丁字母表中特殊语言字符的编码,
也因此而得名。
欧洲语言不是地球上的唯一语言,因此亚洲和非洲语言并不能被8位字符集所支持。仅汉语(或
pictograms)字母表就有80000以上个字符。但是把汉语、日语和越南语的一些相似的字符结合起来,在
不同的语言里,使不同的字符代表不同的字,这样只用2个字节就可以编码地球上几乎所有地区的文
字。因此,创建了UNICODE编码。它通过增加一个高字节对ISO Latin-1字符集进行扩展,当这些高字节
位为0时,低字节就是ISO Latin-1字符。UNICODE支持欧洲、非洲、中东、亚洲(包括统一标准的东亚像
形汉字和韩国像形文字)。但是,UNICODE并没有提供对诸如Braille, Cherokee, Ethiopic, Khmer, Mongolian,
Hmong, Tai Lu, Tai Mau文字的支持。同时它也不支持如Ahom, Akkadian, Aramaic, Babylonian Cuneiform, Balti,
Brahmi, Etruscan, Hittite, Javanese, Numidian, Old Persian Cuneiform, Syrian之类的古老的文字。
事实证明,对可以用ASCII表示的字符使用UNICODE并不高效,因为UNICODE比ASCII占用大一倍的空间
,而对ASCII来说高字节的0对他毫无用处。为了解决这个问题,就出现了一些中间格式的字符集,他
们被称为通用转换格式,既UTF(Universal Transformation Format)。目前存在的UTF格式有:UTF-7, UTF-
7.5, UTF-8, UTF-16, 以及 UTF-32。本文讨论UTF-8字符集的基础。
UTF_8字符集
UTF-8是UNICODE的一种变长字符编码,由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。
UTF-8用1到6个字节编码UNICODE字符。如果UNICODE字符由2个字节表示,则编码成UTF-8很可能需要3
个字节,而如果UNICODE字符由4个字节表示,则编码成UTF-8可能需要6个字节。用4个或6个字节去编
码一个UNICODE字符可能太多了,但很少会遇到那样的UNICODE字符。
UFT-8转换表表示如下:
UNICODE UTF-8
00000000 - 0000007F 0xxxxxxx
00000080 - 000007FF 110xxxxx 10xxxxxx
00000800 - 0000FFFF 1110xxxx 10xxxxxx 10xxxxxx
00010000 - 001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
00200000 - 03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
04000000 - 7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
实际表示ASCII字符的UNICODE字符,将会编码成1个字节,并且UTF-8表示与ASCII字符表示是一样的。
所有其他的UNCODE字符转化成UTF-8将需要至少2个字节。每个字节由一个换码序列开始。第一个字节
由唯一的换码序列,由n位1加一位0组成。n位1表示字符编码所需的字节数。
示例
UNICODE uCA(11001010) 编码成UTF-8将需要2个字节:
uCA -> C3 8A
1100 1010
110xxxxx 10xxxxxx
1100 1010 -> 110xxxxx 10xxxxxx
-> 110xxxxx 10xxxxx0
-> 110xxxxx 10xxxx10
-> 110xxxxx 10xxx010
-> 110xxxxx 10xx1010
-> 110xxxxx 10x01010
-> 110xxxxx 10001010
-> 110xxxx1 10001010
-> 110xxx11 10001010
-> 11000011 10001010
-> C3 8A
UNICODE uF03F (11110000 00111111) 编码成UTF-8将需要3个字节:
u F03F -> EF 80 BF
1111 0000 0011 1111 -> 1110xxxx 10xxxxxx 10xxxxxx
-> 11101111 10000000 10111111
-> EF 80 BF
译者注:由上分析可以看到,UNCODE到UTF-8的转换就是先确定编码所需要的字节数,然后用
UNICODE编码位从低位到高位依次填入上面表示为x的位上,不足的高位以0补充。以上是个人经验,
如有错误,请不惜指教,谢过先:)
UTF-8编码的优点:
UTF-8编码可以通过屏蔽位和移位操作快速读写。
字符串比较时strcmp()和wcscmp()的返回结果相同,因此使排序变得更加容易。
字节FF和FE在UTF-8编码中永远不会出现,因此他们可以用来表明UTF-16或UTF-32文本(见BOM)
UTF-8 是字节顺序无关的。它的字节顺序在所有系统中都是一样的,因此它实际上并不需要BOM。
UTF-8编码的缺点:
你无法从UNICODE字符数判断出UTF-8文本的字节数,因为UTF-8是一种变长编码
它需要用2个字节编码那些用扩展ASCII字符集只需1个字节的字符
ISO Latin-1 是UNICODE的子集,但不是UTF-8的子集
8位字符的UTF-8编码会被email网关过滤,因为internet信息最初设计为7为ASCII码。因此产生了UTF-7编码
。
UTF-8 在它的表示中使用值100xxxxx的几率超过50%, 而现存的实现如ISO 2022, 4873, 6429, 和8859系
统,会把它错认为是C1 控制码。因此产生了UTF-7.5编码。
修正的UTF-8:
java使用UTF-16表示内部文本,并支持用于字符串串行化的非标准的修正UTF-8编码。标准UTF-8和修正
的UTF-8有两点不同:
修正的UTF-8中,null字符编码成2个字节(11000000 00000000) 而不是标准的1个字节(00000000),这
样作可以保证编码后的字符串中不会嵌入null字符。因此如果在类C语言中处理字符串,文本不会在第
一个null字符时截断(C字符串以null结尾)。
在标准UTF-8编码中,超出基本多语言范围(BMP - Basic Multilingual Plain)的字符被编码为4字节格式,
但是在修正的UTF-8编码中,他们由代理编码对(surrogate pairs)表示,然后这些代理编码对在序列中
分别重新编码。结果标准UTF-8编码中需要4个字节的字符,在修正后的UTF-8编码中将需要6个字节。
位序标志BOM
BOM(Byte Order Mark)是一个字符,它表明UNICODE文本的UTF-16,UTF-32的编码字节顺序(高字节低字
节顺序)和编码方式(UTF-8,UTF-16,UTF-32, 其中UTF-8编码是字节顺序无关的)。
如下所示:
Encoding Representation
UTF-8 EF BB BF
UTF-16 Big Endian FE FF
UTF-16 Little Endian FF FE
UTF-32 Big Endian 00 00 FE FF
UTF-32 Little Endian FF FE 00 00
UTF-8 C++ 程序编码示例:
下面是四个C++函数,他们分别实现2字节和4字节UNICODE和UTF-8之间的转换。
#define MASKBITS 0x3F
#define MASKBYTE 0x80
#define MASK2BYTES 0xC0
#define MASK3BYTES 0xE0
#define MASK4BYTES 0xF0
#define MASK5BYTES 0xF8
#define MASK6BYTES 0xFC
typedef unsigned short Unicode2Bytes;
typedef unsigned int Unicode4Bytes;
void UTF8Encode2BytesUnicode(std::vector< Unicode2Bytes > input,
std::vector< byte >& output)
{
for(int i=0; i < input.size(); i++)
{
// 0xxxxxxx
if(input < 0x80)
{
output.push_back((byte)input);
}
// 110xxxxx 10xxxxxx
else if(input < 0x800)
{
output.push_back((byte)(MASK2BYTES | input >> 6));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
// 1110xxxx 10xxxxxx 10xxxxxx
else if(input < 0x10000)
{
output.push_back((byte)(MASK3BYTES | input >> 12));
output.push_back((byte)(MASKBYTE | input >> 6 & MASKBITS));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
}
}
void UTF8Decode2BytesUnicode(std::vector< byte > input,
std::vector< Unicode2Bytes >& output)
{
for(int i=0; i < input.size();)
{
Unicode2Bytes ch;
// 1110xxxx 10xxxxxx 10xxxxxx
if((input & MASK3BYTES) == MASK3BYTES)
{
ch = ((input & 0x0F) << 12) | (
(input[i+1] & MASKBITS) << 6)
| (input[i+2] & MASKBITS);
i += 3;
}
// 110xxxxx 10xxxxxx
else if((input & MASK2BYTES) == MASK2BYTES)
{
ch = ((input & 0x1F) << 6) | (input[i+1] & MASKBITS);
i += 2;
}
// 0xxxxxxx
else if(input < MASKBYTE)
{
ch = input;
i += 1;
}
output.push_back(ch);
}
}
void UTF8Encode4BytesUnicode(std::vector< Unicode4Bytes > input,
std::vector< byte >& output)
{
for(int i=0; i < input.size(); i++)
{
// 0xxxxxxx
if(input < 0x80)
{
output.push_back((byte)input);
}
// 110xxxxx 10xxxxxx
else if(input < 0x800)
{
output.push_back((byte)(MASK2BYTES | input > 6));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
// 1110xxxx 10xxxxxx 10xxxxxx
else if(input < 0x10000)
{
output.push_back((byte)(MASK3BYTES | input >> 12));
output.push_back((byte)(MASKBYTE | input >> 6 & MASKBITS));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
else if(input < 0x200000)
{
output.push_back((byte)(MASK4BYTES | input >> 18));
output.push_back((byte)(MASKBYTE | input >> 12 & MASKBITS));
output.push_back((byte)(MASKBYTE | input >> 6 & MASKBITS));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
// 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
else if(input < 0x4000000)
{
output.push_back((byte)(MASK5BYTES | input >> 24));
output.push_back((byte)(MASKBYTE | input >> 18 & MASKBITS));
output.push_back((byte)(MASKBYTE | input >> 12 & MASKBITS));
output.push_back((byte)(MASKBYTE | input >> 6 & MASKBITS));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
// 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
else if(input < 0x8000000)
{
output.push_back((byte)(MASK6BYTES | input >> 30));
output.push_back((byte)(MASKBYTE | input >> 18 & MASKBITS));
output.push_back((byte)(MASKBYTE | input >> 12 & MASKBITS));
output.push_back((byte)(MASKBYTE | input >> 6 & MASKBITS));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
}
}
void UTF8Decode4BytesUnicode(std::vector< byte > input,
std::vector< Unicode4Bytes >& output)
{
for(int i=0; i < input.size();)
{
Unicode4Bytes ch;
// 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
if((input & MASK6BYTES) == MASK6BYTES)
{
ch = ((input & 0x01) << 30) | ((input[i+1] & MASKBITS) << 24)
| ((input[i+2] & MASKBITS) << 18) | ((input[i+3]
& MASKBITS) << 12)
| ((input[i+4] & MASKBITS) << 6) | (input[i+5] & MASKBITS);
i += 6;
}
// 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
else if((input & MASK5BYTES) == MASK5BYTES)
{
ch = ((input & 0x03) << 24) | ((input[i+1]
& MASKBITS) << 18)
| ((input[i+2] & MASKBITS) << 12) | ((input[i+3]
& MASKBITS) << 6)
| (input[i+4] & MASKBITS);
i += 5;
}
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
else if((input & MASK4BYTES) == MASK4BYTES)
{
ch = ((input & 0x07) << 18) | ((input[i+1]
& MASKBITS) << 12)
| ((input[i+2] & MASKBITS) << 6) | (input[i+3] & MASKBITS);
i += 4;
}
// 1110xxxx 10xxxxxx 10xxxxxx
else if((input & MASK3BYTES) == MASK3BYTES)
{
ch = ((input & 0x0F) << 12) | ((input[i+1] & MASKBITS) << 6)
| (input[i+2] & MASKBITS);
i += 3;
}
// 110xxxxx 10xxxxxx
else if((input & MASK2BYTES) == MASK2BYTES)
{
ch = ((input & 0x1F) << 6) | (input[i+1] & MASKBITS);
i += 2;
}
// 0xxxxxxx
else if(input < MASKBYTE)
{
ch = input;
i += 1;
}
output.push_back(ch);
}
}
限译者水平有限,有不解之处请参考原文。版权属原文作者所有,转载请注明出处及作者。UTF-8 字符集基础
字符集简史
在所有字符集中,最知名可能要数被称为ASCII的7位字符集了。它是美国信息交换标准委员会
(American Standards Committee for Information Interchange)的缩写, 为美国英语通信所设计。它由128个字符
组成,包括大小写字母、数字0-9、标点符号、非打印字符(换行符、制表符等4个)以及控制字符(
退格、响铃等)组成。
但是,由于他是针对英语设计的,当处理带有音调标号(形如汉语的拼音)的欧洲文字时就会出现问
题。因此,创建出了一些包括255个字符的由ASCII扩展的字符集。其中有一种通常被成为IBM字符集,
它把值为128-255之间的字符用于画图和画线,以及一些特殊的欧洲字符。另一种8位字符集是ISO 8859
-1 Latin 1,也简称为ISO Latin-1。它把位于128-255之间的字符用于拉丁字母表中特殊语言字符的编码,
也因此而得名。
欧洲语言不是地球上的唯一语言,因此亚洲和非洲语言并不能被8位字符集所支持。仅汉语(或
pictograms)字母表就有80000以上个字符。但是把汉语、日语和越南语的一些相似的字符结合起来,在
不同的语言里,使不同的字符代表不同的字,这样只用2个字节就可以编码地球上几乎所有地区的文
字。因此,创建了UNICODE编码。它通过增加一个高字节对ISO Latin-1字符集进行扩展,当这些高字节
位为0时,低字节就是ISO Latin-1字符。UNICODE支持欧洲、非洲、中东、亚洲(包括统一标准的东亚像
形汉字和韩国像形文字)。但是,UNICODE并没有提供对诸如Braille, Cherokee, Ethiopic, Khmer, Mongolian,
Hmong, Tai Lu, Tai Mau文字的支持。同时它也不支持如Ahom, Akkadian, Aramaic, Babylonian Cuneiform, Balti,
Brahmi, Etruscan, Hittite, Javanese, Numidian, Old Persian Cuneiform, Syrian之类的古老的文字。
事实证明,对可以用ASCII表示的字符使用UNICODE并不高效,因为UNICODE比ASCII占用大一倍的空间
,而对ASCII来说高字节的0对他毫无用处。为了解决这个问题,就出现了一些中间格式的字符集,他
们被称为通用转换格式,既UTF(Universal Transformation Format)。目前存在的UTF格式有:UTF-7, UTF-
7.5, UTF-8, UTF-16, 以及 UTF-32。本文讨论UTF-8字符集的基础。
UTF_8字符集
UTF-8是UNICODE的一种变长字符编码,由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。
UTF-8用1到6个字节编码UNICODE字符。如果UNICODE字符由2个字节表示,则编码成UTF-8很可能需要3
个字节,而如果UNICODE字符由4个字节表示,则编码成UTF-8可能需要6个字节。用4个或6个字节去编
码一个UNICODE字符可能太多了,但很少会遇到那样的UNICODE字符。
UFT-8转换表表示如下:
UNICODE UTF-8
00000000 - 0000007F 0xxxxxxx
00000080 - 000007FF 110xxxxx 10xxxxxx
00000800 - 0000FFFF 1110xxxx 10xxxxxx 10xxxxxx
00010000 - 001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
00200000 - 03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
04000000 - 7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
实际表示ASCII字符的UNICODE字符,将会编码成1个字节,并且UTF-8表示与ASCII字符表示是一样的。
所有其他的UNCODE字符转化成UTF-8将需要至少2个字节。每个字节由一个换码序列开始。第一个字节
由唯一的换码序列,由n位1加一位0组成。n位1表示字符编码所需的字节数。
示例
UNICODE uCA(11001010) 编码成UTF-8将需要2个字节:
uCA -> C3 8A
1100 1010
110xxxxx 10xxxxxx
1100 1010 -> 110xxxxx 10xxxxxx
-> 110xxxxx 10xxxxx0
-> 110xxxxx 10xxxx10
-> 110xxxxx 10xxx010
-> 110xxxxx 10xx1010
-> 110xxxxx 10x01010
-> 110xxxxx 10001010
-> 110xxxx1 10001010
-> 110xxx11 10001010
-> 11000011 10001010
-> C3 8A
UNICODE uF03F (11110000 00111111) 编码成UTF-8将需要3个字节:
u F03F -> EF 80 BF
1111 0000 0011 1111 -> 1110xxxx 10xxxxxx 10xxxxxx
-> 11101111 10000000 10111111
-> EF 80 BF
译者注:由上分析可以看到,UNCODE到UTF-8的转换就是先确定编码所需要的字节数,然后用
UNICODE编码位从低位到高位依次填入上面表示为x的位上,不足的高位以0补充。以上是个人经验,
如有错误,请不惜指教,谢过先:)
UTF-8编码的优点:
UTF-8编码可以通过屏蔽位和移位操作快速读写。
字符串比较时strcmp()和wcscmp()的返回结果相同,因此使排序变得更加容易。
字节FF和FE在UTF-8编码中永远不会出现,因此他们可以用来表明UTF-16或UTF-32文本(见BOM)
UTF-8 是字节顺序无关的。它的字节顺序在所有系统中都是一样的,因此它实际上并不需要BOM。
UTF-8编码的缺点:
你无法从UNICODE字符数判断出UTF-8文本的字节数,因为UTF-8是一种变长编码
它需要用2个字节编码那些用扩展ASCII字符集只需1个字节的字符
ISO Latin-1 是UNICODE的子集,但不是UTF-8的子集
8位字符的UTF-8编码会被email网关过滤,因为internet信息最初设计为7为ASCII码。因此产生了UTF-7编码
。
UTF-8 在它的表示中使用值100xxxxx的几率超过50%, 而现存的实现如ISO 2022, 4873, 6429, 和8859系
统,会把它错认为是C1 控制码。因此产生了UTF-7.5编码。
修正的UTF-8:
java使用UTF-16表示内部文本,并支持用于字符串串行化的非标准的修正UTF-8编码。标准UTF-8和修正
的UTF-8有两点不同:
修正的UTF-8中,null字符编码成2个字节(11000000 00000000) 而不是标准的1个字节(00000000),这
样作可以保证编码后的字符串中不会嵌入null字符。因此如果在类C语言中处理字符串,文本不会在第
一个null字符时截断(C字符串以null结尾)。
在标准UTF-8编码中,超出基本多语言范围(BMP - Basic Multilingual Plain)的字符被编码为4字节格式,
但是在修正的UTF-8编码中,他们由代理编码对(surrogate pairs)表示,然后这些代理编码对在序列中
分别重新编码。结果标准UTF-8编码中需要4个字节的字符,在修正后的UTF-8编码中将需要6个字节。
位序标志BOM
BOM(Byte Order Mark)是一个字符,它表明UNICODE文本的UTF-16,UTF-32的编码字节顺序(高字节低字
节顺序)和编码方式(UTF-8,UTF-16,UTF-32, 其中UTF-8编码是字节顺序无关的)。
如下所示:
Encoding Representation
UTF-8 EF BB BF
UTF-16 Big Endian FE FF
UTF-16 Little Endian FF FE
UTF-32 Big Endian 00 00 FE FF
UTF-32 Little Endian FF FE 00 00
UTF-8 C++ 程序编码示例:
下面是四个C++函数,他们分别实现2字节和4字节UNICODE和UTF-8之间的转换。
#define MASKBITS 0x3F
#define MASKBYTE 0x80
#define MASK2BYTES 0xC0
#define MASK3BYTES 0xE0
#define MASK4BYTES 0xF0
#define MASK5BYTES 0xF8
#define MASK6BYTES 0xFC
typedef unsigned short Unicode2Bytes;
typedef unsigned int Unicode4Bytes;
void UTF8Encode2BytesUnicode(std::vector< Unicode2Bytes > input,
std::vector< byte >& output)
{
for(int i=0; i < input.size(); i++)
{
// 0xxxxxxx
if(input < 0x80)
{
output.push_back((byte)input);
}
// 110xxxxx 10xxxxxx
else if(input < 0x800)
{
output.push_back((byte)(MASK2BYTES | input >> 6));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
// 1110xxxx 10xxxxxx 10xxxxxx
else if(input < 0x10000)
{
output.push_back((byte)(MASK3BYTES | input >> 12));
output.push_back((byte)(MASKBYTE | input >> 6 & MASKBITS));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
}
}
void UTF8Decode2BytesUnicode(std::vector< byte > input,
std::vector< Unicode2Bytes >& output)
{
for(int i=0; i < input.size();)
{
Unicode2Bytes ch;
// 1110xxxx 10xxxxxx 10xxxxxx
if((input & MASK3BYTES) == MASK3BYTES)
{
ch = ((input & 0x0F) << 12) | (
(input[i+1] & MASKBITS) << 6)
| (input[i+2] & MASKBITS);
i += 3;
}
// 110xxxxx 10xxxxxx
else if((input & MASK2BYTES) == MASK2BYTES)
{
ch = ((input & 0x1F) << 6) | (input[i+1] & MASKBITS);
i += 2;
}
// 0xxxxxxx
else if(input < MASKBYTE)
{
ch = input;
i += 1;
}
output.push_back(ch);
}
}
void UTF8Encode4BytesUnicode(std::vector< Unicode4Bytes > input,
std::vector< byte >& output)
{
for(int i=0; i < input.size(); i++)
{
// 0xxxxxxx
if(input < 0x80)
{
output.push_back((byte)input);
}
// 110xxxxx 10xxxxxx
else if(input < 0x800)
{
output.push_back((byte)(MASK2BYTES | input > 6));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
// 1110xxxx 10xxxxxx 10xxxxxx
else if(input < 0x10000)
{
output.push_back((byte)(MASK3BYTES | input >> 12));
output.push_back((byte)(MASKBYTE | input >> 6 & MASKBITS));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
else if(input < 0x200000)
{
output.push_back((byte)(MASK4BYTES | input >> 18));
output.push_back((byte)(MASKBYTE | input >> 12 & MASKBITS));
output.push_back((byte)(MASKBYTE | input >> 6 & MASKBITS));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
// 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
else if(input < 0x4000000)
{
output.push_back((byte)(MASK5BYTES | input >> 24));
output.push_back((byte)(MASKBYTE | input >> 18 & MASKBITS));
output.push_back((byte)(MASKBYTE | input >> 12 & MASKBITS));
output.push_back((byte)(MASKBYTE | input >> 6 & MASKBITS));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
// 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
else if(input < 0x8000000)
{
output.push_back((byte)(MASK6BYTES | input >> 30));
output.push_back((byte)(MASKBYTE | input >> 18 & MASKBITS));
output.push_back((byte)(MASKBYTE | input >> 12 & MASKBITS));
output.push_back((byte)(MASKBYTE | input >> 6 & MASKBITS));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
}
}
void UTF8Decode4BytesUnicode(std::vector< byte > input,
std::vector< Unicode4Bytes >& output)
{
for(int i=0; i < input.size();)
{
Unicode4Bytes ch;
// 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
if((input & MASK6BYTES) == MASK6BYTES)
{
ch = ((input & 0x01) << 30) | ((input[i+1] & MASKBITS) << 24)
| ((input[i+2] & MASKBITS) << 18) | ((input[i+3]
& MASKBITS) << 12)
| ((input[i+4] & MASKBITS) << 6) | (input[i+5] & MASKBITS);
i += 6;
}
// 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
else if((input & MASK5BYTES) == MASK5BYTES)
{
ch = ((input & 0x03) << 24) | ((input[i+1]
& MASKBITS) << 18)
| ((input[i+2] & MASKBITS) << 12) | ((input[i+3]
& MASKBITS) << 6)
| (input[i+4] & MASKBITS);
i += 5;
}
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
else if((input & MASK4BYTES) == MASK4BYTES)
{
ch = ((input & 0x07) << 18) | ((input[i+1]
& MASKBITS) << 12)
| ((input[i+2] & MASKBITS) << 6) | (input[i+3] & MASKBITS);
i += 4;
}
// 1110xxxx 10xxxxxx 10xxxxxx
else if((input & MASK3BYTES) == MASK3BYTES)
{
ch = ((input & 0x0F) << 12) | ((input[i+1] & MASKBITS) << 6)
| (input[i+2] & MASKBITS);
i += 3;
}
// 110xxxxx 10xxxxxx
else if((input & MASK2BYTES) == MASK2BYTES)
{
ch = ((input & 0x1F) << 6) | (input[i+1] & MASKBITS);
i += 2;
}
// 0xxxxxxx
else if(input < MASKBYTE)
{
ch = input;
i += 1;
}
output.push_back(ch);
}
}
限译者水平有限,有不解之处请参考原文。版权属原文作者所有,转载请注明出处及作者。
字符集简史
在所有字符集中,最知名可能要数被称为ASCII的7位字符集了。它是美国信息交换标准委员会
(American Standards Committee for Information Interchange)的缩写, 为美国英语通信所设计。它由128个字符
组成,包括大小写字母、数字0-9、标点符号、非打印字符(换行符、制表符等4个)以及控制字符(
退格、响铃等)组成。
但是,由于他是针对英语设计的,当处理带有音调标号(形如汉语的拼音)的欧洲文字时就会出现问
题。因此,创建出了一些包括255个字符的由ASCII扩展的字符集。其中有一种通常被成为IBM字符集,
它把值为128-255之间的字符用于画图和画线,以及一些特殊的欧洲字符。另一种8位字符集是ISO 8859
-1 Latin 1,也简称为ISO Latin-1。它把位于128-255之间的字符用于拉丁字母表中特殊语言字符的编码,
也因此而得名。
欧洲语言不是地球上的唯一语言,因此亚洲和非洲语言并不能被8位字符集所支持。仅汉语(或
pictograms)字母表就有80000以上个字符。但是把汉语、日语和越南语的一些相似的字符结合起来,在
不同的语言里,使不同的字符代表不同的字,这样只用2个字节就可以编码地球上几乎所有地区的文
字。因此,创建了UNICODE编码。它通过增加一个高字节对ISO Latin-1字符集进行扩展,当这些高字节
位为0时,低字节就是ISO Latin-1字符。UNICODE支持欧洲、非洲、中东、亚洲(包括统一标准的东亚像
形汉字和韩国像形文字)。但是,UNICODE并没有提供对诸如Braille, Cherokee, Ethiopic, Khmer, Mongolian,
Hmong, Tai Lu, Tai Mau文字的支持。同时它也不支持如Ahom, Akkadian, Aramaic, Babylonian Cuneiform, Balti,
Brahmi, Etruscan, Hittite, Javanese, Numidian, Old Persian Cuneiform, Syrian之类的古老的文字。
事实证明,对可以用ASCII表示的字符使用UNICODE并不高效,因为UNICODE比ASCII占用大一倍的空间
,而对ASCII来说高字节的0对他毫无用处。为了解决这个问题,就出现了一些中间格式的字符集,他
们被称为通用转换格式,既UTF(Universal Transformation Format)。目前存在的UTF格式有:UTF-7, UTF-
7.5, UTF-8, UTF-16, 以及 UTF-32。本文讨论UTF-8字符集的基础。
UTF_8字符集
UTF-8是UNICODE的一种变长字符编码,由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。
UTF-8用1到6个字节编码UNICODE字符。如果UNICODE字符由2个字节表示,则编码成UTF-8很可能需要3
个字节,而如果UNICODE字符由4个字节表示,则编码成UTF-8可能需要6个字节。用4个或6个字节去编
码一个UNICODE字符可能太多了,但很少会遇到那样的UNICODE字符。
UFT-8转换表表示如下:
UNICODE UTF-8
00000000 - 0000007F 0xxxxxxx
00000080 - 000007FF 110xxxxx 10xxxxxx
00000800 - 0000FFFF 1110xxxx 10xxxxxx 10xxxxxx
00010000 - 001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
00200000 - 03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
04000000 - 7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
实际表示ASCII字符的UNICODE字符,将会编码成1个字节,并且UTF-8表示与ASCII字符表示是一样的。
所有其他的UNCODE字符转化成UTF-8将需要至少2个字节。每个字节由一个换码序列开始。第一个字节
由唯一的换码序列,由n位1加一位0组成。n位1表示字符编码所需的字节数。
示例
UNICODE uCA(11001010) 编码成UTF-8将需要2个字节:
uCA -> C3 8A
1100 1010
110xxxxx 10xxxxxx
1100 1010 -> 110xxxxx 10xxxxxx
-> 110xxxxx 10xxxxx0
-> 110xxxxx 10xxxx10
-> 110xxxxx 10xxx010
-> 110xxxxx 10xx1010
-> 110xxxxx 10x01010
-> 110xxxxx 10001010
-> 110xxxx1 10001010
-> 110xxx11 10001010
-> 11000011 10001010
-> C3 8A
UNICODE uF03F (11110000 00111111) 编码成UTF-8将需要3个字节:
u F03F -> EF 80 BF
1111 0000 0011 1111 -> 1110xxxx 10xxxxxx 10xxxxxx
-> 11101111 10000000 10111111
-> EF 80 BF
译者注:由上分析可以看到,UNCODE到UTF-8的转换就是先确定编码所需要的字节数,然后用
UNICODE编码位从低位到高位依次填入上面表示为x的位上,不足的高位以0补充。以上是个人经验,
如有错误,请不惜指教,谢过先:)
UTF-8编码的优点:
UTF-8编码可以通过屏蔽位和移位操作快速读写。
字符串比较时strcmp()和wcscmp()的返回结果相同,因此使排序变得更加容易。
字节FF和FE在UTF-8编码中永远不会出现,因此他们可以用来表明UTF-16或UTF-32文本(见BOM)
UTF-8 是字节顺序无关的。它的字节顺序在所有系统中都是一样的,因此它实际上并不需要BOM。
UTF-8编码的缺点:
你无法从UNICODE字符数判断出UTF-8文本的字节数,因为UTF-8是一种变长编码
它需要用2个字节编码那些用扩展ASCII字符集只需1个字节的字符
ISO Latin-1 是UNICODE的子集,但不是UTF-8的子集
8位字符的UTF-8编码会被email网关过滤,因为internet信息最初设计为7为ASCII码。因此产生了UTF-7编码
。
UTF-8 在它的表示中使用值100xxxxx的几率超过50%, 而现存的实现如ISO 2022, 4873, 6429, 和8859系
统,会把它错认为是C1 控制码。因此产生了UTF-7.5编码。
修正的UTF-8:
java使用UTF-16表示内部文本,并支持用于字符串串行化的非标准的修正UTF-8编码。标准UTF-8和修正
的UTF-8有两点不同:
修正的UTF-8中,null字符编码成2个字节(11000000 00000000) 而不是标准的1个字节(00000000),这
样作可以保证编码后的字符串中不会嵌入null字符。因此如果在类C语言中处理字符串,文本不会在第
一个null字符时截断(C字符串以null结尾)。
在标准UTF-8编码中,超出基本多语言范围(BMP - Basic Multilingual Plain)的字符被编码为4字节格式,
但是在修正的UTF-8编码中,他们由代理编码对(surrogate pairs)表示,然后这些代理编码对在序列中
分别重新编码。结果标准UTF-8编码中需要4个字节的字符,在修正后的UTF-8编码中将需要6个字节。
位序标志BOM
BOM(Byte Order Mark)是一个字符,它表明UNICODE文本的UTF-16,UTF-32的编码字节顺序(高字节低字
节顺序)和编码方式(UTF-8,UTF-16,UTF-32, 其中UTF-8编码是字节顺序无关的)。
如下所示:
Encoding Representation
UTF-8 EF BB BF
UTF-16 Big Endian FE FF
UTF-16 Little Endian FF FE
UTF-32 Big Endian 00 00 FE FF
UTF-32 Little Endian FF FE 00 00
UTF-8 C++ 程序编码示例:
下面是四个C++函数,他们分别实现2字节和4字节UNICODE和UTF-8之间的转换。
#define MASKBITS 0x3F
#define MASKBYTE 0x80
#define MASK2BYTES 0xC0
#define MASK3BYTES 0xE0
#define MASK4BYTES 0xF0
#define MASK5BYTES 0xF8
#define MASK6BYTES 0xFC
typedef unsigned short Unicode2Bytes;
typedef unsigned int Unicode4Bytes;
void UTF8Encode2BytesUnicode(std::vector< Unicode2Bytes > input,
std::vector< byte >& output)
{
for(int i=0; i < input.size(); i++)
{
// 0xxxxxxx
if(input < 0x80)
{
output.push_back((byte)input);
}
// 110xxxxx 10xxxxxx
else if(input < 0x800)
{
output.push_back((byte)(MASK2BYTES | input >> 6));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
// 1110xxxx 10xxxxxx 10xxxxxx
else if(input < 0x10000)
{
output.push_back((byte)(MASK3BYTES | input >> 12));
output.push_back((byte)(MASKBYTE | input >> 6 & MASKBITS));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
}
}
void UTF8Decode2BytesUnicode(std::vector< byte > input,
std::vector< Unicode2Bytes >& output)
{
for(int i=0; i < input.size();)
{
Unicode2Bytes ch;
// 1110xxxx 10xxxxxx 10xxxxxx
if((input & MASK3BYTES) == MASK3BYTES)
{
ch = ((input & 0x0F) << 12) | (
(input[i+1] & MASKBITS) << 6)
| (input[i+2] & MASKBITS);
i += 3;
}
// 110xxxxx 10xxxxxx
else if((input & MASK2BYTES) == MASK2BYTES)
{
ch = ((input & 0x1F) << 6) | (input[i+1] & MASKBITS);
i += 2;
}
// 0xxxxxxx
else if(input < MASKBYTE)
{
ch = input;
i += 1;
}
output.push_back(ch);
}
}
void UTF8Encode4BytesUnicode(std::vector< Unicode4Bytes > input,
std::vector< byte >& output)
{
for(int i=0; i < input.size(); i++)
{
// 0xxxxxxx
if(input < 0x80)
{
output.push_back((byte)input);
}
// 110xxxxx 10xxxxxx
else if(input < 0x800)
{
output.push_back((byte)(MASK2BYTES | input > 6));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
// 1110xxxx 10xxxxxx 10xxxxxx
else if(input < 0x10000)
{
output.push_back((byte)(MASK3BYTES | input >> 12));
output.push_back((byte)(MASKBYTE | input >> 6 & MASKBITS));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
else if(input < 0x200000)
{
output.push_back((byte)(MASK4BYTES | input >> 18));
output.push_back((byte)(MASKBYTE | input >> 12 & MASKBITS));
output.push_back((byte)(MASKBYTE | input >> 6 & MASKBITS));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
// 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
else if(input < 0x4000000)
{
output.push_back((byte)(MASK5BYTES | input >> 24));
output.push_back((byte)(MASKBYTE | input >> 18 & MASKBITS));
output.push_back((byte)(MASKBYTE | input >> 12 & MASKBITS));
output.push_back((byte)(MASKBYTE | input >> 6 & MASKBITS));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
// 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
else if(input < 0x8000000)
{
output.push_back((byte)(MASK6BYTES | input >> 30));
output.push_back((byte)(MASKBYTE | input >> 18 & MASKBITS));
output.push_back((byte)(MASKBYTE | input >> 12 & MASKBITS));
output.push_back((byte)(MASKBYTE | input >> 6 & MASKBITS));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
}
}
void UTF8Decode4BytesUnicode(std::vector< byte > input,
std::vector< Unicode4Bytes >& output)
{
for(int i=0; i < input.size();)
{
Unicode4Bytes ch;
// 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
if((input & MASK6BYTES) == MASK6BYTES)
{
ch = ((input & 0x01) << 30) | ((input[i+1] & MASKBITS) << 24)
| ((input[i+2] & MASKBITS) << 18) | ((input[i+3]
& MASKBITS) << 12)
| ((input[i+4] & MASKBITS) << 6) | (input[i+5] & MASKBITS);
i += 6;
}
// 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
else if((input & MASK5BYTES) == MASK5BYTES)
{
ch = ((input & 0x03) << 24) | ((input[i+1]
& MASKBITS) << 18)
| ((input[i+2] & MASKBITS) << 12) | ((input[i+3]
& MASKBITS) << 6)
| (input[i+4] & MASKBITS);
i += 5;
}
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
else if((input & MASK4BYTES) == MASK4BYTES)
{
ch = ((input & 0x07) << 18) | ((input[i+1]
& MASKBITS) << 12)
| ((input[i+2] & MASKBITS) << 6) | (input[i+3] & MASKBITS);
i += 4;
}
// 1110xxxx 10xxxxxx 10xxxxxx
else if((input & MASK3BYTES) == MASK3BYTES)
{
ch = ((input & 0x0F) << 12) | ((input[i+1] & MASKBITS) << 6)
| (input[i+2] & MASKBITS);
i += 3;
}
// 110xxxxx 10xxxxxx
else if((input & MASK2BYTES) == MASK2BYTES)
{
ch = ((input & 0x1F) << 6) | (input[i+1] & MASKBITS);
i += 2;
}
// 0xxxxxxx
else if(input < MASKBYTE)
{
ch = input;
i += 1;
}
output.push_back(ch);
}
}
限译者水平有限,有不解之处请参考原文。版权属原文作者所有,转载请注明出处及作者。UTF-8 字符集基础
字符集简史
在所有字符集中,最知名可能要数被称为ASCII的7位字符集了。它是美国信息交换标准委员会
(American Standards Committee for Information Interchange)的缩写, 为美国英语通信所设计。它由128个字符
组成,包括大小写字母、数字0-9、标点符号、非打印字符(换行符、制表符等4个)以及控制字符(
退格、响铃等)组成。
但是,由于他是针对英语设计的,当处理带有音调标号(形如汉语的拼音)的欧洲文字时就会出现问
题。因此,创建出了一些包括255个字符的由ASCII扩展的字符集。其中有一种通常被成为IBM字符集,
它把值为128-255之间的字符用于画图和画线,以及一些特殊的欧洲字符。另一种8位字符集是ISO 8859
-1 Latin 1,也简称为ISO Latin-1。它把位于128-255之间的字符用于拉丁字母表中特殊语言字符的编码,
也因此而得名。
欧洲语言不是地球上的唯一语言,因此亚洲和非洲语言并不能被8位字符集所支持。仅汉语(或
pictograms)字母表就有80000以上个字符。但是把汉语、日语和越南语的一些相似的字符结合起来,在
不同的语言里,使不同的字符代表不同的字,这样只用2个字节就可以编码地球上几乎所有地区的文
字。因此,创建了UNICODE编码。它通过增加一个高字节对ISO Latin-1字符集进行扩展,当这些高字节
位为0时,低字节就是ISO Latin-1字符。UNICODE支持欧洲、非洲、中东、亚洲(包括统一标准的东亚像
形汉字和韩国像形文字)。但是,UNICODE并没有提供对诸如Braille, Cherokee, Ethiopic, Khmer, Mongolian,
Hmong, Tai Lu, Tai Mau文字的支持。同时它也不支持如Ahom, Akkadian, Aramaic, Babylonian Cuneiform, Balti,
Brahmi, Etruscan, Hittite, Javanese, Numidian, Old Persian Cuneiform, Syrian之类的古老的文字。
事实证明,对可以用ASCII表示的字符使用UNICODE并不高效,因为UNICODE比ASCII占用大一倍的空间
,而对ASCII来说高字节的0对他毫无用处。为了解决这个问题,就出现了一些中间格式的字符集,他
们被称为通用转换格式,既UTF(Universal Transformation Format)。目前存在的UTF格式有:UTF-7, UTF-
7.5, UTF-8, UTF-16, 以及 UTF-32。本文讨论UTF-8字符集的基础。
UTF_8字符集
UTF-8是UNICODE的一种变长字符编码,由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。
UTF-8用1到6个字节编码UNICODE字符。如果UNICODE字符由2个字节表示,则编码成UTF-8很可能需要3
个字节,而如果UNICODE字符由4个字节表示,则编码成UTF-8可能需要6个字节。用4个或6个字节去编
码一个UNICODE字符可能太多了,但很少会遇到那样的UNICODE字符。
UFT-8转换表表示如下:
UNICODE UTF-8
00000000 - 0000007F 0xxxxxxx
00000080 - 000007FF 110xxxxx 10xxxxxx
00000800 - 0000FFFF 1110xxxx 10xxxxxx 10xxxxxx
00010000 - 001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
00200000 - 03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
04000000 - 7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
实际表示ASCII字符的UNICODE字符,将会编码成1个字节,并且UTF-8表示与ASCII字符表示是一样的。
所有其他的UNCODE字符转化成UTF-8将需要至少2个字节。每个字节由一个换码序列开始。第一个字节
由唯一的换码序列,由n位1加一位0组成。n位1表示字符编码所需的字节数。
示例
UNICODE uCA(11001010) 编码成UTF-8将需要2个字节:
uCA -> C3 8A
1100 1010
110xxxxx 10xxxxxx
1100 1010 -> 110xxxxx 10xxxxxx
-> 110xxxxx 10xxxxx0
-> 110xxxxx 10xxxx10
-> 110xxxxx 10xxx010
-> 110xxxxx 10xx1010
-> 110xxxxx 10x01010
-> 110xxxxx 10001010
-> 110xxxx1 10001010
-> 110xxx11 10001010
-> 11000011 10001010
-> C3 8A
UNICODE uF03F (11110000 00111111) 编码成UTF-8将需要3个字节:
u F03F -> EF 80 BF
1111 0000 0011 1111 -> 1110xxxx 10xxxxxx 10xxxxxx
-> 11101111 10000000 10111111
-> EF 80 BF
译者注:由上分析可以看到,UNCODE到UTF-8的转换就是先确定编码所需要的字节数,然后用
UNICODE编码位从低位到高位依次填入上面表示为x的位上,不足的高位以0补充。以上是个人经验,
如有错误,请不惜指教,谢过先:)
UTF-8编码的优点:
UTF-8编码可以通过屏蔽位和移位操作快速读写。
字符串比较时strcmp()和wcscmp()的返回结果相同,因此使排序变得更加容易。
字节FF和FE在UTF-8编码中永远不会出现,因此他们可以用来表明UTF-16或UTF-32文本(见BOM)
UTF-8 是字节顺序无关的。它的字节顺序在所有系统中都是一样的,因此它实际上并不需要BOM。
UTF-8编码的缺点:
你无法从UNICODE字符数判断出UTF-8文本的字节数,因为UTF-8是一种变长编码
它需要用2个字节编码那些用扩展ASCII字符集只需1个字节的字符
ISO Latin-1 是UNICODE的子集,但不是UTF-8的子集
8位字符的UTF-8编码会被email网关过滤,因为internet信息最初设计为7为ASCII码。因此产生了UTF-7编码
。
UTF-8 在它的表示中使用值100xxxxx的几率超过50%, 而现存的实现如ISO 2022, 4873, 6429, 和8859系
统,会把它错认为是C1 控制码。因此产生了UTF-7.5编码。
修正的UTF-8:
java使用UTF-16表示内部文本,并支持用于字符串串行化的非标准的修正UTF-8编码。标准UTF-8和修正
的UTF-8有两点不同:
修正的UTF-8中,null字符编码成2个字节(11000000 00000000) 而不是标准的1个字节(00000000),这
样作可以保证编码后的字符串中不会嵌入null字符。因此如果在类C语言中处理字符串,文本不会在第
一个null字符时截断(C字符串以null结尾)。
在标准UTF-8编码中,超出基本多语言范围(BMP - Basic Multilingual Plain)的字符被编码为4字节格式,
但是在修正的UTF-8编码中,他们由代理编码对(surrogate pairs)表示,然后这些代理编码对在序列中
分别重新编码。结果标准UTF-8编码中需要4个字节的字符,在修正后的UTF-8编码中将需要6个字节。
位序标志BOM
BOM(Byte Order Mark)是一个字符,它表明UNICODE文本的UTF-16,UTF-32的编码字节顺序(高字节低字
节顺序)和编码方式(UTF-8,UTF-16,UTF-32, 其中UTF-8编码是字节顺序无关的)。
如下所示:
Encoding Representation
UTF-8 EF BB BF
UTF-16 Big Endian FE FF
UTF-16 Little Endian FF FE
UTF-32 Big Endian 00 00 FE FF
UTF-32 Little Endian FF FE 00 00
UTF-8 C++ 程序编码示例:
下面是四个C++函数,他们分别实现2字节和4字节UNICODE和UTF-8之间的转换。
#define MASKBITS 0x3F
#define MASKBYTE 0x80
#define MASK2BYTES 0xC0
#define MASK3BYTES 0xE0
#define MASK4BYTES 0xF0
#define MASK5BYTES 0xF8
#define MASK6BYTES 0xFC
typedef unsigned short Unicode2Bytes;
typedef unsigned int Unicode4Bytes;
void UTF8Encode2BytesUnicode(std::vector< Unicode2Bytes > input,
std::vector< byte >& output)
{
for(int i=0; i < input.size(); i++)
{
// 0xxxxxxx
if(input < 0x80)
{
output.push_back((byte)input);
}
// 110xxxxx 10xxxxxx
else if(input < 0x800)
{
output.push_back((byte)(MASK2BYTES | input >> 6));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
// 1110xxxx 10xxxxxx 10xxxxxx
else if(input < 0x10000)
{
output.push_back((byte)(MASK3BYTES | input >> 12));
output.push_back((byte)(MASKBYTE | input >> 6 & MASKBITS));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
}
}
void UTF8Decode2BytesUnicode(std::vector< byte > input,
std::vector< Unicode2Bytes >& output)
{
for(int i=0; i < input.size();)
{
Unicode2Bytes ch;
// 1110xxxx 10xxxxxx 10xxxxxx
if((input & MASK3BYTES) == MASK3BYTES)
{
ch = ((input & 0x0F) << 12) | (
(input[i+1] & MASKBITS) << 6)
| (input[i+2] & MASKBITS);
i += 3;
}
// 110xxxxx 10xxxxxx
else if((input & MASK2BYTES) == MASK2BYTES)
{
ch = ((input & 0x1F) << 6) | (input[i+1] & MASKBITS);
i += 2;
}
// 0xxxxxxx
else if(input < MASKBYTE)
{
ch = input;
i += 1;
}
output.push_back(ch);
}
}
void UTF8Encode4BytesUnicode(std::vector< Unicode4Bytes > input,
std::vector< byte >& output)
{
for(int i=0; i < input.size(); i++)
{
// 0xxxxxxx
if(input < 0x80)
{
output.push_back((byte)input);
}
// 110xxxxx 10xxxxxx
else if(input < 0x800)
{
output.push_back((byte)(MASK2BYTES | input > 6));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
// 1110xxxx 10xxxxxx 10xxxxxx
else if(input < 0x10000)
{
output.push_back((byte)(MASK3BYTES | input >> 12));
output.push_back((byte)(MASKBYTE | input >> 6 & MASKBITS));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
else if(input < 0x200000)
{
output.push_back((byte)(MASK4BYTES | input >> 18));
output.push_back((byte)(MASKBYTE | input >> 12 & MASKBITS));
output.push_back((byte)(MASKBYTE | input >> 6 & MASKBITS));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
// 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
else if(input < 0x4000000)
{
output.push_back((byte)(MASK5BYTES | input >> 24));
output.push_back((byte)(MASKBYTE | input >> 18 & MASKBITS));
output.push_back((byte)(MASKBYTE | input >> 12 & MASKBITS));
output.push_back((byte)(MASKBYTE | input >> 6 & MASKBITS));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
// 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
else if(input < 0x8000000)
{
output.push_back((byte)(MASK6BYTES | input >> 30));
output.push_back((byte)(MASKBYTE | input >> 18 & MASKBITS));
output.push_back((byte)(MASKBYTE | input >> 12 & MASKBITS));
output.push_back((byte)(MASKBYTE | input >> 6 & MASKBITS));
output.push_back((byte)(MASKBYTE | input & MASKBITS));
}
}
}
void UTF8Decode4BytesUnicode(std::vector< byte > input,
std::vector< Unicode4Bytes >& output)
{
for(int i=0; i < input.size();)
{
Unicode4Bytes ch;
// 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
if((input & MASK6BYTES) == MASK6BYTES)
{
ch = ((input & 0x01) << 30) | ((input[i+1] & MASKBITS) << 24)
| ((input[i+2] & MASKBITS) << 18) | ((input[i+3]
& MASKBITS) << 12)
| ((input[i+4] & MASKBITS) << 6) | (input[i+5] & MASKBITS);
i += 6;
}
// 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
else if((input & MASK5BYTES) == MASK5BYTES)
{
ch = ((input & 0x03) << 24) | ((input[i+1]
& MASKBITS) << 18)
| ((input[i+2] & MASKBITS) << 12) | ((input[i+3]
& MASKBITS) << 6)
| (input[i+4] & MASKBITS);
i += 5;
}
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
else if((input & MASK4BYTES) == MASK4BYTES)
{
ch = ((input & 0x07) << 18) | ((input[i+1]
& MASKBITS) << 12)
| ((input[i+2] & MASKBITS) << 6) | (input[i+3] & MASKBITS);
i += 4;
}
// 1110xxxx 10xxxxxx 10xxxxxx
else if((input & MASK3BYTES) == MASK3BYTES)
{
ch = ((input & 0x0F) << 12) | ((input[i+1] & MASKBITS) << 6)
| (input[i+2] & MASKBITS);
i += 3;
}
// 110xxxxx 10xxxxxx
else if((input & MASK2BYTES) == MASK2BYTES)
{
ch = ((input & 0x1F) << 6) | (input[i+1] & MASKBITS);
i += 2;
}
// 0xxxxxxx
else if(input < MASKBYTE)
{
ch = input;
i += 1;
}
output.push_back(ch);
}
}
限译者水平有限,有不解之处请参考原文。版权属原文作者所有,转载请注明出处及作者。
麻省“偷”走加州理工镇校炮
Posted by
Tony Su
at
7:20 PM
www.thebeijingnews.com ? 2006-4-10 1:22:39? 来源:
美名校互愚成传统
4月6日,麻省理工的师生正在“兴趣盎然”地参观“偷”来的大炮。
大炮立碑,详述“偷”的故事。
大炮近景。
近日,麻省理工学生伪造证件,装成搬运工,从加州理工偷走该校镇校之宝???一尊有130年历史的加农炮。这尊“偷”来的加农炮被展放在麻省理工校园的一片空地上,每天都能吸引不少同学的眼球。4月6日,大炮前方突然出现一块石碑,详细讲述了大炮被盗的故事。
伪造文件骗保安立足麻省面向加州
4月6日,大炮前方不远处出现了一个石碑,石碑的金属板上“如实”记载了事情发生的经过:3月28日,麻省理工的学生编造了一家不存在的“豪和塞尔搬运公司”,使用伪造文件骗过加州理工校园保安。随后,一家搬运公司将这尊重达2吨的加农炮从西海岸运到了东海岸。麻省理工的同学还在炮筒上“套”金黄色的超大号的该校校戒。“为纪念大炮的原有者,大炮指向萨迪那???加州理工所在的城市。”
两校互愚有历史大炮事件一笑而过
这两所美国著名高校有着互“愚”的历史。去年,麻省理工就曾被“涮”过一把。加州理工的学生在新学期开学时,来到麻省理工所在的剑桥。他们向麻省理工的新生免费发放T恤衫。这种看上去很像麻省理工正规校服的T恤背面印着一行字:“并非所有人都能加入加州理工。”(言外之意无非就是,来麻省理工是因为没能力考入加州理工)
尽管偷走镇校之炮有点过分,但出于对两校互“愚”历史的尊敬,这个“小玩笑”被加州理工的师生一笑带过,他们甚至承认麻省理工的对手干得不错。加州理工学生会主席金里奇称,这次事件预示着“新一轮较量将开始”。不过,这宗突然出现的大炮给麻省理工的师生带来不小的惊喜。“我还以为我回到了加州理工。”麻省理工的玛莎笑着说。玛莎去年夏天曾在加州理工小住。
游戏本有规则麻省此次未遵守
对于恶作剧的规则,两校都有明确规定,共同的一点就是,恶作剧者应当在作案后留下纸条,公开身份。而这次麻省理工却没有“按规律出牌”。恶作剧的代表豪解释说,他们的确想留下纸条,但“我们当时有些害怕,不敢回到现场”。
加州理工的这宗“镇校之炮”此前就被“偷”过。12年前,11名哈维玛德大学的学生将它移到了加州的克莱蒙,后来又将大炮归还给加州理工。现在的情况是,麻省理工暂时没有归还计划,而加州理工的发言人则明确表示“我们要大炮归还”。
(姜婧秋)
美名校互愚成传统
4月6日,麻省理工的师生正在“兴趣盎然”地参观“偷”来的大炮。
大炮立碑,详述“偷”的故事。
大炮近景。
近日,麻省理工学生伪造证件,装成搬运工,从加州理工偷走该校镇校之宝???一尊有130年历史的加农炮。这尊“偷”来的加农炮被展放在麻省理工校园的一片空地上,每天都能吸引不少同学的眼球。4月6日,大炮前方突然出现一块石碑,详细讲述了大炮被盗的故事。
伪造文件骗保安立足麻省面向加州
4月6日,大炮前方不远处出现了一个石碑,石碑的金属板上“如实”记载了事情发生的经过:3月28日,麻省理工的学生编造了一家不存在的“豪和塞尔搬运公司”,使用伪造文件骗过加州理工校园保安。随后,一家搬运公司将这尊重达2吨的加农炮从西海岸运到了东海岸。麻省理工的同学还在炮筒上“套”金黄色的超大号的该校校戒。“为纪念大炮的原有者,大炮指向萨迪那???加州理工所在的城市。”
两校互愚有历史大炮事件一笑而过
这两所美国著名高校有着互“愚”的历史。去年,麻省理工就曾被“涮”过一把。加州理工的学生在新学期开学时,来到麻省理工所在的剑桥。他们向麻省理工的新生免费发放T恤衫。这种看上去很像麻省理工正规校服的T恤背面印着一行字:“并非所有人都能加入加州理工。”(言外之意无非就是,来麻省理工是因为没能力考入加州理工)
尽管偷走镇校之炮有点过分,但出于对两校互“愚”历史的尊敬,这个“小玩笑”被加州理工的师生一笑带过,他们甚至承认麻省理工的对手干得不错。加州理工学生会主席金里奇称,这次事件预示着“新一轮较量将开始”。不过,这宗突然出现的大炮给麻省理工的师生带来不小的惊喜。“我还以为我回到了加州理工。”麻省理工的玛莎笑着说。玛莎去年夏天曾在加州理工小住。
游戏本有规则麻省此次未遵守
对于恶作剧的规则,两校都有明确规定,共同的一点就是,恶作剧者应当在作案后留下纸条,公开身份。而这次麻省理工却没有“按规律出牌”。恶作剧的代表豪解释说,他们的确想留下纸条,但“我们当时有些害怕,不敢回到现场”。
加州理工的这宗“镇校之炮”此前就被“偷”过。12年前,11名哈维玛德大学的学生将它移到了加州的克莱蒙,后来又将大炮归还给加州理工。现在的情况是,麻省理工暂时没有归还计划,而加州理工的发言人则明确表示“我们要大炮归还”。
(姜婧秋)
鼠标cursor编程操作
Posted by
Tony Su
at
7:14 PM
现在没用,不过可能以后要用到:)
一、 标准鼠标替换
Windows提供了一系列标准鼠标,其标示前缀均为IDC_,用SetSystemCursor()函数可以替换系统的标准鼠标。SetSystemCusor()有两个参数,第一个为一个通过LoadCursor()(LoadCursor()函数以被LoadImage()函数取代)、CreateCursor()或CopyCursor()获得的Cursor指针。例如:
HCURSOR hnewCur;hnewCur=LoadCursor(hInst,MAKEINTRESOURCE(NEWCURSOR);NEWCURSOR为hInst中的一个Cursor,SetSystemCursor(hnewCur,OCR_NORMAL);使用用户定义鼠标替换系统默认鼠标,当用户再次使用LoadCursor(NULL,IDC_ARROW);加载标准鼠标时获得的将是用户加载的而非系统预定义的鼠标
二、 更换Cursor的方法
1、 新建Cursor
此方法最为烦琐,但用户拥有完全的控制权,比如可以自主设立HotSpot的位置,而不是默认的左上角,具体方法是先填写一个ICONINFO结构:
typedef struct ICONINFO { BOOL fIcon; 是否为图标,将其赋值为FALSE,标示该结构用来建立鼠标DWORD xHotspot; HotSpot的X坐标DWORD yHotspot; HotSpot的Y坐标HBITMAP hbmMask; 鼠标外观的掩模图,用来过滤鼠标的背景HBITMAP hbmColor; 鼠标外观图片} ICONINFO;
填写好后调用CreateIconIndirect()得到一个HICON句柄,如果你建立的是鼠标,将其转换成HCURSOR即可,例如:
ICONINFO ii;HCURSOR hnewCur;ii.fIcon=FALSE;ii.yHotspot=0;ii.yHotspot=0;ii.hbmMask=LoadBitmap(hInst,MAKEINTRESOURCE(IDBCURSORMASK));ii.hbmColor=LoadBitmap(hInst,MAKEINTRESOURCE(IDB_CURSOR));hnewCur=(HCURSOR)CreateIconIndirect(&ii);
2、 加载Cursor
加载是最常用的方法,被加载的鼠标可以是VC集成开发环境中设计好的Cursor,也可以是.ANI或.Cur文件。
1) 从文件中加载:
LoadCursorFromFile();例如:LoadCursorFromFile("C:\\AniCur.ANI")加载一个动画鼠标。
2) 从集成开发环境中加载:
LoadCursor(hInst,MAKEINTRESOURCE(NEWCURSOR));NEWCURSOR可以在资源编辑器中设计。还要说明的是LoadImage()是较LoadCursor()、LoadBitmap()和LoadCursorFromFile()更新的函数,它集多个函数的功能于一身,用起来更加方便,主要的区别在于其多了一个标志来说明加载的是位图、图标函数鼠标。
3、 使用Cursor
1) SetCursor()
捕获窗口的WM_MOUSEMOVE或者WM_SETCURSOR消息,在其处理函数中添加对SetCursor()的调用,例如:SetCursor(hnewCur);其中hnewCur为一个通过上述的任意一种方法获得的HCURSOR
2) SetClassLong()
捕获WM_MOUSEMOVE消息只对有窗口函数的窗口有效,而对像Button控件则无法使用。应当使用setClassLong()函数替换Button类的鼠标,例如:
HWND hbutton;HCURSOR hnewCur;hnewCur=LoadCursorFromFile("C:\\WINNT\\Cursors\\AnimCur.ANI");hbutton=(HWND)GetDlgItem(IDC_BUTTON);//IDC_BUTTON为要改变鼠标的控件IDSetClassLong(hbutton,GCL_HCURSOR,(long)hnewCur);
3) RegisterClass()或RegisterClassEx()函数
这是最麻烦的方法,但是可以作用于属于同一个窗口类的所有窗口。在RegisterClass()或RegisterClassEx()之前,填写WNDCLASS时,将一个自定义的Cursor句柄赋值给hCursor,例如WNDCLASSEX wcx;
wcx.hCursor=LoadCursor(hInst,MAKEINTRESOURCE(NEWCUR));
4、 鼠标操作函数
1) 剪切鼠标,限制鼠标移动
ClipCursor()函数用来剪切鼠标,参数为一个指向RECT的指针,在通常情况下鼠标被剪切于整个屏幕,如果一个程序的某个窗口要剪切鼠标,必须先用GetClipCursor()获得屏幕的鼠标剪切区域,然后用ClipCursor()剪切鼠标至程序窗口,程序退出后必须将鼠标的剪切区域还原成屏幕矩形,以免影响其他的程序使用鼠标。假设我们想将鼠标限制在窗口hwnd内,应当:
RECT rt1;//存放屏幕剪切矩形RECT rt2;//存放程序窗口剪切矩形GetClipCursor(&rt1);//获得当前的鼠标剪切矩形填写入rt1,如果鼠标没有被别的程序剪切,那么整个矩形就是屏幕矩形GetWindowRect(hwnd,&rt2);//获得程序窗口hwnd的矩形至rt2ClipCursor(&rt2);//剪切鼠标之rt2程序执行完成后应当:ClipCursor(&rt1);//将鼠标的剪切矩形还原为rt1(屏幕)
2) 跟踪鼠标位置
GetCursorPos()用来获得当前鼠标位置,SetCursorPos()设置鼠标位置,例如:
POINT pt;//存放鼠标位置的结构 GetCursorPos(&pt1);//获得当前鼠标位置SetCursorPos(pt.x+100,pt.y+100);//根据原位置计算得到新位置
一、 标准鼠标替换
Windows提供了一系列标准鼠标,其标示前缀均为IDC_,用SetSystemCursor()函数可以替换系统的标准鼠标。SetSystemCusor()有两个参数,第一个为一个通过LoadCursor()(LoadCursor()函数以被LoadImage()函数取代)、CreateCursor()或CopyCursor()获得的Cursor指针。例如:
HCURSOR hnewCur;hnewCur=LoadCursor(hInst,MAKEINTRESOURCE(NEWCURSOR);NEWCURSOR为hInst中的一个Cursor,SetSystemCursor(hnewCur,OCR_NORMAL);使用用户定义鼠标替换系统默认鼠标,当用户再次使用LoadCursor(NULL,IDC_ARROW);加载标准鼠标时获得的将是用户加载的而非系统预定义的鼠标
二、 更换Cursor的方法
1、 新建Cursor
此方法最为烦琐,但用户拥有完全的控制权,比如可以自主设立HotSpot的位置,而不是默认的左上角,具体方法是先填写一个ICONINFO结构:
typedef struct ICONINFO { BOOL fIcon; 是否为图标,将其赋值为FALSE,标示该结构用来建立鼠标DWORD xHotspot; HotSpot的X坐标DWORD yHotspot; HotSpot的Y坐标HBITMAP hbmMask; 鼠标外观的掩模图,用来过滤鼠标的背景HBITMAP hbmColor; 鼠标外观图片} ICONINFO;
填写好后调用CreateIconIndirect()得到一个HICON句柄,如果你建立的是鼠标,将其转换成HCURSOR即可,例如:
ICONINFO ii;HCURSOR hnewCur;ii.fIcon=FALSE;ii.yHotspot=0;ii.yHotspot=0;ii.hbmMask=LoadBitmap(hInst,MAKEINTRESOURCE(IDBCURSORMASK));ii.hbmColor=LoadBitmap(hInst,MAKEINTRESOURCE(IDB_CURSOR));hnewCur=(HCURSOR)CreateIconIndirect(&ii);
2、 加载Cursor
加载是最常用的方法,被加载的鼠标可以是VC集成开发环境中设计好的Cursor,也可以是.ANI或.Cur文件。
1) 从文件中加载:
LoadCursorFromFile();例如:LoadCursorFromFile("C:\\AniCur.ANI")加载一个动画鼠标。
2) 从集成开发环境中加载:
LoadCursor(hInst,MAKEINTRESOURCE(NEWCURSOR));NEWCURSOR可以在资源编辑器中设计。还要说明的是LoadImage()是较LoadCursor()、LoadBitmap()和LoadCursorFromFile()更新的函数,它集多个函数的功能于一身,用起来更加方便,主要的区别在于其多了一个标志来说明加载的是位图、图标函数鼠标。
3、 使用Cursor
1) SetCursor()
捕获窗口的WM_MOUSEMOVE或者WM_SETCURSOR消息,在其处理函数中添加对SetCursor()的调用,例如:SetCursor(hnewCur);其中hnewCur为一个通过上述的任意一种方法获得的HCURSOR
2) SetClassLong()
捕获WM_MOUSEMOVE消息只对有窗口函数的窗口有效,而对像Button控件则无法使用。应当使用setClassLong()函数替换Button类的鼠标,例如:
HWND hbutton;HCURSOR hnewCur;hnewCur=LoadCursorFromFile("C:\\WINNT\\Cursors\\AnimCur.ANI");hbutton=(HWND)GetDlgItem(IDC_BUTTON);//IDC_BUTTON为要改变鼠标的控件IDSetClassLong(hbutton,GCL_HCURSOR,(long)hnewCur);
3) RegisterClass()或RegisterClassEx()函数
这是最麻烦的方法,但是可以作用于属于同一个窗口类的所有窗口。在RegisterClass()或RegisterClassEx()之前,填写WNDCLASS时,将一个自定义的Cursor句柄赋值给hCursor,例如WNDCLASSEX wcx;
wcx.hCursor=LoadCursor(hInst,MAKEINTRESOURCE(NEWCUR));
4、 鼠标操作函数
1) 剪切鼠标,限制鼠标移动
ClipCursor()函数用来剪切鼠标,参数为一个指向RECT的指针,在通常情况下鼠标被剪切于整个屏幕,如果一个程序的某个窗口要剪切鼠标,必须先用GetClipCursor()获得屏幕的鼠标剪切区域,然后用ClipCursor()剪切鼠标至程序窗口,程序退出后必须将鼠标的剪切区域还原成屏幕矩形,以免影响其他的程序使用鼠标。假设我们想将鼠标限制在窗口hwnd内,应当:
RECT rt1;//存放屏幕剪切矩形RECT rt2;//存放程序窗口剪切矩形GetClipCursor(&rt1);//获得当前的鼠标剪切矩形填写入rt1,如果鼠标没有被别的程序剪切,那么整个矩形就是屏幕矩形GetWindowRect(hwnd,&rt2);//获得程序窗口hwnd的矩形至rt2ClipCursor(&rt2);//剪切鼠标之rt2程序执行完成后应当:ClipCursor(&rt1);//将鼠标的剪切矩形还原为rt1(屏幕)
2) 跟踪鼠标位置
GetCursorPos()用来获得当前鼠标位置,SetCursorPos()设置鼠标位置,例如:
POINT pt;//存放鼠标位置的结构 GetCursorPos(&pt1);//获得当前鼠标位置SetCursorPos(pt.x+100,pt.y+100);//根据原位置计算得到新位置
决定在这里写了,谈谈看法
Posted by
Tony Su
at
6:55 PM
总而言之毕竟是和google相关的东西
风格是我很喜欢的那种
简约,开放性
比那些华而不实的强多了
但编辑界面的字体看起来还是比较别扭
另外也没有在默认的界面方案中找到一个十分满意的
不过由于开放性,将来可以自己设置吧
决定在这里写了
转点原来存的技术文章先
不主要是给别人看,也是给自己留个备忘
风格是我很喜欢的那种
简约,开放性
比那些华而不实的强多了
但编辑界面的字体看起来还是比较别扭
另外也没有在默认的界面方案中找到一个十分满意的
不过由于开放性,将来可以自己设置吧
决定在这里写了
转点原来存的技术文章先
不主要是给别人看,也是给自己留个备忘
Subscribe to:
Posts (Atom)