理清文本编码

最近搞u3d开发,把一些文本文件打成包,发布到手机上,发现各种乱码,结果法线是各种编码方式不对,于是好好研究了一下不同平台上的字符编码,然后发现以前一直认为的unicode utf8 gbk asc2这些字符编码自以为很懂,其实完全理解的不对,在这方面也是因为有太多的网上文档在误人子弟,这里好好梳理一下

1.首先为什么要对字符进行编码?文本格式同二进制格式有何不同?

   计算机的基本计量单位是一个比特(即一个二进制数),而存储数据的一个基本单位是字节(8位二进制数,2个16进制数 0X00-0xff),也就是说一切数据在磁盘上都是用一个个字节存储的,但是文本字符确实另外一个概念,字节(0X00-0xff)是不能天然表示文本字符的,因为字符太多了,所以需要使用编码方式(用几个字节的组合)来表示不用的文本字符。这是对字符进行编码的原因

   二进制文件就是一个字节的序列。你用不同的解码去解释他可能得到不同的意义,有可能解释出来就是一张jpeg图片也说不定。但是早读写文件时标记为文本文件,就等于告诉了读写程序(例如fstream这些玩意儿),你要按照文件的解码方式去解释这些二进制,返回给我的直接就是解释好的文本字符,而不是最原始的字节,比如在字节5A
二进制读入就是5a(或者十进制的byte表示成90),但是如果用文本格式读(用字符编码区解释)就可能得到的是 ‘Z’。

2.什么是字符编码?

既然需要对文本字符进行编码,就需要有标准,因为历史和其他种种原因,出现了很多编码标准,没有一个全世界唯一认同的编码标准,比如你定义10代表a,我可以定义1000代表a。所以不同的字符编码唯一的区别就是字符的编码值(表示那个字符的多个字节的数值)不同。例如asc2定义z的值为90,没有定义汉字字符,unicode定义0x6211这个数代表‘我’这个汉字。不同的字符值就是不同字符编码体系的体现。

现在常用的字符编码体系主要有asc2和unicode,gbk ,bigend5等,而unicode是完全囊括了asc2的,因为unicode可以说是国际标准,而GBK是大陆的标准,这些不同的编码体系之间通常没有太多的直接联系或者公式好换算,最直接的方法就是查映射表,例如,'我‘在unicode规定的值是0x6211,而在gbk里面是0xced2.值完全不同。

一句话,不同的字符编码集定义表示一个文本字符不同的数值

3.Unicode和utf-8的区别是什么?

首先一种编码集可能只规定了某个字符的值应该是多少,但是对这个值的存储(在传输意义上的)没有规定,所以一个字符编码下可能有不同的实现方式,因此同一个编码集下对同一个字符的存储并不一样,例如同是‘我’,在unicode编码上一定是值0x6211,但是我可以用2个字节存储,也可以用四个字节存储,甚至我可以对某个字符用1个字节存储,某些用多个,因此这就有了一个在同一个编码集下不同是存储实现的问题。

在unicode里,有很多种存储实现方式,包括UTF-8 UTF-16 UTF-32(也有直接用unicode表示utf-32)
,等等,他们对同一个字符都用同一个值表示,但是UTF-16对每个字节会用2个字节存,UTF-8用变长字节存。例如0x00AB和0xAB读进来的值都是一样的,也就是表示的一个字符,但是确实两种不同的存储方式,如果你用UTF-8解码,就要按照UTF-8的定义去读字节,然后得到数值,如果你用UTF-16就要一次读两个字节,然后得到数值。他们的存储方式不同,文件的内容大小肯定不一样,而目前UTF-8因为变长存储的原因,节省存储空间,一般是比较流行的。

所以这里就明白了unicode和utf-8明显不是一个平行的关系,而是UTF-8只是unicode字符编码集中的一种存储实现方式。而unicode和gbk却是平行的概念。

一句话:实现一种字符编码,首先要定义它的字符值,然后定义这个字符值的字节存储方式

4.codepage 和cp936这些编码是啥玩意儿?

这些都是微软自己定义的概念。因为存在这么多种字符编码集,每种编码集里面又可能有不同的存储方式,在写程序上再不同的存储方式的文件中解码编码转换就是个麻烦事,比如你要把一个gbk编码的文件读出来转换成utf-16来存储,怎么办?你首先要用gbk的解存储格式的方法读入文件的每个文本字符的数值,然后查gbk的编码表,得到每个数值表示的文本,得到文本后,要存储,首先就要查utf-16所属的unicode的编码表,得到每个字符在unicode下面应该表示的数值,最后用utf-16的存储方式存储每个数值,完成。

      而微软为了能够在存储方式上统一不同的编码方式,就按照不同编码的不同存储方式为基本单元重新定义一个code page,在这个code page上,UTF-8 UTF-16 GB2312等都是不同的code page,而unicode则没有相应的codepage,因为他不是一个具体的存储方式,gbk也没有被收录,因为gbk不是官方标准,官方的简体中文编码集是GB2312,它的code
page序号是936,因此所说的cp936即是值微软定义的GB2312文本字符编码(和存储方式)。

  5.平台支持和默认编码

   一般在简体中文的windows上,默认的编码就是GB2312(CP936),在linux上一般是utf-8,所以像android  ios这些类unix的系统的默认编码都是utf-8,而windows也支持UTF-8的编解码,但是很多类unix系统确不一定支持GB2312或者GBK这样的编解码(例如android和ios),所以UTF-8一般更加的通用,是一些跨平台时通常选用的编码。

  昨天遇到的问题就是一个带中文的汉字直接打包到ios上乱码,问题就在于汉字生成的时候使用简体中文windows的默认编码GB2312,到ios上面打开,ios默认的编码是UTF-8,当然解析到乱码,所以我们的项目在打包时统一转成UTF-8编码,在设备上(pc android ios)打开再统一用UTF-8解码,问题就解决了

时间: 2024-08-02 04:27:35

理清文本编码的相关文章

【源码】文本编码转换器

问题描述 今天刚注册csdn,分享个小程序,可供学完JavaSE的同学做参考.执行文件:http://pan.baidu.com/s/1kTLt6jd源码:http://pan.baidu.com/s/1mgFRQi8密码:v85o 解决方案 解决方案二:谢谢大神的分享,大神可否共享到http://code.csdn.net/上便于后续在线更新和后续跟进学习解决方案三:引用1楼guest6379的回复: 谢谢大神的分享,大神可否共享到http://code.csdn.net/上便于后续在线更新和

php简单判断文本编码的方法_php技巧

本文实例讲述了php简单判断文本编码的方法.分享给大家供大家参考.具体如下: 这里通过对文本的一次循环编码,来判断是否属于该编码. public function chkCode($string) { $code = array( 'ASCII', 'GBK', 'UTF-8' ); foreach ($code as $c) { if ($string === iconv('UTF-8', $c, iconv($c, 'UTF-8', $string))) { return $c; } } r

php检测文本的编码_php技巧

通过对文本的一次循环编码,来判断是否属于该编码. public function chkCode($string) { $code = array( 'ASCII', 'GBK', 'UTF-8' ); foreach ($code as $c) { if ($string === iconv('UTF-8', $c, iconv($c, 'UTF-8', $string))) { return $c; } } return null; } 以上所述就是本文的全部内容了,希望大家能够喜欢. 以上

二进制-html5下a标签,如何定义下载文件txt的编码方式

问题描述 html5下a标签,如何定义下载文件txt的编码方式 要用a标签的download属性,下载一个txt的文件,文件内容是js下的字符串,然后本人用blob装成二进制流,在用URL.createObjectURL生成href地址.然后赋给a标签.但是每次遇到字符串中有中文,就会出现txt文本编码自动变成utf-8,本人想要的是ansi格式的txt文件. <!doctype html><html lang=""en""><head

《WCF技术内幕》翻译9:第1部分_第2章_面向服务:消息编码

消息编码 随着时间的流逝,也许我们会条件反射式地认为XML(SOAP)是一个结构文本 .毕竟,文本是人可读的,每个计算机系统也可以处理文本.基于文本的XML的 普遍共性与我们的与其它系统交互的想法产生了共鸣.可以容易的解释的基于文 本的XML本质上会体积变大.可以理解使用XML会带来性能损失.就像要花费点精 力把信装到信封里一样,它需要一些处理时间与XML交互.某些情况下,基于文 本的XML数据大小限制了它的应用,特别是当我们要通过网络发送一个XML消息的 时候. 此外,如果我们限制自己使用基于

Linux系统下转换文件编码的方法小结

  一.利用iconv命令进行文件内容编码转换 用法: iconv [选项...] [文件...] 有如下选项可用: 输入/输出格式规范: -f, --from-code=名称 原始文本编码 -t, --to-code=名称 输出编码 信息: -l, --list 列举所有已知的字符集 输出控制: -c 从输出中忽略无效的字符 -o, --output=FILE 输出文件 -s, --silent 关闭警告 --verbose 打印进度信息 -?, --help 给出该系统求助列表 --usag

虹吸墨批量处理文本常见操作

  文本文件作为最常见的文件格式,几乎每个人每天都要和它打交道.普通的文本编辑器,只能进行简单的文字编辑操作,而其实除了文本处理,经常我们还需要对文本文件进行分割合并.批量改名.文件加密.文本计算等处理,往往需要启用多个第三方软件.今天则介绍给大家一款高级文本编辑器--虹吸墨,它除了基本的文字处理之外,常见文本文件的处理工作也能一并完成. 安装设置虹吸墨的注意事项 大家可以从网站nullice.com/Gasoft/Siphonink上去下载"虹吸墨"绿色版,解压后双击其中唯一的可执行

深入Go语言文本类型

Go的作者Ken Thompson是UTF-8的发明人(也是C,Unix,Plan9等的创始人),因此在关于字符编码上,Go有着独到而周全的设计.本文介绍了Go语言中的三种内置文本类型:string, byte,rune的内部表示与相互转换. 1. 概览 Go中,字符串string是内置类型,与文本处理相关的内置类型还有符文rune和字节byte. UTF-8编码在Go语言中有着特殊的位置,无论是源代码的文本编码,还是字符串的内部编码都是UTF-8.Go绕开前辈语言们踩过的坑,使用了UTF8作为

Linux下文本的高效处理

1 引言 所谓的文本处理是指对文本进行查找.替换.删除.排序等操作, linux在文本处理方面提供了大量优秀的工具, 使得在linux下进行文本处理极其的方便.  我们平常的工作中, 经常会用到文本处理, 比如日志分析, 比如文本抽取, 等等, 所以掌握好文本处理, 将会对我们的工作起到极大的作用.  下面我就来逐个介绍下这些强大的工具, 对于我觉得大家可能比较熟知的工具及用法, 我会略过, 或者粗讲下. 2 关于输入 Linux哲学中, 为了更好的组合各种命令达到更加强大的功能, 大多数文本处