本文原創,轉載請注明:https://www.cnblogs.com/tkblack/p/11533874.html
學習了一段時間golang,在生成md5校驗碼時遇到一個問題,我們生成md5一般采用以下方式:
data := []byte("hello") hash := md5.New() bytes := hash.Sum(nil) fmt.Printf("%x\n", bytes) //output:5d41402abc4b2a76b9719d911017c592
或者
data := []byte("hello") bytes := md5.Sum(data) fmt.Printf("%x\n", bytes) //output:5d41402abc4b2a76b9719d911017c592
以上兩種方式都可以獲得正確的md5校驗值,當然,還是有點區別的,前一種返回的bytes是[]byte類型,后一種返回的是[Size]byte類型,這里Size=16。
接下來,我們看另一種處理方式:
data := []byte("hello") hash := md5.New() bytes := hash.Sum(data) fmt.Printf("%x\n", bytes) //output:68656c6c6fd41d8cd98f00b204e9800998ecf8427e
顯然這個結果是不相符的(不能說是錯誤),從長度上就能看出區別,那么這里究竟有什么區別呢?其實,這里調用的是兩個不同的函數,我們直接看源碼:
md5.Sum(data):
// Sum returns the MD5 checksum of the data. func Sum(data []byte) [Size]byte { var d digest d.Reset() d.Write(data) return d.checkSum() }
md5.New().Sum(data):
func (d *digest) Sum(in []byte) []byte { // Make a copy of d so that caller can keep writing and summing. d0 := *d hash := d0.checkSum() return append(in, hash[:]...) }
這樣,我們就很直觀的看到區別了,前者是調用checkSum()方法;后者,先調用checkSum(),再將in和結果進行拼接。所以,這兩個Sum函數雖然同名,但卻是不同的實現,前者屬於md5包的公共函數,后者是digest結構體的成員函數。