转:浅析windows下字符集和文件编码存储/utf8/gbk
最近老猿在学习文件操作及网络爬虫相关知识,发现字符集及编码的处理非常重要,而老猿原来对此了解并不多,因此找了几篇文章看了一下,将老猿认为比较的相关文章转载一下。感谢各位原创大神!
1,字符集
这里主要讲两种字符集,DBCS和UCS
DBCS即双字节编码字符集,最初的计算机只有ASCII码,发展至今,不能表示中文怎么办,于是中国人制定了GBK2312,以及后面陆续扩展并向下兼容的GBK,GB18030.
Unicode学名是“Universal Multiple-Octet Coded Chasracter Set”,简称UCS,他只兼容ANSI,为啥会有Unicode出现呢,因为在使用DBCS的时候,各个国家都有自己的一套字符集,于是非常的混乱的,不能正常显示所有字符,微软使用代码页(Codepage)转换表的技术来过渡性的部分解决这一问题,后来国际组织决定指定一套全球统一字符集,就是Unicode了。
UCS只是规定如何编码,并没有规定如何传输、保存这个编码。例如“汉”字的UCS编码是6C49,
我可以用4个ascii数字来传输、保存这个编码;也可以用utf-8编码:3个连续的字节E6 B1 89来表示它。
关键在于通信双方都要认可。UTF-8、UTF-7、UTF-16都是被广泛接受的方案。
UTF-8就是以8位为单元对UCS进行编码。从UCS-2到UTF-8的编码方式如下:
UCS-2编码(16进制) UTF-8 字节流(二进制)
0000 – 007F 0xxxxxxx
0080 – 07FF 110xxxxx 10xxxxxx
0800 – FFFF 1110xxxx 10xxxxxx 10xxxxxx
UCS-2就是windows的宽字符,也就是utf16编码。
例如“汉”字的Unicode编码是6C49。6C49在0800-FFFF之间,所以肯定要用3字节模板了:1110xxxx 10xxxxxx 10xxxxxx。将6C49写成二进制是:0110 110001 001001,
用这个比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89。
2,BOM
BOM是在一个文本文件之前,用来标记改文件编码方式的一种记录方式,windows下是这样做的,linux不知道。
UTF-8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是“奎”还是“乙”?
Unicode规范中推荐的标记字节顺序的方法是BOM。BOM不是“Bill Of Material”的BOM表,而是Byte Order Mark。BOM是一个有点小聪明的想法:
在UCS编码中有一个叫做”ZERO WIDTH NO-BREAK SPACE”的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符”ZERO WIDTH NO-BREAK SPACE”。
这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。因此字符”ZERO WIDTH NO-BREAK SPACE”又被称作BOM。
UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符”ZERO WIDTH NO-BREAK SPACE”的UTF-8编码是EF BB BF(读者可以用我们前面介绍的编码方法验证一下)。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。
假如文件用UTF8无BOM格式来保存文件,那就不能单纯的依靠BOM头来判断是否是utf8编码的,而要对文件中的数据进行简单的编码分析来确定文件的编码格式,也就是对文件的二进制进行分析,和对应编码的字符集进行匹配,最终确定其编码格式。
一个简单的小例子,用windows的notepad写一个文件,记录下“联通”两个字,关闭打开后,发现文件乱码了,为什么呢?就是文件编码是被错误导致的。
notepad存盘默认用的ansi编码,也就是对应gbk字符集。
联通的gbk字符集是“C1 AA CD A8”
C1 AA 对应的二进制: 1100 0001, 1010 1010
CD AB 对应的二进制: 1100 1101, 1010 1000
注意看红色的部分,刚好和上面UTF8的编码结构完全一致,因此才误将其认为是utf8无BOM编码的文件。可以使用notepad++打开来查看这个文件的编码格式,确实是UTF8无BOM格式。
ansi编码,ascii码用单字节ascii码值存储,非ascii码表内的,使用对应的dbcs字符集编码之来存储,因此同一个“汉字AB”对应的ansi编码存储的文件是 BA BA D7 D6 41 42
最后,统一看下。
"汉"字的gbk,utf8(有BOM),utf8(无BOM)utf16(小端),utf16(大端),二进制分别是
BA BA , EF BB BF E6 B1 89 ,E6 B1 89 , FF FE 49 6C , FE FF 6C 49
本文转自:
浅析windows下字符集和文件编码存储/utf8/gbk http://seanyxie.com/a/jisuanjijichu/caozuoxitong/2019/0409/32.html
转:浅析windows下字符集和文件编码存储/utf8/gbk的更多相关文章
- 基于Windows下处理Java错误:编码GBK的不可映射字符的解决方案
基于Windows下处理Java错误:编码GBK的不可映射字符的解决方案 最近在研究Java,涉及命令行编译,使用notepad++编辑器,然后使用javac编译: 之前的几个文件没有中文的内容,都没 ...
- mysql windows 下导入大文件
先进入你的mysql bin目录 cd D:/php/mysql/bin 输入命令 mysql -u 用户名 -p 密码 数据库名 < 文件路径 ...
- 用脚本如何实现将Linux下的txt文件批量转化为Windows下的txt文件?
众所周知,Windows和Linux的文件换行回车格式不同,Windows下换行格式是\r\n(回车+换行),Linux下换行格式为\n(只是换行),因此,其中一个操作系统的文本文件若需要在另外一个中 ...
- Windows 下目录及文件向Linux同步
本文解决的是Windows 下目录及文件向Linux同步的问题,Windows向 Windows同步的请参考:http://www.idcfree.com/article-852-1.html 环境介 ...
- Windows下如何将一个文件夹通过Git上传到GitHub上(转)
在通过windows系统的电脑上写代码,需要将项目上传到GitHub上去.比如在Pycharm上写Django后端,整个项目是一个文件夹的形式,那么怎么才能这个文件夹通过Git命令上传到GitHub上 ...
- windows下python检查文件是否被其它文件打开
windows下python检查文件是否被其它文件打开.md 有时候我们需要能够判断一个文件是否正在被其它文件访问,几乎不可避免的要调用操作系统接口 from ctypes import cdll i ...
- Linux&Windows下批量修改文件后缀
Linux下从给定文件夹中找出小于1M的文件,并批量添加.gif后缀 先看一下文件夹下的目录的格式 ll -Sh -rw-rw-r-- 1 yangkun yangkun 17M May 10 15: ...
- Windows下创建.gitgnore文件
相信使用过git的朋友可能遇到过,直接在windows下创建.gitgnore文件失败.类似截图那样 上网查了一下,有两种方法. 方法1: 此方法较为简单,前提是安装了git bash. 用git b ...
- windows下打开.ipynb文件
windows下打开.ipynb文件1.首先要下载python,设置环境变量2.下载pip,设置环境变量3.打开命令行,进入到python的Scripts文件中,按顺序执行下面三个命令pip inst ...
随机推荐
- 使用webapi绑定layui数据表格完整增删查改记录
因为每次给layui数据表格绑定数据或者类似操作的时候 总要重新做一遍 而且忘记很多东西 所以干脆写博客把相关东西记录下来 便于查阅和修正 以下是一个完整的数据表格i项目的增删改查案例 先来看后台 ...
- TPE-ThreadPoolExecutor
TPE: java.util.concurrent.ThreadPoolExecutor public ThreadPoolExecutor(int corePoolSize, int maximum ...
- mysql 定时任务执行
SET GLOBAL event_scheduler = ON; show variables like 'event_scheduler'; event_scheduler ON 创建event: ...
- Firefox威武 尚译威武!
有感于鹰文文档看起来麻烦,期待有一款即时翻译的工具,在windows上还可以,但是上班用的是ubuntu,所以就想到要找一个firefox插件,还真找到了,但是不是插件,是一个书签,那就是尚译!尚哥威 ...
- SpringBoot中BeanValidation数据校验与优雅处理详解
目录 本篇要点 后端参数校验的必要性 不使用Validator的参数处理逻辑 Validator框架提供的便利 SpringBoot自动配置ValidationAutoConfiguration Va ...
- Netlink 内核实现分析 1
Netlink 是一种IPC(Inter Process Commumicate)机制,它是一种用于内核与用户空间通信的机制,在一般情况下,用户态和内核态通信会使用传统的Ioctl.sysfs属性文件 ...
- mon的稳定性问题
MON的稳定性问题: mon的选举风暴影响客户端IO LevelDB的暴涨 频繁的客户端请求的DDOS mon选举风暴: monmap会因为mon之间或者mon与客户端之间网络的影响或者消息传递的异常 ...
- Jrebel & Xrebel 在线激活方法 (亲测可用)
一开始用eclipse的时候虽然这是一个狂吃内存的家伙,但是调试代码是真的舒服,修改过的代码可以不用重启热加载,后来转idea,虽然idea很完美但是也有不足的地方,比如代码调试就不能热加载. 还好有 ...
- 企业级工作流解决方案(十五)--集成Abp和ng-alain--Abp其他改造
配置功能增强 Abp定义了各种配置接口,但是没有定义这些配置数据从哪里来,但是管理配置数据对于一个应用程序来说,是必不可少的一件事情. .net的配置数据管理,一般放在Web.config文件或者Ap ...
- 在linux系统中通过fw_printenv查看和设置u-boot中的环境变量
uboot下可以通过命令访问(printenv)和修改环境变量(setenv),但是如果需要在Linux系统下访问这些数据该怎么办呢?其实uboot早就帮我们想好了. 1.编译fw_printenv ...