最近准备把常用的密码学相关的一些算法都过一遍,先从最简单的 Hex 编码开始吧!
在我自己学习的过程中,看过别人的文章,自己也看过源码,发现有些文章的介绍是有问题的。
所以我这里会讲的更细致一些,尽量通俗易懂,但我也不会像讲计算机基础那样,细枝末节的知识就略过了。
计算机存储数据,大部分时候都是以字节为单位的,我们这里称为 1Byte。
但是实际上 1Byte 还可以分的更细,即分为 8 个 bit 位。
bit 位应该大家都熟悉了,1bit 只能存储 0 或者 1, 那么 8bit 能存储数据的范围就是 0000'0000~1111'1111 ,转换成 10 进制就是 0~255,至于是带不带符号,我们这里不关心的,因为编码的时候只管这 8bit 里的 2 进制值。
另外有个地方很多人会混淆的,就是 1Byte 存储数值和存储字符的时候,底层实际的值是不一样的(很多讲 Hex 的文章这一块都讲错了,这些文章没有把数值和字符做区分)。
比如存储数值 1 的时候,1Byte 中的 8 bit 值是 0000'0001,存储字符 "1" 的时候,1Byte 中的 8 bit 值是 0011'0001。
Hex 编码是将数据转换成符合 Intel Hex 文件格式的一种编码方式。
Hex 编码的最小单位是 1Byte 也即 8 个 bit 位。
Hex编码的时候,先取高 4 位 1110 转成十六进制的 e ,然后去寻找字符 "e" 对应的 ascii 码,即为 0110'0101。再取低 4 位 0010 转成十六进制的 2 ,然后去寻找字符 "2" 对应的 ascii 码,即为 0011'0010。最终转换后的数据是 0110'0101 0011'0010。按照字符串显示就是 e2。
Go语言实现的代码如下:
package main
import (
"encoding/hex"
"fmt"
)
func main() {
data := make([]byte, 1, 1)
//这里 data 存放的是真实的数值
data[0] = 226
fmt.Println(data)
//调用 Go 自带的 hex 库来进行编码
res := hex.EncodeToString(data)
fmt.Println(res)
}
Hex编码的时候,先取高 4 位 0110 转成十六进制的 6 ,然后去寻找字符 "6" 对应的 ascii 码,即为 0011'0110,再取低 4 位 0111 转成十六进制的 7 ,然后去寻找字符 "7" 对应的 ascii 码,即为 0011'0111, 最终转换后的数据是 0011'0110 0011'0111,按照字符串显示就是 67。
Go语言实现的代码如下:
package main
import (
"encoding/hex"
"fmt"
)
func main() {
data := make([]byte, 1, 1)
//这里 data 存放的是字符
data[0] = 'g'
fmt.Println(data)
//调用 Go 自带的 hex 库来进行编码
res := hex.EncodeToString(data)
fmt.Println(res)
}
你学废了么?