SHA256 golang实现

结果展示

在这里插入图片描述
输入: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
欢迎大家批判指正,也欢迎大家留言交流

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值