在go语言中对数据计算一个md5,或sha256和其他语言 如java, php中的使用方式稍有不同, 那就是要加密的数据必须通过流的形式写入到你创建的Hash对象中。
Hash数据加密步骤
1. 先使用对应的加密算法包中的New函数创建一个Hash对象,(这个也就是一个io.Writer) ;
如: sha := md5.New()
2. 将要计算MD5/sha256的数据或者文件写入这个writer;
如:io.WriteString(sha, "admin")
文件hash计算:
file,_:=os.Open("yourfile.txt")
io.Copy(sha, file) // 文件hash计算和字符串hash计算的区别就在这里,其他地方完全一样
3. 最后在调用hash对象的方法Sum方法即可计算文件或者数据的MD5值;
如: b0 := sha.Sum(nil) // 注意这个Sum方法对于计算Hash值时不需要传参数,给他个nil 哄一下就行
4. 返回值b0,这个值是16进制的unicode表示,需要使用 %x 将其格式化为可读字符串.
如: md5Str:=fmt.Sprintf("%x",b0)
到此,整个hash加密过程就算完成了, 怎么样是不是很简单?
go语言中的其他Hash加密算法, 如 sha1, sha256, sha512等的加密步骤和方法也都是一样的,唯一不同的地方就是在创建Hash对象的时候你使用的包名不一样而已。
对于文件的hash值计算,
方法也是一样的, 不同的地方就是在数据写入的时候,把 io.WriteString(sha, "admin") 替换为 io.Copy(sha, file) 这里的file是你使用打开的要计算hash的文件对象指针,在这个地方被当做一个reader
Hash对象运行内存图解
上图可以帮助我们验证go语言中的数据加密的运行方式,流式数据写入, 还有hash对象中的这个Sum方法参数在对数据进行加密的时候 为什么必须为nil。
Hash对象运行内存图解中的代码: 这个是一个example测试用例,保存到 xxx_test.go 即可运行
package test
import (
"crypto/md5"
"fmt"
"io"
)
func ExampleMd5() {
sha := md5.New()
io.WriteString(sha, "admin") // 这里要计算MD5的字符串必须要以流的显示写入到hash对象中
b0 := sha.Sum(nil) // 字节放到Sum参数里面最会将数据追加到流的前面返回,不会影响hash对象的数据.
// 验证
fmt.Printf("admin对应的md5字节: %v 字符串: %x \n", b0, b0)
b1 := sha.Sum([]byte("ab中")) // 这里传递的参数不会影响hash对象,仅附加到数据流的前面
//Sum方法里面追加的参数 ab中 被转换为 97 98 228 184 173 , 可见这里的97就是a的码值,98是b的码值,而 228 184 173 则是中对应的码值因为一个汉字占3个字节所以这里有3个byte
fmt.Printf(`Sum([]byte("admin"))后字节: %v 字符串: %x`, b1, b1)
// output:
// admin对应的md5字节: [33 35 47 41 122 87 165 167 67 137 74 14 74 128 31 195] 字符串: 21232f297a57a5a743894a0e4a801fc3
// Sum([]byte("admin"))后字节: [97 98 228 184 173 33 35 47 41 122 87 165 167 67 137 74 14 74 128 31 195] 字符串: 6162e4b8ad21232f297a57a5a743894a0e4a801fc3
}