比特 bit 字节 byte ASCII码 Unicode UTF 32 UTF 8 傻傻分不清楚

比特 bit 字节 byte ASCII码 Unicode UTF 32 UTF 8 傻傻分不清楚


"1个字节是8个比特,1个字母是1个字节,1个汉字是2个字节"

  • 上面这句话很多人都看过听过
  • 但大部分人都不知道为什么 (例如前两天的我)
  • 这句话在某些规定下其实是不正确的

bit

  • 中文:比特
  • 表示0或1
  • 计算机中最小的单位

byte

  • 中文:字节
  • 1byte==8bit 表示8个比特(为什么不是2个或者4个 后面解答)

插一句 比特币 字节跳动 名字取的真好

ASCII码

  • 美国制定的一套让计算机识别、保存、读取字符的标准
  • 字符定义: 数字'7' 字母'a' 操作字符(删除 确定)
  • 一共有128个字符 每个字符都有唯一的编码 查看ascii.pdf
  • 计算机中最小的单位是比特所以我们用比特来存储
  • 那么需要多少个比特来存一个字符呢?
    • 2比特 最多保存 4个数据 00 01 10 11
    • 4比特 最多保存16个数据 0000 0001 0010 0011 ...... 1111
    • 7比特 最多保存128个数据 0000000 0000001 0000010 0000011 ...... 1111111
    • 8比特 最多保存255个数据 00000000 00000001 00000010 00000011 ...... 11111111
  • 其实7bit就可以保存128个字符 但是最后还是用8比特 因为当时用第八位来作为奇偶校验位(奇偶校验位现在没用)
  • byte的概念最早是用来表示一个"字" 也就是char 最后通俗约定 8bit表示1byte
  • 例外:GSM默认采用7bit编码

GB2312编码 GBK编码 GB18030编码 XXXX编码

  • 如果全世界都用英语那ASCII码也够用了
  • 但中国 日本 韩国 也想用计算机显示自己国家的文字
  • 所以中国制定了GB2312 日文制定了Shift_JIS 韩文制定了EUC_KR
  • 每个国家都制定了自己的编码 一般都用2~4字节来表示一个文字

Unicode字符集

  • 每个国家的编码不一样导致很容易产生乱码
  • 如何让所以国家都用一个表来确定字符的编号(学名为码位 / 码点 / Code Point)
  • Unicode就孕育出生了(统一码、万国码、单一码)
  • Unicode准备了1114112个编号来存放世界上所有的文字
  • 1114112 二进制为 10001 00000000 00000000 20bit
  • 2020年3月10日发布了最新的Unicode®13.0.0.pdf

UTF-32 (或 UCS-4)编码

  • 规定每个字符都以4byte(32bit)去存储 读取 传输
  • 优点
    • 快速获取字符数量
    • 快速获取数据中的指定字符
  • 缺点
    • 本来1byte(4bit)就能保存的数据都需要用4byte(32bit) 来保存很浪费容量
    • 存储 读取 传输慢

UTF-8编码

  • 使用1~4个byte确定一个字符

  • UTF-8编码划分Unicode字符集为四个区间

十进制 二进制
0-177 (00000000 00000000 00000000 00000000)-(00000000 00000000 00000000 01111111)
178-2047 (00000000 00000000 00000000 11111111)-(00000000 00000000 01111111 11111111)
2048-65535 (00000000 00000000 11111111 11111111)-(00000000 01111111 11111111 11111111)
65536-1114111 (00000000 11111111 11111111 11111111)-(01111111 11111111 11111111 11111111)
  • 四个区间分别对应四个公式
公式
0xxxxxx
110xxxxx 10xxxxxx
1110xxxx 10xxxxxx 10xxxxxx
11110xxx 10xxxxxx 10xxxxxx
  • 例如
字符 十进制 二进制 属于区间
z 122 01111010 1
37049 10010000 10111001 3
  • 字符 'z' 属于第一区间 套用第一个公式
    • 使用 'z' 的二进制 01111010 从右到左依次填入0xxxxxx
    • 最终得 'z' 的 UTF-8码 为 01111010
  • 字符 '邹' 属于第三区间 套用第三个公式
    • 使用 '邹' 的二进制 10010000 10111001 从右到左依次填入 1110xxxx 10xxxxxx 10xxxxxx
    • 最终得 '邹' 得 UTF-8码 为 11101001 10000010 10111001
  • 优点
    • 兼容ASCII码
    • 保存 读取 传输 低于178范围的字符只需要一个byte(4bit)
    • 根据字符的二进制前有多少个1可以确定一个字符的长度
  • 缺点
    • 不能直接获取数据包含多少个字符
    • 不能直接定位某个字符的二进制位置

总结

  • 1个汉字是2个字节 在UTF-8编码规则下错误的
  • 以上都是个人见解
  • 如有错漏之处敬请指正

Github:https://github.com/QiangZou

博客:https://www.cnblogs.com/zouqiang/

posted @ 2020-04-03 19:52  邹强  阅读(1374)  评论(0编辑  收藏  举报