浅析Go 字符串指纹

写项目时,有时我们需要缓存, 缓存就会需要唯一的key. 常规是对字符串求md5指纹. 在golang里我们也可以使用, 目前可以计算一个字符串的crc32, md5, sha1的指纹.

md5 : 一种被广泛使用的密码散列函数,可以产bai生出一个128位(du16字节)的散列值(hash value),用于确保信息传输完整一zhi致。MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开,用以取代MD4算法。

sha1: SHA1是由NISTNSA设计为同DSA一起使用的,它对长度小于264的输入,产生长度为160bit的散列值,因此抗穷举(brute-force)性更好。SHA-1基于MD5,MD5又基于MD4。

crc32: 本身是“冗余校验码”的意思,CRC32则表示会产生一个32bit(8位十六进制数)的校验值。由于CRC32产生校验值时源数据块的每一个bit(位)都参与了计算,所以数据块中即使只有一位发生了变化,也会得到不同的CRC32值。

golang 实现

md5

// md5值
func Md5Str(s string) string {
	hash := md5.Sum([]byte(s))
	return hex.EncodeToString(hash[:])
}

sha1

// 散列值
func Sha1Str(s string) string {
	r := sha1.Sum([]byte(s))
	return hex.EncodeToString(r[:])
}

crc32

// String hashes a string to a unique hashcode.
// https://github.com/hashicorp/terraform/blob/master/helper/hashcode/hashcode.go
// crc32 returns a uint32, but for our use we need
// and non negative integer. Here we cast to an integer
// and invert it if the result is negative.
func HashCode(s string) int {
	v := int(crc32.ChecksumIEEE([]byte(s)))
	if v >= 0 {
		return v
	}
	if -v >= 0 {
		return -v
	}
	// v == MinInt
	return 0
}

// Strings hashes a list of strings to a unique hashcode.
func HashCodes(strings []string) string {
	var buf bytes.Buffer

	for _, s := range strings {
		buf.WriteString(fmt.Sprintf("%s-", s))
	}

	return fmt.Sprintf("%d", HashCode(buf.String()))
}

使用

func main() {
	// 2713056744
	// 1f8689c0dd07ce42757ac01b1ea714f9
	// 9addcbc6fee9c06f43d7110b657f3c61ff707032
	txt := "https://github.com/hashicorp/terraform/blob/master/helper/hashcode/hashcode.go"
	fmt.Println(HashCode(txt))
	fmt.Println(Md5Str(txt))
	fmt.Println(Sha1Str(txt))
}

效率

得出效率: hash_code > md5 > sha1

const (
	Txt = "https://github.com/hashicorp/terraform/blob/master/helper/hashcode/hashcode.go"
)

// go test -test.bench=. -test.benchmem
func BenchmarkMd5Str(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Md5Str(Txt)
	}
}
func BenchmarkHashCode(b *testing.B) {
	for i := 0; i < b.N; i++ {
		HashCode(Txt)
	}
}
func BenchmarkSha1Str(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Sha1Str(Txt)
	}
}

// BenchmarkMd5Str-8    2148428        518 ns/op       144 B/op     3 allocs/op
// BenchmarkHashCode-8   8105571        160 ns/op       80 B/op     1 allocs/op
// BenchmarkSha1Str-8    1836854        700 ns/op       176 B/op     3 allocs/op

// 得出效率: hash_code > md5 > sha1

以上就是浅析Go 字符串指纹的详细内容,更多关于Go 字符串指纹的资料请关注我们其它相关文章!

(0)

相关推荐

  • Golang字符串的拼接方法汇总

    字符串拼接在 golang 里面其实有很多种实现. 实现方式 直接使用运算符 func BenchmarkAddStringWithOperator(b *testing.B) {     hello := "hello"     world := "world"     for i := 0; i < b.N; i++ {         _ = hello + "," + world     } } golang里面的字符串都是不可变的

  • go浮点数转字符串保留小数点后N位的完美解决方法

    最近在项目中碰到很多次float转string,同时要求保留小数点后几位,并且去掉小数点后0的场景 虽然问题很简单,但是隔了挺久没处理这种场景就有些生疏了,自己也搜了一下,很多回答都不太满意.这里贴一下自己的做法,如果有更好的解决办法的话,还请多多指教 // 主要逻辑就是先乘,trunc之后再除回去,就达到了保留N位小数的效果 func FormatFloat(num float64, decimal int) string { // 默认乘1 d := float64(1) if decima

  • 让Django的BooleanField支持字符串形式的输入方式

    再Django中,你可以把字符串形式的数值赋值给IntegerField,然后Django会默认把字符串转换成int. 但是BooleanField则不行,BooleanField只能接受True和False,或者0和1(BTW:在python中True即是1,False即是0). 这对于很多网络参数上传的场景很不利,因为很多时候我们处于方便会将布尔型参数转换成字符串形式来上传. 一个典型的场景是在使用Swfit的Alamofire框架中的upload来上传Multipartform时,由于fo

  • 分享6个Go处理字符串的技巧小结

    如果你从 Ruby 或者 Python 转型到 Go,将会有很多语言差异需要学习,其中很多问题都是围绕处理 string 类型. 下面是一些字符串的技巧,这些技巧解决了我在使用 Golang 的最初几周中遇到的问题. 1. 多行字符串 在 Go 中创建多行字符串非常容易.只需要在你声明或赋值时使用 (``) . str := `This is a multiline string.` 注意 - 任何你在字符串中的缩进都将被保留在最终结果. str := `This string will hav

  • Golang 中整数转字符串的方法

    整形转字符串经常会用到,本文讨论一下 Golang 提供的这几种方法.基于 go1.10.1 fmt.Sprintf fmt 包应该是最常见的了,从刚开始学习 Golang 就接触到了,写 'hello, world' 就得用它.它还支持格式化变量转为字符串. func Sprintf(format string, a ...interface{}) string Sprintf formats according to a format specifier and returns the re

  • Golang中的Unicode与字符串示例详解

    背景: 在我们使用Golang进行开发过程中,总是绕不开对字符或字符串的处理,而在Golang语言中,对字符和字符串的处理方式可能和其他语言不太一样,比如Python或Java类的语言,本篇文章分享一些Golang语言下的Unicode和字符串编码. Go语言字符编码 注意: 在Golang语言中的标识符可以包含 " 任何Unicode编码可以标识的字母字符 ". 被转换的整数值应该可以代表一个有效的 Unicode 代码点,否则转换的结果就将会是 "�",即:一个

  • Go 验证字符串中是否包含中文(推荐)

    发现一个验证字符串是否包含中文滴时候,一个比正则更好使滴方法,而且是golang 自带滴验证. 不需要自己写正则验证,代码如下: package main import ( "fmt" "regexp" "unicode" ) func main() { s1 := "我是中国人hello word!,2020 street 188#" var count int for _, v := range s1 { if unico

  • Golang中生成随机字符串并复制到粘贴板的方法

    前段时间在生活中偶尔需要对某些文件进行重命名,而且是随机名字,刚 开始是手动重命名然后在键盘上胡乱打一些字母数字,时间长了发现也挺麻烦的,于是想到能不能用golang实现这个功能并且自动把生成的字符串 复制到粘贴板,然后生成exe文件,要用的是直接鼠标双击就行.说干就干. 网上搜了些相关资料,于是写了出来. 安装必要的库 go get github.com/atotto/clipboard 代码实现 package main import ( "fmt" "github.co

  • Go 结构体、数组、字典和 json 字符串的相互转换方法

    Go 语言中 encoding/json 包可以很方便的将结构体.数组.字典转换为 json 字符串. 引用 import "encoding/json" 解析语法 // v 传入结构体.数组等实例变量 // []byte 字节数组 // error 可能会有的错误 func Marshal(v interface{}) ([]byte, error) 反解析 // []byte 字节数组 // v 传入结构体.数组等实例变量的指针地址 // error 可能会有的错误 func Un

  • Go语言中的字符串处理方法示例详解

    1 概述 字符串,string,一串固定长度的字符连接起来的字符集合.Go语言的字符串是使用UTF-8编码的.UTF-8是Unicode的实现方式之一. Go语言原生支持字符串.使用双引号("")或反引号(``)定义. 双引号:"", 用于单行字符串. 反引号:``,用于定义多行字符串,内部会原样解析. 示例: // 单行 "心有猛虎,细嗅蔷薇" // 多行 ` 大风歌 大风起兮云飞扬. 威加海内兮归故乡. 安得猛士兮守四方! ` 字符串支持转义

  • 简单谈谈Golang中的字符串与字节数组

    前言 字符串是 Go 语言中最常用的基础数据类型之一,虽然字符串往往都被看做是一个整体,但是实际上字符串是一片连续的内存空间,我们也可以将它理解成一个由字符组成的数组,Go 语言中另外一个与字符串关系非常密切的类型就是字节(Byte)了,相信各位读者也都非常了解,这里也就不展开介绍. 我们在这一节中就会详细介绍这两种基本类型的实现原理以及它们的转换关系,但是这里还是会将介绍的重点主要放在字符串上,因为这是我们接触最多的一种基本类型并且后者就是一个简单的 uint8 类型,所以会给予 string

  • Go 高效截取字符串的一些思考

    最近我在Go Forum中发现了String size of 20 character的问题,"hollowaykeanho" 给出了相关的答案,而我从中发现了截取字符串的方案并非最理想的方法,因此做了一系列实验并获得高效截取字符串的方法,这篇文章将逐步讲解我实践的过程. 字节切片截取 这正是 "hollowaykeanho" 给出的第一个方案,我想也是很多人想到的第一个方案,利用 go 的内置切片语法截取字符串: s := "abcdef" f

随机推荐