• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >编程技巧 > 计算机中的字符串编码、乱码、BOM等问题详解

计算机中的字符串编码、乱码、BOM等问题详解

作者:junjie 字体:[增加 减小] 来源:互联网 时间:2017-05-12

junjie 通过本文主要向大家介绍了计算机中的字符串编码、乱码、BOM等问题详解等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

因为电脑是windows 7系统,开发环境又在linux,经常在linux碰到乱码问题,很是痛苦,于是决定好好了解编码的来龙气脉,并分享个各位,免得出现乱码时不知所措。

是否存在文件编码

在讲解字符编码之前,我们需先明确文件本身没有编码一说,只有文字才有编码的概念,我们通常说某个文件是什么编码,通常是指文件里字符的编码。

vim为什么会出现乱码

我在linux下一般使用vim进行文件编辑,发现经常会碰到乱码的情况,那么为什么会出现乱码呢? 首先我们了解下vim编码方面的基础知识,关于编码方面vim存在3个变量:

1.encoding: Vim 内部使用的字符编码方式,包括 Vim 的 buffer (缓冲区)、菜单文本、消息文本等。默认是根据你的locale选择.用户手册上建议只在 .vimrc 中改变它的值,事实上似乎也只有在.vimrc 中改变它的值才有意义。你可以用另外一种编码来编辑和保存文件,如你的vim的encoding为utf-8,所编辑的文件采用cp936编码,vim会自动将读入的文件转成utf-8(vim的能读懂的方式),而当你写入文件时,又会自动转回成cp936(文件的保存编码).

2.fileencoding: Vim 中当前编辑的文件的字符编码方式,Vim 保存文件时也会将文件保存为这种字符编码方式 (不管是否新文件都如此)。

3.termencoding: Vim 所工作的终端 (或者 Windows 的 Console 窗口) 的字符编码方式。如果vim所在的term与vim编码相同,则无需设置。如其不然,你可以用vim的termencoding选项将自动转换成term的编码.

当这三个变量的编码出现问题时就会出现乱码:

1.encoding不是utf-8编码:如果encoding不是utf-8编码,其他字符可能无法转为 Encoding的指定编码。如:如果encoding是gbk编码,而文件内容采用big5编码的,其就无法转换为gbk编码。

2.fileencoding不对:Fileencoding编码是vim的读取文件内容时使用的编码,如果其编码与文件字符编码不同,必然会出现乱码。Fileencoding编码一般由vim自动检测,可以使用fileencodings设置,Vim自动探测fileencoding的顺序列表。不过vim有时候会检测错误,就会出现乱码了。

3.termencoding编码不对:我们登录服务器一般采用远程登录,这就涉及终端编码问题,我经常碰到因为终端编码不对导致乱码的。如:SecureCRT设置为utf-8编码,而vim的termencoding却为gbk,就出现乱码了。

字符编码介绍

说了那么多,到底字符编码是什么玩意呢?

字符(Character)是文字与符号的总称,包括文字、图形符号、数学符号等,一组抽象字符的集合就是字符集(Charset)。 字符集常常和一种具体的语言文字对应起来,该文字中的所有字符或者大部分常用字符就构成了该文字的字符集,比如英文字符集,汉字字符集。 计算机要处理各种字符,就需要将字符和二进制内码对应起来,这种对应关系就是字符编码(Encoding)。 制定编码首先要确定字符集,并将字符集内的字符排序,然后和二进制数字对应起来。根据字符集内字符的多少,会确定用几个字节来编码。

字符集和编码的区别:

字符集字符的集合,不一定适合计算机存储、网络传送、处理,有时须经编码(encode)后才能应用。如Unicode字符集可依不同需要以UTF-8、UTF-16、UTF-32等方式编码。

字符编码的发展

字符编码大概分为三个发展阶段。

ASCII编码:ASCII(American Standard Code for Information Interchange,美国信息互换标准代码)是基于拉丁字母的一套电脑编码系统。 因为计算机起源于美国,为表示英文字符,他们制定了ASCII编码,ASCII编码使用7位二进制来表示字符,高位用来做奇偶校验,0×20以下的字节状态称为”控制码”,同时包括标点符号、数字等,当时人们觉得已经够用了。

多种编码并存:但随着计算机的广泛应用,别的国家也开始使用计算机,但是很多国家用的不是英文,他们的字母里有许多是ASCII里没有的,为了可以在计算机保存他们的文字,他们决定采用127号之后的空位来表示这些新的字母、符号,还加入了很多画表格时需要用下到的横线、竖线、交叉等形状,一直把序号编到了最后一个状态255。从128到255这一页的字符集被称”扩展字符集”。最优秀的扩展方案是ISO 8859-1,通常称之为Latin-1,Latin-1包括了足够的附加字符集来写基本的西欧语言。

后来其他国家也开始使用计算机,为了表达自己国家的文字,不同的国家和地区制定了不同的标准,产生了GB2312,BIG5,JIS等各自的编码标准。通常使用0×80~xFF范围的2个字节来表示1个字符。比如:汉字 ‘中' 在中文操作系统中,使用 [0xD6,0xD0]这两个字节存储。 这些使用2个字节来代表一个字符的延伸编码方式,称为 ANSI 编码。

在简体中文系统下,ANSI 编码代表 GB2312 编码,在日文操作系统下,ANSI 编码代表 JIS 编码。 不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。

Unicode编码 由于不同国家的ANSI编码互不兼容,为了使国际间信息交流更加方便,国际组织制定了UNICODE字符集,为各种语言中的每一个字符设定了统一并且唯一的数字编号,以满足跨语言、跨平台进行文本转换、处理的要求。 UNICODE开始制订时,计算机的存储器容量极大地发展了,空间再也不成为问题了。于是ISO就直接规定必须用两个字节,也就是16位来统一表示所有的字符,对于ascii里的那些“半角”字符,UNICODE保持其原编码不变,只是将其长度由原来的8位扩展为16位,而其他文化和语言的字符则全部重新统一编码。由于”半角”英文符号只需要用到低8位,所以其高8位永远是0,因此这种大气的方案在保存英文文本时会多浪费一倍的空间。

但是UNICODE来到时,一起到来的还有计算机网络的兴起,UNICODE如何在网络上传输也是一个必须考虑的问题,于是面向传输的众UTF(UCS Transfer Format)标准出现了,顾名思义,UTF8就是每次8个位传输数据,而UTF16就是每次16个位,只不过为了传输时的可靠性,从UNICODE到UTF时并不是直接的对应,而是要过一些算法和规则来转换。

学过计算机网络的童鞋都知道,在网络里传递信息时有一个很重要的问题,就是对于数据高低位的解读方式,一些计算机是采用低位先发送的方法,例如我们PC机采用的INTEL架构;而另一些是采用高位先发送的方式。在网络中交换数据时,为了核对双方对于高低位的认识是否是一致的,采用了一种很简便的方法,就是在文本流的开始时向对方发送一个标志符——如果之后的文本是高位先发送,那就发送”FEFF”,反之,则发送”FFFE”。(IP/TCP协议规定网络字节序使用大端法)
因为UTF-8编码兼容之前的ASCII编码,而且有利于传输,其得到了非常广泛的应用。

从UNICODE到UTF8的转换规则:

Unicode             UTF-8
0000 - 007F         0xxxxxxx
0080 - 07FF         110xxxxx 10xxxxxx
0800 - FFFF         1110xxxx 10xxxxxx 10xxxxxx
</div>

汉字ANSI编码发展

GB2312:为了表示汉字,我们国家首先发明了GB2312 编码,GB2312 编码规定一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,前面的一个字节(他称之为高字节)从0xA1用到0xF7,后面一个字节(低字节)从0xA1到0xFE,这样我们就可以组合出大约7000多个简体汉字了。在这些编码里,我们还把数学符号、罗马希腊的字母、日文的假名们都编进去了,连在 ASCII 里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的”全角”字符,而原来在127号以下的那些就叫”半角”字符了。

GBK 后来发现很多偏僻字和少数名族的语言还是没办法编码进来,为了表示这些字符,于是干脆不再要求低字节一定是127号之后的内码,只要第一个字节是大于127就固定表示这是一个汉字的开始,不管后面跟的是不是扩展字符集里的内容。结果扩展之后的编码方案被称为 GBK 标准,GBK包括了GB2312的所有内容,同时又增加了近20000个新的汉字(包括繁体字)和符号。

GB18030 后来少数民族也要用电脑了,于是我们再扩展,又加了几千个新的少数民族的字,GBK扩成了GB18030。从此之后,中华民族的文化就可以在计算机时代中传承了。

BOM介绍

1.BOM的来历: 为了识别 Unicode 文件,Microsoft 建议所有的 Unicode 文件应该以 ZERO WIDTH NOBREAK SPACE(U+FEFF)字符开头。这作为一个“特征符”或“字节顺序标记(byte-order mark,BOM)”来识别文件中使用的编码和字节顺序。

2.不同的系统对BOM的支持:因为一些系统或程序不支持BOM,因此带有BOM的Unicode文件有时会带来一些问题。

①JDK1.5以及之前的Reader都不能处理带有BOM的UTF-8编码的文件,解析这种格式的xml文件时,会抛出异常:Content is not allowed in prolog。
②Linux/UNIX 并没有使用 BOM,因为它会破坏现有的 ASCII 文件的语法约定。
③不同的编辑工具对BOM的处理也各不相同。使用Windows自带的记事本将文件保存为UTF-8编码的时候,记事本会自动在文件开头插入BOM(虽然BOM对UTF-8来说并不是必须的)。而其它很多编辑器用不用BOM是可以选择的。UTF-8、UTF-16都是如此。<

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

相关文章

  • 2017-05-12Git提交文件到三个区的实现方法
  • 2017-05-12判断Email地址是否正确的几个函数(asp/php/javascript)
  • 2017-05-12有效的提高编程技能的12个方法
  • 2017-05-12Web开发人员常用速查手册 英文集合推荐
  • 2017-05-12Web 设计与开发者必须知道的 15 个站点
  • 2017-05-12网址(URL)支持的最大长度是多少?最大支持多少个字符?
  • 2017-05-12微信报警 zabbix实现详解
  • 2017-05-12git提交空目录的方法
  • 2017-05-12图片的色彩空间问题
  • 2017-05-12分享下GET和POST的真正区别

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • UI基础知识学习
    • 电子邮件 退信原因大全
    • python数据分析
    • textarea 在IE和FF下换行无法正常显示的解决方法
    • gb2312的详细介绍
    • 详解版本控制利器Git,SVN的异同以及适用范围
    • zend stdio8.0 快捷键汇总集合
    • 遇到不能复制的网站怎么办?
    • 关于base64编码的原理及实现方法分享
    • 程序员的八种境界,你在哪一境?

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有