研究了一下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生成方式》