计算机是如何存数据的

请看最后的结论

第一步(内存)如何存0和1

实际就是晶体管里的电信号

  • 1就充电
  • 0就不充电

读取

  • 电量大于50%就是1
  • 电量小于50%就是0

第二步 如何存数字

十进制转二进制 (十进制)37 ==》(二进制)100101

计算机只存0和1

第三步 存字符

ASCⅡ码

  • 如果存 a 那么a对应的asc码就是 97
  • 而97对应的二进制就是0110 0001

第四步 存中文

GB2312 国标码 共收录6763个常用字

后来为了存储生僻字、繁体字、日语、韩语等微软推出了GBK

第五步 如何存储所有字符

Unicode 将全球所有字符编号

2016年6月总共存有12万个字符

第六步 如何将Unicode存到计算机里

变长存储有可能一个字节有可能三个字节

低性价比

a > 00000000 00000000 00000000 01100001 = 0061
你 > 00000000 00000000 01001111 01100000 = 4F60

高性价比 UTF-8

a > 01100001
你 > 11100100 10111101 10100000

utf-8的原理

  1. if 你表示的数字小于七位

    1
    0XXX XXXX
  1. else if 你的数字大于七位加4位 也就是11位,前面110代表占用两字节的空间

    1
    110XXXXX 10XXXXXX
  2. else if 表示两个字节,前面1110代表占用三字节的空间

    1
    1110XXXX 10XXXXXX 10XXXXXX  所有X位加一起16位 两个字节就可以表示所有的汉字
  3. else 11110代表占用四个字节的空间

    1
    11110XXX 10XXXXXX 10XXXXXX 10XXXXXX

规律就是你由几个字节组成 最左面的冗余信息就是用来表示你占用几个字节

你实际占用两个字节就是11,三个字节就是111 四个字节就是1111

UTF-8是一种编码方式,不是字符集

现实问题(这些字符集的发明时间)

  • 1981年 GB2312
  • 1993年 GB13000 unicode 1.1
  • 1993 -1999 GBK
  • 1995年 js诞生的时候 unicode3还没有出来
  • 1999年 Unicode3.0
  • 2000年 GB18030 兼容GBK并扩展

现在开发网站一定要使用UTF-8

现实问题2

JS使用了Unicode字符集,但是没有使用UTF-8

JS用的UCS-2编码(已经没人使用的编码)最多表示2个字节的汉字
因为1995年UTF-16还没有发明,JS也不想使用UTF-32

1
'\u4f60'  //代表 '你' 这是unicode

后果

ES5无法表示\uFFFF之后的字符,也就是大于2个字节的(如\u1D306)某些情况会出bug

1
2
3
var str = '\u1D306'  
str.length ? //2
//js会把 1D30看成一个字符 6是另一个字符

但是HTML支持utf-8

1
2
3
4
<h1 id="xxx">&#x1d306;</h1> 

xxx.innerText.length = ? //2
// 显示的是一个字符,但是JS取出来的长度却是 2 这就是 JS在ES5之前编码上的bug