Go语言实现各种hash算法
1、各种hash算法的实现
package mainimport ("crypto""crypto/md5""crypto/sha1""crypto/sha256""crypto/sha512""encoding/hex""fmt""hash""golang.org/x/crypto/md4""golang.org/x/crypto/ripemd160"
)func main() {str1 := HashByType("Hello World", "md4", false)fmt.Println(str1)str2 := HashByCrypto("Hello World", crypto.MD4, false)fmt.Println(str2)
}// 根据不同哈希类型进行哈希: md4、md5、sha1、ripemd160、sha256、sha512
func HashByType(text string, hashType string, isHex bool) string {var hashInstance hash.Hash // 定义哈希实例switch hashType { // 选择哈希类型case "md4":hashInstance = md4.New() // "golang.org/x/crypto/md4"case "md5":hashInstance = md5.New()case "sha1":hashInstance = sha1.New()case "ripemd160":hashInstance = ripemd160.New() // "golang.org/x/crypto/ripemd160"case "sha256":hashInstance = sha256.New()case "sha512":hashInstance = sha512.New()}if isHex {arr, _ := hex.DecodeString(text) // 十六进制字符串转为十六进制字节数组hashInstance.Write(arr) // 写入哈希实例对象} else {hashInstance.Write([]byte(text)) // 将字符串转换为字节数组,写入哈希对象}bytes := hashInstance.Sum(nil) // 哈希值追加到参数后面,只获取原始值,不用追加,用nil,返回哈希值字节数组return fmt.Sprintf("%x", bytes) // 格式化输出哈希值
}// 根据不同哈希类型进行哈希: md4、md5、sha1、ripemd160、sha256、sha512
func HashByCrypto(text string, myhash crypto.Hash, isHex bool) string {hashInstance := myhash.New() // 定义哈希实例if isHex {arr, _ := hex.DecodeString(text) // 十六进制字符串转为十六进制字节数组hashInstance.Write(arr) // 写入哈希实例对象} else {hashInstance.Write([]byte(text)) // 将字符串转换为字节数组,写入哈希对象}bytes := hashInstance.Sum(nil) // 哈希值追加到参数后面,只获取原始值,不用追加,用nil,返回哈希值字节数组return fmt.Sprintf("%x", bytes) // 格式化输出哈希值
}
支持的Hash算法有:
const (MD4 Hash = 1 + iota // import golang.org/x/crypto/md4MD5 // import crypto/md5SHA1 // import crypto/sha1SHA224 // import crypto/sha256SHA256 // import crypto/sha256SHA384 // import crypto/sha512SHA512 // import crypto/sha512MD5SHA1 // no implementation; MD5+SHA1 used for TLS RSARIPEMD160 // import golang.org/x/crypto/ripemd160SHA3_224 // import golang.org/x/crypto/sha3SHA3_256 // import golang.org/x/crypto/sha3SHA3_384 // import golang.org/x/crypto/sha3SHA3_512 // import golang.org/x/crypto/sha3SHA512_224 // import crypto/sha512SHA512_256 // import crypto/sha512BLAKE2s_256 // import golang.org/x/crypto/blake2sBLAKE2b_256 // import golang.org/x/crypto/blake2bBLAKE2b_384 // import golang.org/x/crypto/blake2bBLAKE2b_512 // import golang.org/x/crypto/blake2bmaxHash
)
2、两次hash
- 有连续两次哈希需求时,为了不重复创建哈希对象,造成内存的浪费,可以单独封装函数。
- 哈希完成一次后,使用以下语句,清除哈希对象内容,然后进行第二次哈希。
hashInstance.Reset() // 重置哈希实例
完整代码:
package mainimport ("crypto""crypto/md5""crypto/sha1""crypto/sha256""crypto/sha512""encoding/hex""fmt""hash""golang.org/x/crypto/md4""golang.org/x/crypto/ripemd160"
)func main() {str1 := HashByType("Hello World", "md4", false)fmt.Println(str1)str2 := HashByCrypto("Hello World", crypto.MD4, false)fmt.Println(str2)str3 := DoubleHashByCrypto("Hello World", crypto.MD4, false)fmt.Println(str3)
}// 根据不同哈希类型进行哈希: md4、md5、sha1、ripemd160、sha256、sha512
func HashByType(text string, hashType string, isHex bool) string {var hashInstance hash.Hash // 定义哈希实例switch hashType { // 选择哈希类型case "md4":hashInstance = md4.New() // "golang.org/x/crypto/md4"case "md5":hashInstance = md5.New()case "sha1":hashInstance = sha1.New()case "ripemd160":hashInstance = ripemd160.New() // "golang.org/x/crypto/ripemd160"case "sha256":hashInstance = sha256.New()case "sha512":hashInstance = sha512.New()}if isHex {arr, _ := hex.DecodeString(text) // 十六进制字符串转为十六进制字节数组hashInstance.Write(arr) // 写入哈希实例对象} else {hashInstance.Write([]byte(text)) // 将字符串转换为字节数组,写入哈希对象}bytes := hashInstance.Sum(nil) // 哈希值追加到参数后面,只获取原始值,不用追加,用nil,返回哈希值字节数组return fmt.Sprintf("%x", bytes) // 格式化输出哈希值
}// 根据不同哈希类型进行哈希: md4、md5、sha1、ripemd160、sha256、sha512
func HashByCrypto(text string, myhash crypto.Hash, isHex bool) string {hashInstance := myhash.New() // 定义哈希实例if isHex {arr, _ := hex.DecodeString(text) // 十六进制字符串转为十六进制字节数组hashInstance.Write(arr) // 写入哈希实例对象} else {hashInstance.Write([]byte(text)) // 将字符串转换为字节数组,写入哈希对象}bytes := hashInstance.Sum(nil) // 哈希值追加到参数后面,只获取原始值,不用追加,用nil,返回哈希值字节数组return fmt.Sprintf("%x", bytes) // 格式化输出哈希值
}// 根据不同哈希类型进行哈希: md4、md5、sha1、ripemd160、sha256、sha512
// 两次哈希256后的字节数组,第二次是将第一次哈希后的16进制进行哈希
func DoubleHashByCrypto(text string, myhash crypto.Hash, isHex bool) string {hashInstance := myhash.New() // 定义哈希实例if isHex {arr, _ := hex.DecodeString(text) // 十六进制字符串转为十六进制字节数组hashInstance.Write(arr) // 写入哈希实例对象} else {hashInstance.Write([]byte(text)) // 将字符串转换为字节数组,写入哈希对象}bytes := hashInstance.Sum(nil) // 哈希值追加到参数后面,只获取原始值,不用追加,用nil,返回哈希值字节数组hashInstance.Reset()hashInstance.Write(bytes)bytes = hashInstance.Sum(nil)return fmt.Sprintf("%x", bytes) // 格式化输出哈希值
}
# 输出
77a781b995cf1cfaf39d9e2f5910c2cf
77a781b995cf1cfaf39d9e2f5910c2cf
487b5e8e42dcd5b4cc218c2e275561fb