php基础篇 不懂 bit,byte,字符、编码之间的关系,别跟我说你会sock网络编程!
bit(位)
数据存储的最小单位。每个
二进制
数字0或者1就是1个位;
byte(字节)
64位系统:8个位构成一个字节;即:1 byte (字节)= 8 bit(位);
32位系统:4个位构成一个字节;即:1 byte (字节)= 4 bit(位);
储存空间换算
1 byte = 1 bit (位)
1 KB = 1024 B(字节);
1 MB = 1024 KB; (2^10 B)
1 GB = 1024 MB; (2^20 B)
1 TB = 1024 GB; (2^30 B)
字符
a-z,A-Z、符号,0-9…均表示一个字符;
一般 utf-8 编码下,一个汉字 字符 占用 3 个 字节;
var_dump(strlen(mb_convert_encoding('大雷编程','UTF-8')));
一般 gbk 编码下,一个汉字 字符 占用 2 个 字节;
var_dump(strlen(mb_convert_encoding('大雷编程','GBK')));
要测试其他编码中文占用的字节也可以使用上面的方法。
编码
基本概念
1.字符编码(Character Encoding)是什么?
是一套法则,使用该法则能够对自然语言的字符的一个集合(如字母表),与其他东西的一个集合(如二进制字节码)进行配对。即在符号集合与数字系统之间建立对应关系,它是信息处理的一项基本技术。通常人们用符号集合(一般情况下就是文字)来表达信息。而以计算机为基础的信息处理系统则是利用元件(硬件)不同状态的组合来存储和处理信息的。元件不同状态的组合能代表数字系统的数字,因此字符编码就是将符号转换为计算机可以接受的数字系统的数,称为数字代码。
- 单字节编码是什么?
一个字节就表示一个字符,比如典型的ASCII码中的所有字符都是单字节编码的
- 双字节编码是什么?
需要用两个字节来表示一个字符的编码,比如汉字的GBK,GB2312编码
- 多字节编码是什么?
需要用多个字节来表示一个字符的编码,比如Unicode,UTF-8编码
字符集
字符集(Charset):是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。
ASCii
-
标准 ASCii 字符集:有96个打印字符,和32个控制字符组成;一共96+32=128个;
-
用7位二进制数来对每1个字符进行编码;
-
而由于7位还还不够1个字节,而电脑的内部常用字节来用处理,每个字节中多出来的最高位用0替代;
二进制 | 十进制 | ASCII |
---|---|---|
0 000 0000 | 0 | NUL (NULL) |
0 100 0001 | 65 | A |
0 110 0001 | 97 | a |
0 111 1111 | 127 | DEL (Delete) |
- 从0----127,来表示128个ACSii编码;
- 注意:
10
在计算器内部是没有编码的,因为它是字符串,而不是单个字符。可以分别对1
,0
字符编码存储;
扩展ASCii字符集
-
将标准的ASCii最高位由0替换为1,得到十进制代码128—255(1 000 0000----1 111 1111);
-
所以字符集一共有0—255, 也就是256个字符;
-
ASCII标准字符集是由低7位编码组成,字符集只能组合成128个字符,为了表示更多的欧洲常用字符对,IBM对ASCII码进行了扩展,把第八位也用上了,数量也翻了一位,可达到256字符。
-
扩展部分由80H到0FFH组成共128个字符,一般称为"扩充字符",这128个扩充字符是由IBM制定的,并非标准的ASCII码.这些字符是用来表示框线、音标和其它欧洲非英语系的字母。
gb2312字符集
-
所有汉字字符在计算机内部采用2个字节来表示,每个字节的最高位规定为1【正好与标准ASCii字符(最高位是0)不重叠,并兼容】,不支持繁体字;
-
GB2312编码是第一个汉字编码国家标准,由中国国家标准总局1980年发布,1981年5月1日开始使用。GB2312编码共收录汉字6763个,用两个大于127的字符连在一起时,就表示一个汉字,前面的一个字节(他称之为高字节)从0xA1用到 0xF7,后面一个字节(低字节)从0xA1到0xFE,这样我们就可以组合出大约7000多个简体汉字了。在这些编码里,还把数学符号、罗马希腊的字母、日文的假名们都编进去了,连在ASCII里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的
全角
字符,而原来在127号以下的那些就叫半角
字符了。 -
gb2312表示汉字的编码为:[129–255][129–255] (两个字节,每个字节最高位是1);小于127的字符,与ASCii编码相同;
gbk字符集
- gb2312的扩充,兼容gb2312,除了收录gb2312所有的字符外,还收录了其他不常见的汉字、繁体字等;
- gbk中字符是一个或两个字节,单字节字符
00--7F(0---127)
这个区间和ASCII是一样的; - 双字节字符的第一个字节是在
81--FE(129--254)
之间。通过这个可以判断是单字节还是双字节; - 即在gbk字符编码,如果第一个字节是
>128
的,则再往后找一个字节,组成汉字;如果第一个字节<128
,则表示的是一个单字节(此时和ASCII是一样的); - GBK、GB2312编码:是将两个字节连在一起表示一个字符,这两个字节分别叫高字节和低字节,GBK的编码中只要高字节代表的字符大于127就表示该字符为汉字,GB2312编码中必须两个字节所标识的字符都大于127才标识这个字符为汉字。
Unicode字符集
- Unicode 是基于通用字符集,它是用4个字节来表示一个字符,所以能把目前世界上所有的语言文字字符都表示出来;(以及对应的二进制数字);
- Unicode只是一个编码规范,目前实际实现的unicode编码只要有三种:
UTF-8
,UCS-2
和UTF-16
,三种unicode字符集之间可以按照规范进行转换。 - 由于Unicode字符编码用4个字节表示一个字符会浪费很多空间,所以UTF-8编码采用一种变长编码规则,如一个英文字母a,只需要一个字节就可以,那么UTF-8编码中a还用一个字节,有些字符需要4个字节才能表示出来,就用4个字节来表示。注意在UTF-8编码中汉字是需要3个字节来表示的。
utf-8编码
- UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,也是一种前缀码。它可以用来表示Unicode标准中的任何字符,且其编码中的第一个字节仍与ASCII兼容,这使得原来处理ASCII字符的软件无须或只须做少部分修改,即可继续使用。因此,它逐渐成为电子邮件、网页及其他存储或发送文字的应用中,优先采用的编码。
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 |
- 对于UTF-8编码中的任意字节B,如果B的第一位为0,则B独立的表示一个字符(ASCII码);
- 如果B的第一位为1,第二位为0,则B为一个多字节字符中的一个字节(非ASCII字符);
- 如果B的前两位为1,第三位为0,则B为两个字节表示的字符中的第一个字节;
- 如果B的前三位为1,第四位为0,则B为三个字节表示的字符中的第一个字节;
- 如果B的前四位为1,第五位为0,则B为四个字节表示的字符中的第一个字节;
- 因此,对UTF-8编码中的任意字节,根据第一位,可判断是否为ASCII字符;根据前二位,可判断该字节是否为一个字符编码的第一个字节;根据前四位(如果前两位均为1),可确定该字节为字符编码的第一个字节,并且可判断对应的字符由几个字节表示;根据前五位(如果前四位为1),可判断编码是否有错误或数据传输过程中是否有错误。
即:
- 单字节的字符,字节的第一位设为0,对于英语文本,UTF-8码只占用一个字节,和ASCII码完全相同;
- n个字节的字符(n>1),第一字节的前n位设为1,第n+1位设为0,后面字节的前两位都设为10;
- 2个字节,第一个字节的前2位是1;3个字节,第一个字节的前三位是1; 4个字节,第一个字节的前4位都是1;