首页 > 编码小记(未整理-持续更新)

编码小记(未整理-持续更新)

----------------基本概念-------------------------------

一.位:

计算机存储信息的最小单位,称之为位(bit),音译比特,二进制的一个“0”或一个“1”叫一位。

二.字节

字节(Byte)是一种计量单位,表示数据量多少,它是计算机信息技术用于计量存储容量的一种计量单位,8个二进制位组成1个字节。在ASCII码中,一个标准英文字母(不分大小写)占一个字节位置,一个标准汉字占二个字节位置。

三.字符

字符是指计算机中使用的文字和符号,比如“1、2、3、A、B、C、~!·#¥%…*()+”等等。

-----------------常用的编码的简单分类(3类)---------------

单字节字符编码:

1. 编码标准:ISO-8859-1

2. 说明:

最简单的编码规则,每一个字节直接作为一个 UNICODE 字符。比如,[0xD6, 0xD0] 这两个字节,通过 iso-8859-1 转化为字符串时,将直接得到 [0x00D6, 0x00D0] 两个 UNICODE 字符,即 "ÖÐ"。

反之,将 UNICODE 字符串通过 iso-8859-1 转化为字节串时,只能正常转化 0~255 范围的字符。

ANSI 编码:

1. 编码标准:GB2312,BIG5,Shift_JIS,ISO-8859-2等

2. 说明:

把 UNICODE 字符串通过 ANSI 编码转化为“字节串”时,根据各自编码的规定,一个 UNICODE 字符可能转化成一个字节或多个字节。

反之,将字节串转化成字符串时,也可能多个字节转化成一个字符。比如,[0xD6, 0xD0] 这两个字节,通过 GB2312 转化为字符串时,将得到 [0x4E2D ] 一个字符,即 '中' 字。

“ANSI 编码”的特点:

1. 这些“ANSI 编码标准”都只能处理各自语言范围之内的 UNICODE 字符。

2. “UNICODE 字符”与“转换出来的字节”之间的关系是人为规定的。

UNICODE 编码:

1. 编码标准:UTF-8,UTF-16(BE),UTF-16(LE)等

2. 说明:

与“ANSI 编码”类似的,把字符串通过 UNICODE 编码转化成“字节串”时,一个 UNICODE 字符可能转化成一个字节或多个字节。

与“ANSI 编码”不同的是:

1. 这些“UNICODE 编码”能够处理所有的 UNICODE 字符。

2. “UNICODE 字符”与“转换出来的字节”之间是可以通过计算得到的。

 

--------------------------------UTF编码简介---------------------------------

UTF-8:

1. 对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。

2. 对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码

3. 一种变长的编码方案,使用 1~6 个字节来存储

Unicode符号范围 | UTF-8编码方式

(十六进制) | (二进制)

--------------------+------------------------------------------------------

0000 0000-0000 007F | 0xxxxxxx

0000 0080-0000 07FF | 110xxxxx 10xxxxxx

0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx

0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

0020 0000-03FF FFFF | 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

0400 0000-7FFF FFFF | 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

 

UTF-16:

1. 介于 UTF-8 和 UTF-32 之间,使用 2 个或者 4 个字节来存储,长度既固定又可变。

2. 对于 Unicode 编号范围在 0 ~ FFFF 之间的字符,UTF-16 使用两个字节存储,并且直接存储 Unicode 编号,不用进行编码转换

3. 对于 Unicode 编号范围在 10000~10FFFF 之间的字符,UTF-16 使用四个字节存储,具体来说就是:将字符编号的所有比特位分成两部分,较高的一些比特位用一个值介于 D800~DBFF 之间的双字节存储,较低的一些比特位(剩下的比特位)用一个值介于 DC00~DFFF 之间的双字节存储。

4. 位于 0xD800~0xDFFF 之间的 Unicode 编码是特别为四字节的 UTF-16 编码预留的,所以不应该在这个范围内指定任何字符,也就是该范围内在unicode里面不存在对应的unicode编码

5. UTF-16 要求在制定 Unicode 字符集时必须考虑到编码问题,所以真正的 Unicode 字符集也不是随意编排字符的

Unicode符号范围 | UTF-8编码方式

(十六进制) | (二进制)

---------------------+----------------------------------------------------------------------

0000 0000-0000 FFFF | (xxxxxxxx xxxx xxxxx) - (xxxxxxxx xxxxxxxx)

0001 0000-0010 FFFF | (yyyyyyyy yyxxxxxx xxxxxxxx xxxxxxxx) - (110110yy yyyyyyyy 110111xx xxxxxxxx)



UTF-32:

1. 一种固定长度的编码方案,不管字符编号大小,始终使用 4 个字节来存储

2. 以容纳所有的 Unicode 字符,所以直接存储 Unicode 编号即可,不需要任何编码转换。浪费了空间,提高了效率



----------------------名词解释-----------------------

unicode:

1. Unicode是为整合全世界的所有语言文字而诞生的。任何文字在Unicode中都对应一个值, 这个值称为代码点(code point)。代码点的值通常写成 U+ABCD 的格式。

2. Unicode是由美国主要计算机制造商联盟指定的编码字符集,主要用于克服在创建多语言程序和国际化软件时使用的不同编码字符集的混乱。 从版本1.1开始,Unicode严格保持与ISO / IEC 10646及其扩展兼容。 该联盟也是ISO工作的重要贡献者,以进一步发展ISO / IEC 10646

3. CJK就是中日韩的意思。Unicode为了节省码位,将中日韩三国语言中的文字统一编码

ucs-2 & ucs-4:

1. ucs全称是Universal Multiple-Octet Coded Character Set

2. UCS旨在可用于计算机系统和数据通信中的内部数据表示

3. 文字和代码点之间的对应关系就是UCS-2(Universal Character Set coded in 2 octets)。 顾名思义,UCS-2是用两个字节来表示代码点,其取值范围为 U+0000~U+FFFF。

为了能表示更多的文字,人们又提出了UCS-4,即用四个字节表示代码点。 它的范围为 U+00000000~U+7FFFFFFF,其中 U+00000000~U+0000FFFF和UCS-2是一样的。

4. ucs-4结构分为 group plane row cell,每一部分占用一个字节,其中当group和plane为00(16进制)时,是和ucs-2相对应

5. UTF-16是完全对应于UCS-2的

6. UCS-4最高位为0

BMP:

1. 基本多语言面板(Basic Multilingual Plane,简称 BMP)

2. UCS-2 = BMP = plane 00 of group 00



UTF:

1. UCS Transformation Format

2. UTF-8、UTF-16以及UTF-32都是UCS的具体实现,用来存储和传输以及表示

3. UTF-16保存的最小单位为2个字节,UTF-32保存的最小单位为4个字节,所以多字节的编码涉及到字节摆放顺序的问题(大小头)

BOM:

1. Byte Order Mark

2. 是用来标识字节顺序的,只存在于windows平台中,字节流开头的“FFFE”或者“FEFF”也被称为字符"ZERO WIDTH NO-BREAK SPACE"

3. windows平台下的UTF-8编码格式是默认会加上BOM,因为UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式,“FFFE”在UTF-8中的表示为“EF BB BF”(UTF-16的BOM是FEFF),所以如果收到以“EF BB BF”开头的字节流,则表明这是UTF-8编码

4. UTF-16或者UTF-32可以不含有BOM

Big Endian(BE) & Little Endian(LE):

1. ucs-2或者ucs-4中规定的码点在以UTF-16或者UTF-32表示的时候,字节存放顺序的2种

2. 表现为unicode编码的数据中的前2个字节为 "FF FE(Little Endian)",其中windows平台下的默认的Unicode编码为Little Endian的UTF-16

3. 例如“汉”字的Unicode编码是6C49。那么写到文件里时,究竟是将6C写在前面,还是将49写在前 面?如果将6C写在前面,就是Big Endian。如果将49写在前面,就是Little Endian

大端,高位存储在内存地址的低位

小端,低位存储在内存地址的低位

4. unix或者linux相关的平台使用无bom的utf8作为标准的原因是:一切皆文件,一切文件皆是流,一个流可以被任意的切断,独立解析,而不会改变含义。所以它不能有头,也不能有结尾。由于头根本不存在,所以bom不允许存在

5. windows平台使用带BOM的UTF-8编码的原因是:系统缺省都是用户当前代码页(code page),当前代码页不是utf8,这样,utf8作为非当前代码页格式就无法识别



ASCII:

1.美国(国家)信息交换标准(代)码(America Standard Code for Information Interchange)

2.ISO-8859-1是单字节编码,是以8位作为一个表示单元,相当于是ASCII的扩展,是完全兼容ASCII

3.Unicode只与ASCII兼容(更准确地说,是与ISO-8859-1兼容)

ANSI:

1. 美国国家标准协会(American National Standard Institite)

2. ANSI编码是指不同地区或者国家的编码标准,比如GB2312、GBK或者Big-5编码标准,一般都是使用2个字节来表示一个字符,但也有例外,比如GB18030编码标准中的一些汉字是用3个字节表示,不同的ANSI编码是互不兼容的

3. 在windows或者linux中存在内码页(code page)的概念,也就是不同的非unicode编码是存在不同的页的,比如GBK编码在CP936页,UTF-8的代码页是65001

4. 在操作系统内部,比如windows系列的内码就是Unicode编码,是以UTF-16来表示的,只要安装了对应的代码页,则可以正确显示出字符,记事本中选择ANSI编码保存则是使用系统缺省的编码格式存储数据,可以通过修改系统的地区来达到修改缺省的编码格式

5. 内码是指操作系统内部的字符编码,微软一般将缺省代码页指定的编码说成是内码,在确认了内码后,系统将按照当前的缺省代码页去解释文本文件里的字节流



GB2312:

1. 用两个数来编码汉字和中文符号。第一个数称为“区”,第二个数称为“位”。所以也称为区位码

2. GB2312的原文还是区位码,从区位码到内码,需要在高字节和低字节上分别加上A0

3. “啊”的区位码是1601,写成16进制是0x10,0x01。这和计算机广泛使用的ASCII编码冲突。为了兼容00-7f的ASCII编码,我们在区位码的高、低字节上分别加上A0。这样“啊”的编码就成为B0A1,我们将加过两个A0的编码也称为GB2312编码

(从区位码到内码需要在高、低字节上分别加上A0),但是GB2312的原文还是区位码

 



-----------------误解纠正-----------------------

误解:“ISO-8859-1 是国际编码?”

非也。iso-8859-1 只是单字节字符集中最简单的一种,也就是“字节编号”与“UNICODE 字符编号”一致的那种编码规则。当我们要把一个“字节串”转化成“字符串”,而又不知道它是哪一种 ANSI 编码时,先暂时地把“每一个字节”作为“一个字符”进行转化,不会造成信息丢失。然后再使用 bytes = string.getBytes("iso-8859-1") 的方法可恢复到原始的字节串。

误解:“Java 中,怎样知道某个字符串的内码?”

Java 中,字符串类 java.lang.String 处理的是 UNICODE 字符串,不是 ANSI 字符串。我们只需要把字符串作为“抽象的符号的串”来看待。因此不存在字符串的内码的问题。

当 UNICODE 被支持后,Java 中的 String 是以字符的“序号”来存储的,不是以“某种编码的字节”来存储的,因此已经不存在“字符串的编码”这个概念了。只有在“字符串”与“字节串”转化时,或者,将一个“字节串”当成一个 ANSI 字符串时,才有编码的概念。

用每“一个字节”就是“一个字符”的转化方法,实际上也就等同于采用 ISO-8859-1 进行转化。因此,我们常常使用 bytes = string.getBytes("iso-8859-1") 来进行逆向操作,得到原始的“字节串”。然后再使用正确的 ANSI 编码,比如 string = new String(bytes, "GB2312"),来得到正确的“UNICODE 字符串”。

 

-------------------------宽字符和窄字符(多字节字符)-------------------------------------

1. 有的编码方式采用 1~n 个字节存储,是变长的,例如 UTF-8、GB2312、GBK 等;如果一个字符使用了这种编码方式,我们就将它称为多字节字符,或者窄字符。

2. 有的编码方式是固定长度的,不管字符编号大小,始终采用 n 个字节存储,例如 UTF-32、UTF-16 等;如果一个字符使用了这种编码方式,我们就将它称为宽字符。

3. Unicode 字符集可以使用窄字符的方式存储,也可以使用宽字符的方式存储;GB2312、GBK、Shift-JIS 等国家编码一般都使用窄字符的方式存储;ASCII 只有一个字节,无所谓窄字符和宽字符。 

转载于:https://www.cnblogs.com/linusflow/p/10049961.html

更多相关:

  • 很多同学对于编码问题都不是很清楚,计算机常见的编码格式为: ASCII ISO-8859-1 GB2312 GBK UTF-8 UTF-16 对于Python开发中,我们一般都是采用统一的编码格式:UTF-8第一行加入环境申明: #coding=utf-8 编码操作方式一般都分为:编码(encode)和解码(decode) 但是对于...

  • 函数近似方法7.1 目标预测(VE‾overline{VE}VE)7.2 随机梯度下降和半梯度下降例7.1: 1000态随机行走的状态收敛7.3 线性近似7.4 线性方法的特征构造7.4.1 Coarse Coding(粗编码)例7.2:粗编码的粗度7.4.2 Tile Coding(瓦片编码)7.4.3 实例:Tile Codin...

  • 1,Ascii和ebcic. 为了方便交流,美国人发明了ASCII编码,后来被确认为国际标准。后来以发明了EBCDIC编码。 一般地说,开放的操作系统(LINUX 、WINDOWS等)采用ASCII 编码,而大型主机系统(MVS 、OS/390等)采用EBCDIC 编码。在发送数据给对方前,需要事先告知对方自己所使用的编码,或者通过...

  • Unicode字符集中收录110多万个字符集合。UTF-8(8-bit Unicode Transformation Format),是一种针对 Unicode 的可变长度字符编码方式。使用一到四个字节来编码 Unicode 字符 在计算机内存中统一使用Unicode编码,当需要保存到硬盘或者需要传输时,转换为UTF—8编码。 字符...

  • 字节串bytes字节串也叫字节序列,是不可变的序列,存储以字节为单位的数据字节串表示方法:b"ABCD"b"x41x42"...字节串的构造函数:bytes() 创建一个空的字节串 ,同b””bytes(整数可迭代对象) 用可迭代对象创建一个字节串bytes(整数n) 生成n个值为0的字节串bytes(字符串,encoding='...

  • Unicode编码  最初的unicode编码是固定长度的,16位,也就是2两个字节代表一个字符,这样一共可以表示65536个字符。显然,这样要表示各种语言中所有的字符是远远不够的。Unicode4.0规范考虑到了这种情况,定义了一组附加字符编码,附加字符编码采用2个16位来表示,这样最多可以定义1048576个附加字符。所以4个字节...

  • Java IO流学习总结三:缓冲流-BufferedInputStream、BufferedOutputStream 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/54894451 本文出自【赵彦军的博客】 InputStream |__FilterInputSt...

  •   一直对编码这块晕晕乎乎,今天终于看到一篇写的很清楚也很风趣的文章,转过来mark一下。 很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物。他们看到8个开关状态是好的,于是他们把这称为”字节“。再后来,他们又做了一些可以处理这些字节的机器,机器开动了,可以用字节来组合出很多状态,状态开始...

  • 我们知道在由于大端机和小端机导致网络字节序和主机序有可能是有差异的,我们可以使用系统的ntohs,ntohl,htons和htonl这些处理函数进行转换,下面是我写的一个关于ntohs在处理小端机字节序转换的函数的简单实现. 思想大致如下: 用u_int16_t的2字节16位的整形变量来存储这个整数,首先将第一个字节和该变量进行或运算...

  • 1. 三字母词 在C语言中有一种三字母词的说法,trigraph sequences,目前为止有九种三字母词,如下 ??=               #                  ??)            ]                  ??!           |         ??(      ...

  • 题目:   请你来实现一个 atoi 函数,使其能将字符串转换成整数。   首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。   当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与之后连续的数字字符组...

  • 联考考试考到了这个题,随机化40分,现在来秒掉它吧。   题意: 给一个字符串,求其中的一段,使得出现次数最多的字符与出现次数最少的字符的出现次数之差最大。 输入输出样例 输入样例#1: 复制 10 aabbaaabab 输出样例#1: 复制 3   我们定义$cnt[i][j]$表示区间$[1,i]$中,j出现的次数, 定义...

  • 本推文主要识别的验证码是这种:第一步: 二值化所谓二值化就是把不需要的信息通通去除,比如背景,干扰线,干扰像素等等,只剩下需要识别的文字,让图片变成2进制点阵。第二步: 文字分割为了能识别出字符,需要对要识别的文字图图片进行分割,把每个字符作为单独的一个图片看待。第三步: 标准化对于部分特殊的验证码,需要对分割后的图片进行标准化处理,...

  •   源字符串: a a 1 ~`!@#$%^&()_+-={}[];',.- + 编码后: a%20a%201%20~%60%21@%23$%25%5E&%28%29_+-=%7B%7D%5B%5D;%27,.-%20+   源字符串: 变 ~!@#¥%…………&()——+=-·{}:“;‘、《》?,。、-+A a 1 编码后:...