简析多种编码方式(Hex, Base64, UTF-8)

简析多种编码方式(Hex, Base64, UTF-8)

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

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

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

 

字节、字符与字符串:

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

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

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

 

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

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

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

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

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

 

Unicode、GBK都是字符串编码:

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

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

 

Java内部是Unicode默认,以及其面向字符、面向字节

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

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

 

UTF-8和Unicode是哈夫曼编码:

  自己去查一下吧,是哈夫曼编码转换的

    Unicode

  UTF-8

    待补

 

Hex编码的编码原理:

* Hex编码的原理就是将原来8位的二进制字节打断,分成两个4位的,并且在前面加上4个零,
* 进行补位这样一个8位二进制字节就变成了2个8位的二进制字节,在将新得到的2个二进制字符进行16位进制转换
* 得到的新的16位字符串就是Hex的值,所以 二进制的[72, 69, 88]  《hex》 484558是相等的。
* [72, 69, 88]byte数组的二进制=‭01001000‬ ‭01000101‬ ‭01011000‬
* 二进制=‭01001000‬ ‭01000101‬ ‭01011000‬ 进行hex的打断操作 ‭0100 1000‬ ‭0100 0101‬ ‭0101 1000
* 在加上前面的4个零得到一个新的6个8位二进制 = 0000‭0100 00001000 ‬0000‭0100 00000101‬ 0000‭0101 00001000
* 新的6个8位二进制 进行16进制转换 0000‭0100 00001000 ‬0000‭0100 00000101‬ 0000‭0101 00001000 = 484558
* 总结所以说Hex编码后的二进制长度变为了原来的2倍,所以字节长度增加了一倍。
 

Hex的编码过程

字符串:                    HEX
ASCII码:                  [72,69,88]
二进制码:                  ‭01001000‬ ‭01000101‬ ‭01011000‬
重新分组:                  0100 1000 0100 0101 0101 1000
高位补零后的二进制码:       00000100 00001000 00000100 00000101 00000101 00001000
十六进制码:                       4        8        4        5        5        8
Hex码:                    484558

 

Java 代码实现

package com.gl.test;
 
import org.apache.commons.codec.binary.Hex;
 
import java.util.Arrays;
 
public class TestHex {
 
    public static void main(String[] args) {
    
        //一个字符串
        String hex = "HEX";
        //获取字符串的byte数组
        byte[] buf = hex.getBytes();
        //输出byte数组
        System.out.println(Arrays.toString(buf));
        //转换成Hex输出
        System.out.println(Hex.encodeHexString(buf));
    }
}

maven 依赖

 <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.10</version>
        </dependency>

 

    原文作者:smilejiasmile
    原文地址: https://blog.csdn.net/smilejiasmile/article/details/96311277
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞