研究了一下Go的md5计算方法,目前来看,效率最高运行最快的写法是调用md5.Sum()函数返回16字节checksum,然后把每个字节的高4位和低4位分别映射成16进制字符存到两个字节里,得到32字节,再转成字符串。FastMD5较其它算法效率提高了至少46%以上。
const hextable = "0123456789abcdef"
//作者: pengpengzhou
func FastMD5(str string) string {
src := md5.Sum([]byte(str))
var dst = make([]byte, 32)
j := 0
for _, v := range src {
dst[j] = hextable[v>>4]
dst[j+1] = hextable[v&0x0f]
j += 2
}
return string(dst)
}
Go Test Benchmark测试结果:
goos: linux
goarch: amd64
pkg: example
BenchmarkFastMD5-4 5564898 205 ns/op
BenchmarkV1-4 3461698 379 ns/op
BenchmarkV2-4 2277235 516 ns/op
BenchmarkV3-4 2158122 527 ns/op
PASS
ok example 6.440s
详细代码如下:
package main
import (
"crypto/md5"
"encoding/hex"
"fmt"
"io"
)
const hextable = "0123456789abcdef"
func FastMD5(str string) string {
src := md5.Sum([]byte(str))
var dst = make([]byte, 32)
j := 0
for _, v := range src {
dst[j] = hextable[v>>4]
dst[j+1] = hextable[v&0x0f]
j += 2
}
return string(dst)
}
func md5V1(str string) string {
h := md5.New()
h.Write([]byte(str))
return hex.EncodeToString(h.Sum(nil))
}
func md5V2(str string) string {
data := []byte(str)
has := md5.Sum(data)
md5str := fmt.Sprintf("%x", has)
return md5str
}
func md5V3(str string) string {
w := md5.New()
io.WriteString(w, str)
md5str := fmt.Sprintf("%x", w.Sum(nil))
return md5str
}
func main() {
str := "中文"
fmt.Println(FastMD5(str))
fmt.Println(md5V1(str))
fmt.Println(md5V2(str))
fmt.Println(md5V3(str))
}
package main
import (
"testing"
)
var str = "golang中文教程"
func BenchmarkFastMD5(b *testing.B) {
for i := 0; i < b.N; i++ {
FastMD5(str)
}
}
func BenchmarkV1(b *testing.B) {
for i := 0; i < b.N; i++ {
md5V1(str)
}
}
func BenchmarkV2(b *testing.B) {
for i := 0; i < b.N; i++ {
md5V2(str)
}
}
func BenchmarkV3(b *testing.B) {
for i := 0; i < b.N; i++ {
md5V3(str)
}
}
V1,V2,V3算法参考自《golang中字符串MD5生成方式》