哈希
哈希(Hash)也称为散列,是把任意长度的输入通过哈希算法变换为固定长度的输出,这个输出值也就是散列值。
哈希表是根据键值对(key value)而直接进行访问的数据结构,通过将键值对映射到表中一个位置来访问记录,以加快查询速度。映射函数又称为散列函数,存放记录的数组叫做哈希表。
如果两个输入串的哈希函数的值相同则发生了碰撞(Collision),既然把任意较长字符串转化为固定长度且较短的字符串,因此必有一个输出串对应多个输入串,碰撞是必然存在的。这种碰撞又称为哈希冲突。
散列函数
哈希算法是一种广义的算法,也可以认为是一种思想,使用哈希算法可提高存储空间的利用率和数据查询效率。
- 哈希函数又称为散列函数,采用散列算法。
- 哈希函数是一种从任何一种数据中创建小的数字“指纹”的方法。
- 哈希函数将数据打乱混合,重新创建一个叫做散列值的“指纹”。
- 哈希函数会将消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来。
接口
- Golang的
hash
包提供多种散列算法,比如crc32/64
、adler32
、fnv
...
type Hash interface{
io.Writer //嵌入io.Writer接口,向执行中的hash加入更多数据。
Sum(b []byte) []byte//将当前hash追加到字节数组b后面,不会改变当前hash状态。
Reset()//重置hash到初始化状态
Size() int//返回hash结果返回的字节数
BlockSize() int//返回hash的集成块大小,为提高效率,Write方法传入的字节数最好是block size的倍数。
}
MD5
MD5消息摘要算法,是一种被广泛使用的密码散列函数,可以产出一个128位(16子节)的散列值。
MD5已被证实无法防止碰撞,已经不算是很安全的算法,因此不适用于安全性认证,比如SSL公开密钥认证或数字签名等用途。
对于需要高度安全性的数据,一般建议改用其他算法,比如SHA256。
input := "123456"
hash := md5.New() //创建散列值
n, err := hash.Write([]byte(input)) //写入待处理字节
if err != nil {
fmt.Println(err, n)
os.Exit(-1)
}
//bytes := hash.Sum([]byte(""))
bytes := hash.Sum(nil) //获取最终散列值的字符切片
fmt.Printf("%v\n", bytes)
//[225 10 220 57 73 186 89 171 190 86 224 87 242 15 136 62]
fmt.Printf("%x\n", bytes) //以16进制字符串格式化字符切片
//e10adc3949ba59abbe56e057f20f883e
MD5和SHA256是非常常用的两种单向散列函数
import (
"crypto/md5"
"encoding/hex"
"testing"
)
func MD5(input string) string {
c := md5.New()
c.Write([]byte(input))
bytes := c.Sum(nil)
return hex.EncodeToString(bytes)
}
SHA-1
SHA1全称Secure Hash Algorithm 1安全散列算法1,是一种密码散列函数,由美国国家安全局设计,并由美国国家标准技术研究所NIST发布为联邦数据处理标准FIPS。
1993年发布SHA0,1995年发布了SHA1。其设计原理类似于MIT教授Ronald L.Rivest所设计的密码学散列算法MD4和MD5。
SHA1可以生成一个被称为消息摘要的160位20字节的散列值,散列值呈现形式为40个十六进制数,主要适用于数字签名标准(Digital Signature Standard, DSS)里面定义的数字签名算法(Digital Signature Algorithm, DSA)。
类别 | 消息长度 | 分组长度 | 计算字长 | 计算步骤 | 消息摘要长度 |
---|---|---|---|---|---|
SHA-1 | 小于2^64位 | 512 | 32 | 80 | 160 |
password := "123456"
ins := sha1.New()
ins.Write([]byte(password))
result := ins.Sum([]byte(""))
fmt.Printf("%x\n", result)
//7c4a8d09ca3762af61e59520943dc26494f8941b
import (
"crypto/sha1"
"encoding/hex"
"testing"
)
func SHA1(input string) string {
c := sha1.New()
c.Write([]byte(input))
bytes := c.Sum(nil)
return hex.EncodeToString(bytes)
}
CRC32
- CRC即Cyclic Redundancy Check循环冗余校验码
- CRC是实现32位循环冗余校验或CRC-32校验和
在远距离数据通信中,为确保高效而无差错地传送数据,必须对数据进行校验即差错控制。
CRC(Cyclic Redundancy Check/Code)循环冗余校验是对一个传送数据块进行校验,是一种高效的差错控制方法。
ChecksumIEEE使用IEEE多项式返回数据的CRC-32校验和
func ChecksumIEEE(data []byte) uint32
例如:
package test
import (
"hash/crc32"
"testing"
)
func CRC32(input string) uint32 {
bytes := []byte(input)
return crc32.ChecksumIEEE(bytes)
}
func TestHash(t *testing.T) {
input := "123456"
t.Log(CRC32(input)) //158520161
}
有疑问加站长微信联系(非本文作者)