golang中的检验hash

1.对字符串进行hash

大家可以看一下, SHA1 Hashes

Go by Example写道:

The pattern for generating a hash is sha1.New(), sha1.Write(bytes), then sha1.Sum([]byte{}). 

附上golang代码

package main

import (
        "crypto/sha1"
        "fmt"
)

func main() {
        s := "sha1 this string"

        h := sha1.New()

        h.Write([]byte(s))

        bs := h.Sum(nil)

        fmt.Println(s)
        fmt.Printf("%x\n", bs)

}

结果输出为:

sha1 this string
cf23df2207d99a74fbe169e3eba035e633b65d94

而在godoc产生的文档使用io:WriteString代替sha1.Write(),测试2种方法都可以用。

有些文档说,使用io:WriteString,意思更加明显,而且不用像上面要进行类型转换。

h := sha1.New()
io.WriteString(h, "His money is twice tainted: ‘taint yours and ‘taint mine.")
fmt.Printf("% x", h.Sum(nil))

说个有趣的现象,使用上面代码产生的hash值和命令行中sha1sum的值不一致。

$echo "sha1 this string" | sha1sum
0faabfb58d5c522f47944173f2953f40ecfc2975  -
$
$cat a.txt
sha1 this string
$sha1sum a.txt
0faabfb58d5c522f47944173f2953f40ecfc2975  a.txt
$

可以看到,上面2个结果是一致的,但与我们上面golang代码的输出不一致。

原因是,命令行echo会在字符串后面添加一个换行符,导致整个hash值变化。大家可以自行在golang的代码中,在验证的字符串中添加换行符测试看看。

2.对文本进行hash

参考 google论坛

模式是,os.Open(file), io.Copy(dst,src), sha1.Sum()

摘录2个github代码,代码在原来的基础上有修改。

go md5/sha1 example

/*
Hash - Guillermo Estrada

Simple utility to obtain the MD5 and/or SHA-1
of a file from the command line.

package main

import (
        "io"
        "os"
        "fmt"
        "flag"
        "crypto/md5"
        "crypto/sha1"
)

func main() {

        md5f := flag.Bool("md5", false, "-md5 calculate md5 hash of file")
        sha1f := flag.Bool("sha1", false, "-sha1 calculate sha1 hash of file")
        flag.Parse()

        if !*md5f && !*sha1f {
                fmt.Println("err: No hash specified. Use -md5 or -sha1 or both.")
                os.Exit(1)
        }

        infile, inerr := os.Open(flag.Arg(0))
        if inerr == nil {
                if *md5f {
                        md5h := md5.New()
                        io.Copy(md5h,infile)
                        fmt.Printf("%x  %s\n",md5h.Sum(nil), flag.Arg(0))
                }
                if *sha1f {
                        sha1h := sha1.New()
                        io.Copy(sha1h,infile)
                        fmt.Printf("%x  %s\n",sha1h.Sum(nil), flag.Arg(0))
                }

        } else {
                fmt.Println(inerr)
                os.Exit(1)
        }
}

命令行调用:

#for a in md5 sha1 ; do echo ${a}sum; ./hash -$a /bin/ls; ${a}sum /bin/ls; echo; done
md5sum
b691e28e120f6989e37c7db21cb51931  /bin/ls
b691e28e120f6989e37c7db21cb51931  /bin/ls

sha1sum
502202e177bb8677c8c3b059cc1401d1524806c8  /bin/ls
502202e177bb8677c8c3b059cc1401d1524806c8  /bin/ls

#

hashes.go

/*
Hash - Guillermo Estrada

Simple utility to obtain the MD5 and/or SHA-1
of a file from the command line.

2011

Edited: Marko Mikulicic 2011
*/

package main

import (
        "io"
        "os"
        "fmt"
        "flag"
        "hash"
        "crypto/md5"
        "crypto/sha1"
        "crypto/sha256"
        "crypto/sha512"
        //"crypto/ripemd160"
)

func main() {

        algos := [...]string{"md5", "sha1", "sha256", "sha512" }
        impls := [...]hash.Hash{md5.New(), sha1.New(), sha256.New(), sha512.New() }
        flags := make([]*bool, len(algos))
        for i, a := range algos {
                flags[i] = flag.Bool(a, false, fmt.Sprintf("-%s calculate %s hash of file", a, a))
        }

        flag.Parse()

        any := false
        for _, f := range flags {
                any = any || *f
        }
        if any == false {
                fmt.Println("err: No hash specified. Please run with --help to see list of supported hash algos")
                os.Exit(1)
        }

        infile, err := os.Open(flag.Arg(0))
        if err != nil {
                fmt.Println(err)
                os.Exit(1)
        }

        writers := make([]io.Writer, 0, len(impls))
        for i, flag := range flags {
                if *flag {
                        writers = append(writers, impls[i])
                }
        }

        dest := io.MultiWriter(writers...)

        io.Copy(dest, infile)

        for i, flag := range flags {
                if *flag {
                        fmt.Printf("%s: \n%x\n", algos[i], impls[i].Sum(nil))
                }
        }

}

命令行调用:

#for a in md5 sha1 sha256 sha512 ; do ./hashes -$a /bin/ls; ${a}sum /bin/ls; echo; done
md5:
b691e28e120f6989e37c7db21cb51931
b691e28e120f6989e37c7db21cb51931  /bin/ls

sha1:
502202e177bb8677c8c3b059cc1401d1524806c8
502202e177bb8677c8c3b059cc1401d1524806c8  /bin/ls

sha256:
1e87d99599ddea2a93f060b50a54066e8b756d752158e6147cbb99b06eb11d99
1e87d99599ddea2a93f060b50a54066e8b756d752158e6147cbb99b06eb11d99  /bin/ls

sha512:
343b38486ad17c5813026c9df7e1ce7e268d7c64e70439aebddcafdfe10a0dfc9f55bf8169c3e592942f50bb408a852dfd1fb08e0bcadf214bc89dbf72d693f8
343b38486ad17c5813026c9df7e1ce7e268d7c64e70439aebddcafdfe10a0dfc9f55bf8169c3e592942f50bb408a852dfd1fb08e0bcadf214bc89dbf72d693f8  /bin/ls

#

golang中的检验hash

时间: 2024-07-31 14:52:46

golang中的检验hash的相关文章

Golang 中使用多维 map

http://tnt.wicast.tk/2015/11/02/golang-multiple-dimension-map/ Golang 的 XML/JSON 解析库乍看使用起来很方便,只要构造一样结构的 Struct 就可以一下子导入到变量中去了.其实手工构造 Struct 非常容易出现结构偏差,而且最要命的是 Unmarshal() 执行的时候不是严格导入所以没有任何报错. 于是这两天写了一个给 Golang 用的 XML to Struct 生成器,希望能一劳永逸. 不过在制作过程中有遇

在Golang中使用Redis

周五上班的主要任务是在公司老平台上用redis处理一个队列问题,顺便复习了一下redis操作的基础知识,回来后就想着在自己的博客demo里,用redis来优化一些使用场景,学习一下golang开发下redis的使用. Redis简单介绍 简介 关于Redis的讨论,其实在现在的后台开发中已经是个老生常谈的问题,基本上也是后端开发面试的基本考察点.其中 Redis的背景介绍和细节说明在这里就不赘述.不管怎么介绍,核心在于Redis是一个基于内存的key-value的多数据结构存储,并可以提供持久化

Golang中多用途的defer

defer顾名思义就是延迟执行,那么defer在Golang中该如何使用以及何时使用呢? A "defer" statement invokes a function whose executionis deferred to the moment the surrounding function returns, Golang的官方时这么定义的. 1.那么在什么情况下会调用defer延迟过的函数呢? 从文档中可以知道主要有两种情况: 当函数执行了return 语句后 当函数处于pan

Golang中使用log(一):Golang 标准库提供的Log

Golang的标准库提供了log的机制,但是该模块的功能较为简单(看似简单,其实他有他的设计思路).不过比手写fmt. Printxxx还是强很多的.至少在输出的位置做了线程安全的保护.其官方手册见Golang log (天朝的墙大家懂的).这里给出一个简单使用的例子: package main import ( "log" ) func main(){ log.Fatal("Come with fatal,exit with 1 \n") } 编译运行后,会看到程

Go_18: Golang 中三种读取文件发放性能对比

Golang 中读取文件大概有三种方法,分别为: 1. 通过原生态 io 包中的 read 方法进行读取 2. 通过 io/ioutil 包提供的 read 方法进行读取 3. 通过 bufio 包提供的 read 方法进行读取 下面通过代码来验证这三种方式的读取性能,并总结出我们平时应该使用的方案,以便我们可以写出最优代码: package main import ( "os" "io" "bufio" "io/ioutil"

Go_14:GoLang中 json、map、struct 之间的相互转化

1. golang 中 json 转 struct <1. 使用 json.Unmarshal 时,结构体的每一项必须是导出项(import field).也就是说结构体的 key 对应的首字母必须为大写.请看下面的例子: package commontest import ( "testing" "encoding/json" ) type Person struct { name string age int } func TestStruct2Json(

golang中使用selenium进行爬虫

selenium本来是用来做自动测试,但是因为可以模拟浏览器操作,所以也可以用来做爬虫(尤其是一些比较变态登陆网站,又不会模拟登陆的),只是速度会比较慢. 转载请注明出处:http://www.cnblogs.com/SSSR/p/6390229.html 经验总结: 1.火狐浏览器在运行较长时间后,会导致内存泄露,但是Google浏览器不会,所以如果长时间运行还是使用Google浏览器比较好. 2.截图方面选择火狐浏览器,Google浏览器无法截全部页面,即使设置了页面大小也不行. 3.Fir

Golang中的字节序列化操作

在写网络程序的时候,我们经常需要将结构体或者整数等数据类型序列化成二进制的buffer串.或者从一个buffer中解析出来一个结构体出来,最典型的就是在协议的header部分表征head length 或者body length在拼包和拆包的过程中,需要按照规定的整数类型进行解析,且涉及到大小端序的问题. 1.C中是怎么操作的 在C中我们最简单的方法是用memcpy来一个整形数或者结构体等其他类型复制到一块内存中,然后在强转回需要的类型.如:     // produce     int a =

Golang中使用log(二):Golang 标准库log的实现

前一篇文章我们看到了Golang标准库中log模块的使用,那么它是如何实现的呢?下面我从log.Logger开始逐步分析其实现. 其源码可以参考官方地址 1.Logger结构 首先来看下类型Logger的定义: type Logger struct { mu sync.Mutex // ensures atomic writes; protects the following fields prefix string // prefix to write at beginning of each