go语言各种hash哈希算法使用汇总(超详细代码)

2023-10-30

目录

前言

一、首先以md4为例

(一)16进制字符串的md4

(二)字符串的md4

(三)16进制字符串、字符串封装

二、md4、md5、sha1、ripemd160、sha256、sha512

(一)导包

(二)单个使用

(三)md4、md5、sha1、ripemd160、sha256、sha512封装

三、两次sha256

(一)返回两次哈希256后字节数组

(二)返回两次哈希256后字符串


前言

  • 消息摘要,包括MD4、MD5(128位)、SHA-1、ripeMD160、SHA-224、SHA-256、SHA-384、SHA-512、SHA-3(Keccak算法,512、384、256、224)

  • 一个优秀hash算法

    • 正向快速

    • 逆向困难

    • 输入敏感

    • 抗冲突(抗碰撞)

  • 用户密码加Salt(盐)后哈希保存,增加破解难度

    • 例:密码:“123”,哈希前修改为:"123aabbcc"等。

一、首先以md4为例

(一)16进制字符串的md4

        1、"5A24"=>0x5A24。

arr, _ := hex.DecodeString("5A24")

        2、完整代码:

// 参数为16进制字符串(必须偶数个,两位16进制为1个字节)
func MD4HexString(text string) string {
	var hashInstance hash.Hash       // 定义哈希实例
	hashInstance = md4.New()         // 实例赋值 "golang.org/x/crypto/md4"
	arr, _ := hex.DecodeString(text) // 十六进制字符串转为十六进制字节数组
	hashInstance.Write(arr)          // 写入哈希实例对象
	bytes := hashInstance.Sum(nil)   // 哈希值追加到参数后面,只获取原始值,不用追加,用nil,返回哈希值字节数组
	return fmt.Sprintf("%x", bytes)  // 格式化输出哈希值
}

(二)字符串的md4

        1、将字符串转换为字节数组

arr := []byte("字符串")

        2、完整代码

// 参数为字符串
func MD4String(text string) string {
	var hashInstance hash.Hash      // 定义哈希实例
	hashInstance = md4.New()        // 实例赋值 "golang.org/x/crypto/md4"
	arr := []byte(text)             // 十六进制字符串转为十六进制字节数组
	hashInstance.Write(arr)         // 写入哈希实例对象
	bytes := hashInstance.Sum(nil)  // 哈希值追加到参数后面,只获取原始值,不用追加,用nil,返回哈希值字节数组
	return fmt.Sprintf("%x", bytes) // 格式化输出哈希值
}

(三)16进制字符串、字符串封装

  • 封装(一)、(二)
// 16进制字符串哈希:
// 第1个参数为16进制字符串(必须偶数个)时,第2个参数为:true。
// 字符串哈希:
// 第1个参数为字符串时,第2个参数为:false。
func MD4(text string, isHex bool) string {
	var hashInstance hash.Hash // 定义哈希实例
	hashInstance = md4.New()   // 实例赋值
	if isHex {
		arr, _ := hex.DecodeString(text) // 16进制字符串转为16进制字节数组
		hashInstance.Write(arr)          // 写入哈希实例对象
	} else {
		hashInstance.Write([]byte(text)) // 将字符串转换为字节数组,写入哈希对象
	}
	bytes := hashInstance.Sum(nil)  // 哈希值追加到参数后面,只获取原始值,不用追加,用nil,返回哈希值字节数组
	return fmt.Sprintf("%x", bytes) // 格式化输出哈希值
}

二、md4、md5、sha1、ripemd160、sha256、sha512

(一)导包

  • 根据具体需求的算法进行导包。
import (
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"
	"crypto/sha512"
	"encoding/hex"
	"fmt"
	"hash"

	"golang.org/x/crypto/md4"
	"golang.org/x/crypto/ripemd160"
)

(二)单个使用

  • 举一反三,根据md4的使用,我们可以将代码简单的修改以实现其他哈希算法。
  • 只需要将md4代码中的一句代码按照需求进行修改即可完成,不要忘记导包:
hashInstance = md4.New()   // md4
hashInstance = md5.New()         // md5
hashInstance = sha1.New()        // sha1
hashInstance = ripemd160.New()   // ripemd160
hashInstance = sha256.New()      // sha256
hashInstance = sha512.New()      // sha512

(三)md4、md5、sha1、ripemd160、sha256、sha512封装

// 根据不同哈希类型进行哈希:md4、md5、sha1、ripemd160、sha256、sha512
func HASH(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) // 格式化输出哈希值
}

(四)使用crypto.Hash简化代码

func HASH(text string, myhash crypto.Hash, isHex bool) string {
	var hashInstance hash.Hash // 定义哈希实例
	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) // 格式化输出哈希值
}

三、两次sha256

  • 有连续两次哈希需求时,为了不重复创建哈希对象,造成内存的浪费,可以单独封装函数。
  • 哈希完成一次后,使用以下语句,清除哈希对象内容,然后进行第二次哈希。
hashInstance.Reset()           // 重置哈希实例

(一)返回两次哈希256后字节数组

// 两次哈希256后的字节数组,第二次是将第一次哈希后的16进制进行哈希
func SHA256Double(text string, isHex bool) []byte {
	hashInstance := sha256.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 bytes
}

(二)返回两次哈希256后字符串

// 两次哈希256后的哈希字符串,第二次是将第一次哈希后的16进制进行哈希
func SHA256DoubleString(text string, isHex bool) string {
	return fmt.Sprintf("%x", SHA256Double(text, isHex))
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

go语言各种hash哈希算法使用汇总(超详细代码) 的相关文章

  • 为什么结构体不能转换为嵌入类型

    package main type Inner struct x int type Outer struct Inner func main x Inner 1 y Outer x cannot convert x type Inner t
  • 使用 MongoDB Atlas 时 mongo-go-driver 因服务器选择超时而失败

    去版本 1 12 5 我有这个使用 node js mongo 驱动程序的代码 const MongoClient require mongodb MongoClient const uri process env MONGO HOST d
  • 在 Alpine 中找不到运行时/cgo

    In an alpine edge我安装的容器通过 RUN apk add no cache musl dev go 我试着跑go get github com golang protobuf protoc gen go then 这会导致
  • 如何使用golang中通过引用传递的索引访问切片中的元素

    我将切片的引用传递给函数 并且我正在函数内的切片中进行更改 我还尝试使用索引访问切片中的元素 它在 golang 中抛出异常 通过引用传递的索引访问切片中的元素的最佳方法是什么 您可以在此处找到示例代码 参考 http www reddit
  • 无需时间即可生成随机字符串?

    我知道如何使用 Runes 和播种 rand Init 在 go 中生成随机字符串time UnixNano 我的问题是 是否可以 使用 stdlib 在不使用当前时间戳 安全 的情况下播种 rand 此外 我问 因为仅仅依靠时间来为敏感操
  • 在 Go 中生成随机、固定长度的字节数组

    我有一个字节数组 固定长度为4 token make byte 4 我需要将每个字节设置为随机字节 我怎样才能以最有效的方式做到这一点 这math rand就我而言 方法不提供随机字节函数 也许有一种内置的方法 或者我应该生成一个随机字符串
  • 我想在后端验证来自 golang 前端的时区

    前端在注册期间发送时区以及其他用户详细信息 我需要在时区上放置一个验证器来进行 api 测试 时区数据的格式为 GMT 10 00 Hawaii GMT 08 00 Pacific Time US amp Canada 我所做的是定义数组中
  • 初始化嵌套匿名结构

    我有一个 json 作为 fields time id status customerId additionalDetail pageInfo start 0 rows 1000 我想将我的结构编组到上面的 json 并创建如下结构 typ
  • 是否可以获取有关 Golang 中调用者函数的信息?

    是否可以获取有关 Golang 中调用者函数的信息 例如 如果我有 func foo Do something func main foo 我怎样才能得到那个foo已被呼叫来自main 我可以用其他语言实现这一点 例如在 C 中我只需要使用
  • 如何分析 VSCode 中函数的性能

    我用 C Golang 编写了一个程序 如何找到占用最高 CPU 周期的函数 目的是提高正在执行的程序的性能 2021 年 10 月 金香儿哈娜 https github com hyangah宣布 tweet https twitter
  • GOPATH值设置

    我用go1 3 1 windows amd64 msi安装go 安装后GOROOT是默认设置 我发现 D Programs Go bin 在 PATH 中 然后我创建一个 GOPATH 环境变量 使用 go get 命令时 出现错误 软件包
  • 鸭子在 Go 中打字

    我想写一个Join函数接受任意对象String 方法 package main import fmt strings type myint int func i myint String string return fmt Sprintf
  • Golang 正则表达式命名组和子匹配

    我正在尝试匹配正则表达式并获取匹配的捕获组名称 当正则表达式仅与字符串匹配一次时 这是有效的 但如果它与字符串匹配多次 SubexpNames不返回重复的名称 这是一个例子 package main import fmt regexp fu
  • go中有memset的类似物吗?

    在 C 中 我可以使用某些值初始化数组memset https msdn microsoft com en us library aa246471 28v vs 60 29 aspx const int MAX 1000000 int is
  • 复杂数据类型作为 Go 中映射的键

    我正在尝试在 Go 中创建一个由大整数作为键的映射 effective Go 明确指出 结构体 数组和切片不能用作映射键 因为这些类型上没有定义相等性 这是有道理的 我当然可以将大整数转换为字符串并使用字符串作为键 但我在这里寻找更通用的解
  • 有队列实现吗?

    任何人都可以建议使用 Go 容器来实现简单快速的 FIF 队列 Go 有 3 种不同的容器 heap list and vector 哪一种更适合实现队列 事实上 如果您想要的是一个基本且易于使用的 fifo 队列 slice 可以满足您所
  • 如何使信号量超时

    Go 中的信号量是通过通道来实现的 一个例子是这样的 https sites google com site gopatterns concurrency semaphores https sites google com site gop
  • “go.tools”的权限被拒绝错误

    当我尝试安装 go 工具时 我的权限被拒绝 usr local go pkg tool linux amd64 cover 我可以接受 因为它是 usr local 目录及需求root使用权 但我的第一个疑问是为什么当我设置时它试图安装在这
  • 如何同时使用 LoadHTMLGlob 和 LoadHTMLFiles

    我想要来自不同子目录的分隔符逻辑模板templates文件夹 下面是我的templates文件夹 templates authentication login gohtml logout gohtml index gohtml profil
  • 如何仅在测试时允许一个包访问另一个包的未导出数据?

    In Go 编程语言 第 11 2 4 节 有一个外部测试访问的示例fmt isSpace 通过声明IsSpace in fmt s export test go文件 这似乎是完美的解决方案 所以这就是我所做的 a a go package

随机推荐