详见代码...
/**
md5 hash
**/
package main
import (
"crypto/md5"
"fmt"
"encoding/hex"
"io"
"reflect"
)
// 方法一
func md5V1(str string) {
bytes := []byte(str)
// 创建 md5 对象
hash := md5.New()
// 也可以增加一个 key,和 key 一起使用 md5 计算摘要。加盐
// func NewMD5(key []byte) hash.Hash
// 将要计算的字符串以 byte 数组的形式写入对象中
hash.Write(bytes)
// 获取摘要结果,返回一个 []byte 类型
hashValue := hash.Sum(nil)
// []uint8(unit8即byte)
fmt.Println(reflect.TypeOf(hashValue).String())
// [177 148 106 201 36 146 210 52 124 98 53 180 210 97 17 132]
fmt.Println(hashValue);
// 通常以 ASCII 形式输 出四个由 4 字节组成的十六进制数
hashSzie := hash.Size()
for i := 0; i < hashSzie; i += 4 {
var val uint32
// 比低位高 3 字节,*pow(2,3*8)
val = uint32(hashValue[i]) << 24 +
// 比低位高 2 字节,*pow(2,2*8)
uint32(hashValue[i + 1]) << 16 +
// // 比低位高 1 字节,*pow(2,1*8)
uint32(hashValue[i + 2]) << 8 +
uint32(hashValue[i + 3])
fmt.Printf("%x", val)
}
fmt.Println()
// 上述转换过程可以使用 hex.EncodeToString
fmt.Println(hex.EncodeToString(hashValue))
// 其实直接使用 %x 格式化输出也是一样的
fmt.Printf("%x\n", hashValue)
// 也可以通过 fmt 写入 string 字符串
md5Str := fmt.Sprintf("%x", hashValue)
fmt.Println(md5Str)
fmt.Println("==================")
}
// 方法二
func md5V2(str string) {
bytes := []byte(str)
// 该方法写起来较方法一,三方便
// 返回的 [16]byte 类型,区别于方法一和方法三中的 []byte
hashValue := md5.Sum(bytes)
// [16]uint8(unit8即byte)
fmt.Println(reflect.TypeOf(hashValue).String())
fmt.Printf("%x\n", hashValue)
fmt.Println("==================")
}
// 方法三
func md5V3(str string) {
hash := md5.New()
// 和方法一的区别就是此处使用的 io.WriteString 将字符串写入 hash
// 而方法一使用的 md5.Write 将字符串写入 hash 中
io.WriteString(hash, str)
hashValue := hash.Sum(nil)
// []uint8(unit8即byte)
fmt.Println(reflect.TypeOf(hashValue).String())
fmt.Printf("%x\n", hashValue)
fmt.Println("==================")
}
func main() {
str := "hello\n";
md5V1(str)
md5V2(str)
md5V3(str)
}