go 调用 md5 方法

新建 md5.go 文件,代码如下:

package main

import(
    "fmt"
    "crypto/md5"
    "encoding/hex"
)

func main(){
    data := []byte("hello world")
    s := fmt.Sprintf("%x", md5.Sum(data))
    fmt.Println(s)

    // 也可以用这种方式
    h := md5.New()
    h.Write(data)
    s = hex.EncodeToString(h.Sum(nil))
    fmt.Println(s)
}


--------

运行结果

go run md5.go

5eb63bbbe01eeed093cb22bb8f5acdc3
5eb63bbbe01eeed093cb22bb8f5acdc3

**

md5 实现原理

**
1.对MD5算法简要的叙述可以为:MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。

填充:如果输入信息的长度(bit)对512求余的结果不等于448,就需要填充使得对512求余的结果等于448。填充的方法是填充一个1和n个0。填充完后,信息的长度就为N*512+448(bit);

2.记录信息长度:用64位来存储填充前信息长度。这64位加在第一步结果的后面,这样信息长度就变为N*512+448+64=(N+1)*512位。

3.装入标准的幻数(四个整数):标准的幻数(物理顺序)是(A=(01234567)16,B=(89ABCDEF)16,C=(FEDCBA98)16,D=(76543210)16)。如果在程序中定义应该是(A=0X67452301,B=0XEFCDAB89,C=0X98BADCFE,D=0X10325476)

4.四轮循环运算:循环的次数是分组的个数(N+1)

1.将每一512字节细分成16个小组,每个小组64位(8个字节)
2.先认识四个线性函数(&是与,|是或,^是异或)

F(X,Y,Z)=(Y ^ Z) & X) ^ Z  
G(X,Y,Z)=((X ^ Y) & Z) ^ Y  
H(X,Y,Z)=X ^ Y ^ Z  
I(X,Y,Z)=Y ^ (X | ^Z)  

完整代码

package main

import(
    "fmt"
    "unsafe"
)

const Size = 16

const (
    chunk = 64
    init0 = 0x67452301
    init1 = 0xEFCDAB89
    init2 = 0x98BADCFE
    init3 = 0x10325476
)

// digest represents the partial evaluation of a checksum.
type digest struct {
    s   [4]uint32
    x   [chunk]byte
    nx  int
    len uint64
}

func (d *digest) Reset() {
    d.s[0] = init0
    d.s[1] = init1
    d.s[2] = init2
    d.s[3] = init3
    d.nx = 0
    d.len = 0
}

func (d *digest) Write(p []byte) (nn int, err error) {
    nn = len(p)
    d.len += uint64(nn)
    if d.nx > 0 {
        n := copy(d.x[d.nx:], p)
        d.nx += n
        if d.nx == chunk {
            blockGeneric(d, d.x[:])
            d.nx = 0
        }
        p = p[n:]
    }
    if len(p) >= chunk {
        n := len(p) &^ (chunk - 1)
        blockGeneric(d, p[:n])
        p = p[n:]
    }
    if len(p) > 0 {
        d.nx = copy(d.x[:], p)
    }

    fmt.Printf("%v\n",d)

    return
}

func (d *digest) checkSum() [Size]byte {
    // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
    len := d.len
    var tmp [64]byte
    tmp[0] = 0x80
    if len%64 < 56 {
        d.Write(tmp[0 : 56-len%64])
        fmt.Printf("%v",d)
    } else {
        d.Write(tmp[0 : 64+56-len%64])
    }

    // Length in bits.
    len <<= 3
    for i := uint(0); i < 8; i++ {
        tmp[i] = byte(len >> (8 * i))
    }
    d.Write(tmp[0:8])

    if d.nx != 0 {
        panic("d.nx != 0")
    }

    var digest [Size]byte
    for i, s := range d.s {
        digest[i*4] = byte(s)
        digest[i*4+1] = byte(s >> 8)
        digest[i*4+2] = byte(s >> 16)
        digest[i*4+3] = byte(s >> 24)
    }

    return digest
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值