zoukankan      html  css  js  c++  java
  • 比特 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/

  • 相关阅读:
    为Qtcreator 编译的程序添加管理员权限
    热备,冷备,云备
    最近面试java后端开发的感受:如果就以平时项目经验来面试,通过估计很难——再论面试前的准备
    进入2012 -- 回顾我走过的编程之路
    为什么中国程序员水平一直上不了层次?无非是这些原因!
    我是如何失去团队掌控的?
    后端开发甩锅奥义
    一个线程oom,进程里其他线程还能运行吗?
    架构师必备,带你弄清混乱的JAVA日志体系!
    IDEA一定要改的八条配置
  • 原文地址:https://www.cnblogs.com/zouqiang/p/12628602.html
Copyright © 2011-2022 走看看