结果展示
输入:abcdefghijklmnopqrstuvwxyz
输出:71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73
SHA256在线验证网站:https://www.online-convert.com/
golang代码
SHA256完整代码:
package hash256
import (
"errors"
)
//常量
var arrMisc [8]uint32
var arrConst [64]uint32
//移位函数
//右循环
func ROTR(w uint32,n int) uint32{
return (w >> n) | (w << (32 - n))
}
//左循环
func ROTL(w uint32,n int) uint32{
return (w << n) | (w >> (32 - n))
}
//右移位
func SHR(w uint32,n int) uint32{
return w >> n
}
//6个hash函数
var func1 func(uint32,uint32,uint32)uint32
var func2 func(uint32,uint32,uint32)uint32
var func3 func(uint32)uint32
var func4 func(uint32)uint32
var func5 func(uint32)uint32
var func6 func(uint32)uint32
//数据和函数初始化
func init(){
arrMisc = [8]uint32 {0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,
0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19}
arrConst = [64]uint32{0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2}
func1 = func (x,y,z uint32)uint32{
return (x&y)^((^x)&z)
}
func2 = func (x,y,z uint32)uint32{
return (x&y)^(x&z)^(y&z)
}
func3 = func(x uint32)uint32{
return ROTL(x,30) ^ ROTL(x,19) ^ ROTL(x,10)
}
func4 = func(x uint32)uint32{
return ROTL(x,26) ^ ROTL(x,21) ^ ROTL(x,7)
}
func5 = func(x uint32)uint32{
return ROTL(x,25) ^ ROTL(x,14) ^ SHR(x,3)
}
func6 = func(x uint32)uint32{
return ROTL(x,15) ^ ROTL(x,13) ^ SHR(x,10)
}
}
//数据预处理,填充位和长度,默认最小为一个字节(8位)
func datePre(data []byte)[]byte{
//需要填充数据
var data1 uint8 = 0x80
var data2 uint8 = 0x00
//字符串总共字节数
var dataLen uint64 = uint64(len(data))
var remainder int = int(dataLen % 64)
//填充位,至少补一个字节
data = append(data,data1)
if remainder < 56{
//已经填充过一个字节
remainder++
for i := 0;i < 56 - remainder;i++{
data = append(data,data2)
}
}else if remainder == 56{
//添加63个字节,64 - 1,-1因为已经填充过一个字节
for i := 0;i < 63;i++{
data = append(data,data2)
}
}else{
//已经填充过一个字节//60 48 + 64 - 60
remainder++
//需要补到120个字节
tmp := 120 - remainder
for i := 0;i < tmp;i++{
data = append(data,data2)
}
}
//填充长度
byteLen := dataLen * 8
var byteAttach [8]byte;
for i := 0;i < 8;i++{
byteAttach[i] = byte(byteLen % 0x100)
byteLen = byteLen / 0x100
}
for i := 8;i > 0;i--{
data = append(data,byteAttach[i - 1])
}
return data
}
/*
映射函数,H[i] + data[i] -> H[i+1]
data:512比特数据
H:上一个块的hashMap计算结果,初始值为arrMisc,8个常量
返回值:当前块的计算结果
*/
func hashMap(data [64]byte,H [8]uint32)[8]uint32{
var res [8]uint32 = H
var wordData [64]uint32
for i := 0;i < 16;i++{
var base uint32 = 8
for j := 0;j < 4;j++{
wordData[i] = wordData[i] << base + uint32(data[ i * 4 + j])
}
}
for i := 16;i < 64;i++{
wordData[i] = func6(wordData[i - 2]) + wordData[i - 7] + func5(wordData[i - 15]) + wordData[i - 16]
}
var T1,T2 uint32
for i := 0;i < 64;i++{
T1 = res[7] + func4(res[4]) + func1(res[4],res[5],res[6]) + arrConst[i] + wordData[i]
T2 = func3(res[0]) + func2(res[0],res[1],res[2])
res[7] = res[6]
res[6] = res[5]
res[5] = res[4]
res[4] = res[3] + T1
res[3] = res[2]
res[2] = res[1]
res[1] = res[0]
res[0] = T1 + T2
}
for i := 0;i < 8;i++{
H[i] += res[i]
}
return H
}
/*
hash256主函数
data:需要计算的数据
返回值:如果error为nil,则返回hash256结果和nil,否则返回0和"The len is 0"
*/
func HashMain(data []byte)([8]uint32,error){
if len(data) == 0{
var res [8]uint32
return res,errors.New("The len is 0")
}
//初始化数据
var res [8]uint32 = arrMisc
data = datePre(data)
for i := 0;i < len(data);i = i + 64{
tmp := [64]byte(data[i:i + 64])
res = hashMap(tmp,res)
}
return res,nil
}
测试代码
package main
import (
"fmt"
"algorithm/hash/hash256" //此处需要根据个人的包路径填写
)
func main(){
n := 26
var testStr []byte = make([]byte,n,n)
for i := 0;i < n;i++{
testStr[i] = byte('a' + i)
}
fmt.Printf("%s\n",testStr)
res,_ := hash256.HashMain(testStr)
for i := 0;i < 8;i++{
fmt.Printf("%x",res[i])
}
fmt.Println()
}
参考文章
本文参考:https://blog.csdn.net/lwanttowin/article/details/53726450
欢迎大家批判指正,也欢迎大家留言交流