常见哈希函数FNV和MD5

Bryce · · 8577 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

介绍哈希函数之前,先说一下Golang的哈希结果。在包/hash/下的hash.go文件,定义了哈希函数的接口。所有哈希函数都要实现此接口。

// Hash is the common interface implemented by all hash functions.
type Hash interface {
	// Write (via the embedded io.Writer interface) adds more data to the running hash.
	// It never returns an error.
	io.Writer

	// Sum appends the current hash to b and returns the resulting slice.
	// It does not change the underlying hash state.
	Sum(b []byte) []byte

	// Reset resets the Hash to its initial state.
	Reset()

	// Size returns the number of bytes Sum will return.
	Size() int

	// BlockSize returns the hash's underlying block size.
	// The Write method must be able to accept any amount
	// of data, but it may operate more efficiently if all writes
	// are a multiple of the block size.
	BlockSize() int
}

此接口提供了常用的Sum等函数,此外,它还继承了io.Writer接口。该接口定义在io包里的io.go文件里。该接口定义了Write写入函数。

// Writer is the interface that wraps the basic Write method.
//
// Write writes len(p) bytes from p to the underlying data stream.
// It returns the number of bytes written from p (0 <= n <= len(p))
// and any error encountered that caused the write to stop early.
// Write must return a non-nil error if it returns n < len(p).
type Writer interface {
	Write(p []byte) (n int, err error)
}

常见的哈希函数调用过程大体如此,初始化hash.Hash之后,通过Write写入数据,通过Sum函数得到哈希结果。其中,Sum(b []byte) []byte函数的参数b,当传入nil的时候,将直接返回哈希结果,而b不为空的时候,就会将哈希结果追加到b后面。

MD5的加密算法调用如下,源码

package main

import (
	"crypto/md5"
	"encoding/hex"
)

func main() {
	m := md5.New()
	m.Write([]byte("hello, world"))
	s := hex.EncodeToString(m.Sum(nil))
	println(s)
}

FNV的加密调用也很简单,源码fnv.New32()使用的是32位的FNV-1算法进行的哈希。

package main

import "fmt"
import "hash/fnv"
import "encoding/hex"

func main() {
	a := fnv.New32()
	a.Write([]byte("hello"))
	fmt.Println(hex.EncodeToString(a.Sum(nil)))
}

FNV是一种非加密的哈希算法,支持32位、64位、128位、256位、512位和1024位的哈希。碰撞还算比较低,具体的碰撞的对比可以网上查一下。

直接哈希得到的都是整数类型,直接输出的话就会是乱码了,如果想查看正常的哈希结果,需要将结果转成对应表示的字符即可。使用包encoding/hex可以帮助实现十六进制编码。


补充一下。。。基础不好的坑自己。。。

MD5加密结果是32个16进制数,而一个字节能表示的范围是0~255,256=16×16,也就是两个十六进制数代表一个字节。所以Sum函数得到的byte数组长度是16,纠结了我半天。。。


######参考文献 + 【1】Package fnv - The Go Programming Language + 【2】Fowler–Noll–Vo hash function - wikipedia + 【3】FNV哈希算法 - 思思入code

原文链接:常见哈希函数FNV和MD5,转载请注明来源!


有疑问加站长微信联系(非本文作者)

本文来自:Cyeam

感谢作者:Bryce

查看原文:常见哈希函数FNV和MD5

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

8577 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传