zoukankan      html  css  js  c++  java
  • 【深入编码本质】浅谈编码Base64、Hex、UTF-8、Unicode、GBK等

    前言:

      网络上大多精彩的回答,该随笔用作自我总结;

      首先计算机只认得二进制,0和1,所以我们现在看到的字都是经过二进制数据编码后的;计算机能针对0和1的组合做很多事情,这些规则都是人定义的;然后有了字节的概念,8比特一个字节,如01011100就是一个字节;

      人定义好计算机的0和1的数据结构做事的时候,如果每个人都用不同的数据结构,不同的定义,就会使得人和人之间让计算机做的事无法统一,也导致无法通讯,所以要一起共同定义一套大家都认同的规则,其中ASCii码就是最初始的交换码,用做记录信息、交互信息的;

      相同的字节串不同的编码就会有不同的展示,只有正确的编码才能表达出字符串本身要记载的信息,而信息是面向人的,只有人能识别,才叫信息,只是偶尔被计算机理解;

    字节、字符与字符串:

      字节是8比特位构成,上传已经说了;

      字符是用字节构成的,但多少字节,怎么构成我们认识的唯一的字符?这个由编码格式决定,也就是Unicode、GBK,(为啥要用字节?,因为历史觉得8比特很牛逼啊)

      字符串是字符的序列,各种计算机语言不同表示,如Redis就和C的字符串不一样,C是以 ‘’ 结尾;我们说的对字符的编码,而不是字符串;

    Hex用字符串形式看二进制代码:

      首先,二进制文件通常不易于人看,因为人会看眼花,所以必须转为其他进制,16进制是最好的,刚好2字符表示一个字节

      Hex编码是以4比特作为一个单位编码,用4是因为计算机进位是2的倍数,而为了能把比特串分割开来,最适中就是取16进制;所以Hex编码就是16进制编码;用于人类比用比特更直观简介的方式看待比特串(马上反应过来比特串),当然取更多位不适合人口算;

      然后我们就有了WinHex这个工具的命名;用它修复二进制文件很不错,前提你对该文件二进制构表(一般是具有协议去解析二进制的,我称之为构表协议吧)很熟;

      Base64是面向网络的,其实性质也是这样;

    Unicode、GBK都是字符串编码:

      看到知乎一个alipay的说啥编码和编码格式不同,gbk是unicode的编码格式,简直笑死人;

      Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。目前的Unicode字符分为17组编排,0x0000 至 0x10FFFF,每组称为平面(Plane),而每平面拥有65536个码位,共1114112个,但是码表和字符串的映射可以用数字表示,高位填0,但编码的方案确实可以多种的,例如如果码数1,用2字节就是:0x0001,需要传输2字节;但有必要吗?明显是没必要的!

      重复一遍,字符是独一无二的,人类符号系统抽象的产物,世界唯一,全世界的字符构成字符集,字符也是在演进的;而Unicode和GBK等都是字符的一种编码;也就是一个二进制比特串(数字)和字符的映射表;

    面向字符、面向字节

      对于一个抽象字符,在Java中的二进制表示当然需要编码,用的就是Unicode,如果源文件存储并非Unicode怎么办呢?当然需要转换,因此Java很多面向字符流的I/O其实都是默认有转换规则存在;

      这里提下I/O都分面向字节和字符,其实面向字节就是不管编码,而面向字符是带编码转换,是的一个抽象字符串如 “饭” 是在哪种编码格式都表示 “饭”,因此面向字符I/O指定编码格式很重要,一般不指定采用默认,如win操作系统默认GBK,而linux默认UTF-8;

    UTF-8是编码规则 — 哈夫曼编码:

      Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。目前的Unicode字符分为17组编排,0x0000 至 0x10FFFF,每组称为平面(Plane),而每平面拥有65536个码位,共1114112个,谨记;

      所以我们上面提到了,其实0x0001是没有必要用2个字节表示的,其实我用一个字节也可以的,那么什么情况下可以做到,在读一个2个字节表示的字符时候,我就读比特串中的2个字节位呢;所以比特串中,就需要有前几位代表,到底需要读几位;

      哈夫曼编码转换的

        Unicode

      UTF-8

      范围:0000 - 007F  前缀:0xxxxxxx

      范围:0080 - 07FF  前缀:110xxxxx 10xxxxxx

      范围:0800 - FFFF  前缀:1110xxxx 10xxxxxx 10xxxxx

      所以UTF-16也是一种编码规则,他们各自有各自的好处,主要体现在空间的节省上,如果文档的大部分字符串都是英文,那么用UTF-8会比较好,而如果大部分都是中文,则UTF-16会更节省空间。

  • 相关阅读:
    数据库分库分表之后,你是如何解决事务问题?
    数据库周刊31丨openGauss 正式开源;7月数据库排行榜发布;浙江移动国产数据库AntDB迁移;oracle ADG跨版本搭建;PG解决社保问题;mysqlbinlog解析……
    2020年7月国产数据库排行:华为、腾讯发新品,中兴、阿里结硕果
    47%的MongoDB数据库遭黑客比特币勒索,你中招了吗?中招怎么办?
    数据库周刊30丨数据安全法草案将亮相;2020数据库产业报告;云南电网上线达梦;达梦7误删Redo Log;Oracle存储过程性能瓶颈;易鲸捷实践案例……
    数据库周刊29│2020数据库研究报告;Oracle取消今年技术大会;腾讯云DBbridge发布支持一键迁库;饿了么迁至阿里云;PG数组查询;Oracle被比特币勒索;DM8 安全管理…
    数据库周刊28│开发者最喜爱的数据库是什么?阿里云脱口秀聊程序员转型;MySQL update误操作;PG流复制踩坑;PG异机归档;MySQL架构选型;Oracle技能表;Oracle文件损坏处理……
    怎么查看HBase表的创建时间
    Hadoop/HBase Kerberos认证失败:Clock skew too great
    java线程莫名异常退出时,如何捕获异常信息
  • 原文地址:https://www.cnblogs.com/iCanhua/p/8929988.html
Copyright © 2011-2022 走看看