md5加密算法原理及其GO语言实现
生活随笔
收集整理的這篇文章主要介紹了
md5加密算法原理及其GO语言实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
md5加密算法原理及其GO語言實現
MD5訊息摘要演算法(英語:MD5 Message-Digest Algorithm),一種被廣泛使用的密碼雜湊函數,可以產生出一個128位元(16位元組)的散列值(hash value),用于確保信息傳輸完整一致。
go 調用 md5 方法
新建 md5.go 文件,代碼如下:
package mainimport("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 5eb63bbbe01eeed093cb22bb8f5acdc3md5 實現原理
對MD5算法簡要的敘述可以為:MD5以512位分組來處理輸入的信息,且每一分組又被劃分為16個32位子分組,經過了一系列的處理后,算法的輸出由四個32位分組組成,將這四個32位分組級聯后將生成一個128位散列值。
填充:如果輸入信息的長度(bit)對512求余的結果不等于448,就需要填充使得對512求余的結果等于448。填充的方法是填充一個1和n個0。填充完后,信息的長度就為N*512+448(bit);
記錄信息長度:用64位來存儲填充前信息長度。這64位加在第一步結果的后面,這樣信息長度就變為N*512+448+64=(N+1)*512位。
裝入標準的幻數(四個整數):標準的幻數(物理順序)是(A=(01234567)16,B=(89ABCDEF)16,C=(FEDCBA98)16,D=(76543210)16)。如果在程序中定義應該是(A=0X67452301,B=0XEFCDAB89,C=0X98BADCFE,D=0X10325476)
四輪循環運算:循環的次數是分組的個數(N+1)
- 將每一512字節細分成16個小組,每個小組64位(8個字節)
- 先認識四個線性函數(&是與,|是或,^是異或)
- 設Mj表示消息的第j個子分組(從0到15),<<
完整代碼
package mainimport("fmt""unsafe" )const Size = 16const (chunk = 64init0 = 0x67452301init1 = 0xEFCDAB89init2 = 0x98BADCFEinit3 = 0x10325476 ) // digest represents the partial evaluation of a checksum. type digest struct {s [4]uint32x [chunk]bytenx intlen uint64 }func (d *digest) Reset() {d.s[0] = init0d.s[1] = init1d.s[2] = init2d.s[3] = init3d.nx = 0d.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 += nif 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.lenvar tmp [64]bytetmp[0] = 0x80if 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 <<= 3for 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]bytefor 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 }func blockGeneric(dig *digest, p []byte) {a := dig.s[0]b := dig.s[1]c := dig.s[2]d := dig.s[3]var X *[16]uint32for len(p) >= chunk {aa, bb, cc, dd := a, b, c, dX = (*[16]uint32)(unsafe.Pointer(&p[0])) // Round 1.a += (((c ^ d) & b) ^ d) + X[0] + 3614090360a = a<<7 | a>>(32-7) + bd += (((b ^ c) & a) ^ c) + X[1] + 3905402710d = d<<12 | d>>(32-12) + ac += (((a ^ b) & d) ^ b) + X[2] + 606105819c = c<<17 | c>>(32-17) + db += (((d ^ a) & c) ^ a) + X[3] + 3250441966b = b<<22 | b>>(32-22) + ca += (((c ^ d) & b) ^ d) + X[4] + 4118548399a = a<<7 | a>>(32-7) + bd += (((b ^ c) & a) ^ c) + X[5] + 1200080426d = d<<12 | d>>(32-12) + ac += (((a ^ b) & d) ^ b) + X[6] + 2821735955c = c<<17 | c>>(32-17) + db += (((d ^ a) & c) ^ a) + X[7] + 4249261313b = b<<22 | b>>(32-22) + ca += (((c ^ d) & b) ^ d) + X[8] + 1770035416a = a<<7 | a>>(32-7) + bd += (((b ^ c) & a) ^ c) + X[9] + 2336552879d = d<<12 | d>>(32-12) + ac += (((a ^ b) & d) ^ b) + X[10] + 4294925233c = c<<17 | c>>(32-17) + db += (((d ^ a) & c) ^ a) + X[11] + 2304563134b = b<<22 | b>>(32-22) + ca += (((c ^ d) & b) ^ d) + X[12] + 1804603682a = a<<7 | a>>(32-7) + bd += (((b ^ c) & a) ^ c) + X[13] + 4254626195d = d<<12 | d>>(32-12) + ac += (((a ^ b) & d) ^ b) + X[14] + 2792965006c = c<<17 | c>>(32-17) + db += (((d ^ a) & c) ^ a) + X[15] + 1236535329b = b<<22 | b>>(32-22) + c // Round 2.a += (((b ^ c) & d) ^ c) + X[(1+5*0)&15] + 4129170786a = a<<5 | a>>(32-5) + bd += (((a ^ b) & c) ^ b) + X[(1+5*1)&15] + 3225465664d = d<<9 | d>>(32-9) + ac += (((d ^ a) & b) ^ a) + X[(1+5*2)&15] + 643717713c = c<<14 | c>>(32-14) + db += (((c ^ d) & a) ^ d) + X[(1+5*3)&15] + 3921069994b = b<<20 | b>>(32-20) + ca += (((b ^ c) & d) ^ c) + X[(1+5*4)&15] + 3593408605a = a<<5 | a>>(32-5) + bd += (((a ^ b) & c) ^ b) + X[(1+5*5)&15] + 38016083d = d<<9 | d>>(32-9) + ac += (((d ^ a) & b) ^ a) + X[(1+5*6)&15] + 3634488961c = c<<14 | c>>(32-14) + db += (((c ^ d) & a) ^ d) + X[(1+5*7)&15] + 3889429448b = b<<20 | b>>(32-20) + ca += (((b ^ c) & d) ^ c) + X[(1+5*8)&15] + 568446438a = a<<5 | a>>(32-5) + bd += (((a ^ b) & c) ^ b) + X[(1+5*9)&15] + 3275163606d = d<<9 | d>>(32-9) + ac += (((d ^ a) & b) ^ a) + X[(1+5*10)&15] + 4107603335c = c<<14 | c>>(32-14) + db += (((c ^ d) & a) ^ d) + X[(1+5*11)&15] + 1163531501b = b<<20 | b>>(32-20) + ca += (((b ^ c) & d) ^ c) + X[(1+5*12)&15] + 2850285829a = a<<5 | a>>(32-5) + bd += (((a ^ b) & c) ^ b) + X[(1+5*13)&15] + 4243563512d = d<<9 | d>>(32-9) + ac += (((d ^ a) & b) ^ a) + X[(1+5*14)&15] + 1735328473c = c<<14 | c>>(32-14) + db += (((c ^ d) & a) ^ d) + X[(1+5*15)&15] + 2368359562b = b<<20 | b>>(32-20) + c // Round 3.a += (b ^ c ^ d) + X[(5+3*0)&15] + 4294588738a = a<<4 | a>>(32-4) + bd += (a ^ b ^ c) + X[(5+3*1)&15] + 2272392833d = d<<11 | d>>(32-11) + ac += (d ^ a ^ b) + X[(5+3*2)&15] + 1839030562c = c<<16 | c>>(32-16) + db += (c ^ d ^ a) + X[(5+3*3)&15] + 4259657740b = b<<23 | b>>(32-23) + ca += (b ^ c ^ d) + X[(5+3*4)&15] + 2763975236a = a<<4 | a>>(32-4) + bd += (a ^ b ^ c) + X[(5+3*5)&15] + 1272893353d = d<<11 | d>>(32-11) + ac += (d ^ a ^ b) + X[(5+3*6)&15] + 4139469664c = c<<16 | c>>(32-16) + db += (c ^ d ^ a) + X[(5+3*7)&15] + 3200236656b = b<<23 | b>>(32-23) + ca += (b ^ c ^ d) + X[(5+3*8)&15] + 681279174a = a<<4 | a>>(32-4) + bd += (a ^ b ^ c) + X[(5+3*9)&15] + 3936430074d = d<<11 | d>>(32-11) + ac += (d ^ a ^ b) + X[(5+3*10)&15] + 3572445317c = c<<16 | c>>(32-16) + db += (c ^ d ^ a) + X[(5+3*11)&15] + 76029189b = b<<23 | b>>(32-23) + ca += (b ^ c ^ d) + X[(5+3*12)&15] + 3654602809a = a<<4 | a>>(32-4) + bd += (a ^ b ^ c) + X[(5+3*13)&15] + 3873151461d = d<<11 | d>>(32-11) + ac += (d ^ a ^ b) + X[(5+3*14)&15] + 530742520c = c<<16 | c>>(32-16) + db += (c ^ d ^ a) + X[(5+3*15)&15] + 3299628645b = b<<23 | b>>(32-23) + c // Round 4.a += (c ^ (b | ^d)) + X[(7*0)&15] + 4096336452a = a<<6 | a>>(32-6) + bd += (b ^ (a | ^c)) + X[(7*1)&15] + 1126891415d = d<<10 | d>>(32-10) + ac += (a ^ (d | ^b)) + X[(7*2)&15] + 2878612391c = c<<15 | c>>(32-15) + db += (d ^ (c | ^a)) + X[(7*3)&15] + 4237533241b = b<<21 | b>>(32-21) + ca += (c ^ (b | ^d)) + X[(7*4)&15] + 1700485571a = a<<6 | a>>(32-6) + bd += (b ^ (a | ^c)) + X[(7*5)&15] + 2399980690d = d<<10 | d>>(32-10) + ac += (a ^ (d | ^b)) + X[(7*6)&15] + 4293915773c = c<<15 | c>>(32-15) + db += (d ^ (c | ^a)) + X[(7*7)&15] + 2240044497b = b<<21 | b>>(32-21) + ca += (c ^ (b | ^d)) + X[(7*8)&15] + 1873313359a = a<<6 | a>>(32-6) + bd += (b ^ (a | ^c)) + X[(7*9)&15] + 4264355552d = d<<10 | d>>(32-10) + ac += (a ^ (d | ^b)) + X[(7*10)&15] + 2734768916c = c<<15 | c>>(32-15) + db += (d ^ (c | ^a)) + X[(7*11)&15] + 1309151649b = b<<21 | b>>(32-21) + ca += (c ^ (b | ^d)) + X[(7*12)&15] + 4149444226a = a<<6 | a>>(32-6) + bd += (b ^ (a | ^c)) + X[(7*13)&15] + 3174756917d = d<<10 | d>>(32-10) + ac += (a ^ (d | ^b)) + X[(7*14)&15] + 718787259c = c<<15 | c>>(32-15) + db += (d ^ (c | ^a)) + X[(7*15)&15] + 3951481745b = b<<21 | b>>(32-21) + ca += aab += bbc += ccd += ddp = p[chunk:]}dig.s[0] = adig.s[1] = bdig.s[2] = cdig.s[3] = d }func main() {var d digestd.Reset()data := []byte("hello world")d.Write(data)hashnum := d.checkSum()fmt.Printf("%x\n",hashnum)}總結
以上是生活随笔為你收集整理的md5加密算法原理及其GO语言实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分组密码的调用
- 下一篇: 使用 go 实现 Proof of St