Merge pull request #1847 from def-/md5-fixed
Translate md5 module to unsigned numbers
This commit is contained in:
commit
07ccd2dca6
1 changed files with 135 additions and 135 deletions
228
lib/pure/md5.nim
228
lib/pure/md5.nim
|
|
@ -9,15 +9,17 @@
|
||||||
|
|
||||||
## Module for computing MD5 checksums.
|
## Module for computing MD5 checksums.
|
||||||
|
|
||||||
|
import unsigned
|
||||||
|
|
||||||
type
|
type
|
||||||
MD5State = array[0..3, int32]
|
MD5State = array[0..3, uint32]
|
||||||
MD5Block = array[0..15, int32]
|
MD5Block = array[0..15, uint32]
|
||||||
MD5CBits = array[0..7, int8]
|
MD5CBits = array[0..7, uint8]
|
||||||
MD5Digest* = array[0..15, int8]
|
MD5Digest* = array[0..15, uint8]
|
||||||
MD5Buffer = array[0..63, int8]
|
MD5Buffer = array[0..63, uint8]
|
||||||
MD5Context* {.final.} = object
|
MD5Context* {.final.} = object
|
||||||
state: MD5State
|
state: MD5State
|
||||||
count: array[0..1, int32]
|
count: array[0..1, uint32]
|
||||||
buffer: MD5Buffer
|
buffer: MD5Buffer
|
||||||
|
|
||||||
const
|
const
|
||||||
|
|
@ -31,57 +33,57 @@ const
|
||||||
"\0\0\0\0\0\0\0\0" &
|
"\0\0\0\0\0\0\0\0" &
|
||||||
"\0\0\0\0"
|
"\0\0\0\0"
|
||||||
|
|
||||||
proc F(x, y, z: int32): int32 {.inline.} =
|
proc F(x, y, z: uint32): uint32 {.inline.} =
|
||||||
result = (x and y) or ((not x) and z)
|
result = (x and y) or ((not x) and z)
|
||||||
|
|
||||||
proc G(x, y, z: int32): int32 {.inline.} =
|
proc G(x, y, z: uint32): uint32 {.inline.} =
|
||||||
result = (x and z) or (y and (not z))
|
result = (x and z) or (y and (not z))
|
||||||
|
|
||||||
proc H(x, y, z: int32): int32 {.inline.} =
|
proc H(x, y, z: uint32): uint32 {.inline.} =
|
||||||
result = x xor y xor z
|
result = x xor y xor z
|
||||||
|
|
||||||
proc I(x, y, z: int32): int32 {.inline.} =
|
proc I(x, y, z: uint32): uint32 {.inline.} =
|
||||||
result = y xor (x or (not z))
|
result = y xor (x or (not z))
|
||||||
|
|
||||||
proc rot(x: var int32, n: int8) {.inline.} =
|
proc rot(x: var uint32, n: uint8) {.inline.} =
|
||||||
x = toU32(x shl ze(n)) or (x shr toU32(32 -% ze(n)))
|
x = (x shl n) or (x shr (32'u32 - n))
|
||||||
|
|
||||||
proc FF(a: var int32, b, c, d, x: int32, s: int8, ac: int32) =
|
proc FF(a: var uint32, b, c, d, x: uint32, s: uint8, ac: uint32) =
|
||||||
a = a +% F(b, c, d) +% x +% ac
|
a = a + F(b, c, d) + x + ac
|
||||||
rot(a, s)
|
rot(a, s)
|
||||||
a = a +% b
|
a = a + b
|
||||||
|
|
||||||
proc GG(a: var int32, b, c, d, x: int32, s: int8, ac: int32) =
|
proc GG(a: var uint32, b, c, d, x: uint32, s: uint8, ac: uint32) =
|
||||||
a = a +% G(b, c, d) +% x +% ac
|
a = a + G(b, c, d) + x + ac
|
||||||
rot(a, s)
|
rot(a, s)
|
||||||
a = a +% b
|
a = a + b
|
||||||
|
|
||||||
proc HH(a: var int32, b, c, d, x: int32, s: int8, ac: int32) =
|
proc HH(a: var uint32, b, c, d, x: uint32, s: uint8, ac: uint32) =
|
||||||
a = a +% H(b, c, d) +% x +% ac
|
a = a + H(b, c, d) + x + ac
|
||||||
rot(a, s)
|
rot(a, s)
|
||||||
a = a +% b
|
a = a + b
|
||||||
|
|
||||||
proc II(a: var int32, b, c, d, x: int32, s: int8, ac: int32) =
|
proc II(a: var uint32, b, c, d, x: uint32, s: uint8, ac: uint32) =
|
||||||
a = a +% I(b, c, d) +% x +% ac
|
a = a + I(b, c, d) + x + ac
|
||||||
rot(a, s)
|
rot(a, s)
|
||||||
a = a +% b
|
a = a + b
|
||||||
|
|
||||||
proc encode(dest: var MD5Block, src: cstring) =
|
proc encode(dest: var MD5Block, src: cstring) =
|
||||||
var j = 0
|
var j = 0
|
||||||
for i in 0..high(dest):
|
for i in 0..high(dest):
|
||||||
dest[i] = toU32(ord(src[j]) or
|
dest[i] = uint32(ord(src[j])) or
|
||||||
ord(src[j+1]) shl 8 or
|
uint32(ord(src[j+1])) shl 8 or
|
||||||
ord(src[j+2]) shl 16 or
|
uint32(ord(src[j+2])) shl 16 or
|
||||||
ord(src[j+3]) shl 24)
|
uint32(ord(src[j+3])) shl 24
|
||||||
inc(j, 4)
|
inc(j, 4)
|
||||||
|
|
||||||
proc decode(dest: var openArray[int8], src: openArray[int32]) =
|
proc decode(dest: var openArray[uint8], src: openArray[uint32]) =
|
||||||
var i = 0
|
var i = 0
|
||||||
for j in 0..high(src):
|
for j in 0..high(src):
|
||||||
dest[i] = toU8(src[j] and 0xff'i32)
|
dest[i] = src[j] and 0xff'u32
|
||||||
dest[i+1] = toU8(src[j] shr 8'i32 and 0xff'i32)
|
dest[i+1] = src[j] shr 8 and 0xff'u32
|
||||||
dest[i+2] = toU8(src[j] shr 16'i32 and 0xff'i32)
|
dest[i+2] = src[j] shr 16 and 0xff'u32
|
||||||
dest[i+3] = toU8(src[j] shr 24'i32 and 0xff'i32)
|
dest[i+3] = src[j] shr 24 and 0xff'u32
|
||||||
inc(i, 4)
|
inc(i, 4)
|
||||||
|
|
||||||
proc transform(buffer: pointer, state: var MD5State) =
|
proc transform(buffer: pointer, state: var MD5State) =
|
||||||
|
|
@ -92,92 +94,92 @@ proc transform(buffer: pointer, state: var MD5State) =
|
||||||
var b = state[1]
|
var b = state[1]
|
||||||
var c = state[2]
|
var c = state[2]
|
||||||
var d = state[3]
|
var d = state[3]
|
||||||
FF(a, b, c, d, myBlock[0], 7'i8, 0xD76AA478'i32)
|
FF(a, b, c, d, myBlock[0], 7'u8, 0xD76AA478'u32)
|
||||||
FF(d, a, b, c, myBlock[1], 12'i8, 0xE8C7B756'i32)
|
FF(d, a, b, c, myBlock[1], 12'u8, 0xE8C7B756'u32)
|
||||||
FF(c, d, a, b, myBlock[2], 17'i8, 0x242070DB'i32)
|
FF(c, d, a, b, myBlock[2], 17'u8, 0x242070DB'u32)
|
||||||
FF(b, c, d, a, myBlock[3], 22'i8, 0xC1BDCEEE'i32)
|
FF(b, c, d, a, myBlock[3], 22'u8, 0xC1BDCEEE'u32)
|
||||||
FF(a, b, c, d, myBlock[4], 7'i8, 0xF57C0FAF'i32)
|
FF(a, b, c, d, myBlock[4], 7'u8, 0xF57C0FAF'u32)
|
||||||
FF(d, a, b, c, myBlock[5], 12'i8, 0x4787C62A'i32)
|
FF(d, a, b, c, myBlock[5], 12'u8, 0x4787C62A'u32)
|
||||||
FF(c, d, a, b, myBlock[6], 17'i8, 0xA8304613'i32)
|
FF(c, d, a, b, myBlock[6], 17'u8, 0xA8304613'u32)
|
||||||
FF(b, c, d, a, myBlock[7], 22'i8, 0xFD469501'i32)
|
FF(b, c, d, a, myBlock[7], 22'u8, 0xFD469501'u32)
|
||||||
FF(a, b, c, d, myBlock[8], 7'i8, 0x698098D8'i32)
|
FF(a, b, c, d, myBlock[8], 7'u8, 0x698098D8'u32)
|
||||||
FF(d, a, b, c, myBlock[9], 12'i8, 0x8B44F7AF'i32)
|
FF(d, a, b, c, myBlock[9], 12'u8, 0x8B44F7AF'u32)
|
||||||
FF(c, d, a, b, myBlock[10], 17'i8, 0xFFFF5BB1'i32)
|
FF(c, d, a, b, myBlock[10], 17'u8, 0xFFFF5BB1'u32)
|
||||||
FF(b, c, d, a, myBlock[11], 22'i8, 0x895CD7BE'i32)
|
FF(b, c, d, a, myBlock[11], 22'u8, 0x895CD7BE'u32)
|
||||||
FF(a, b, c, d, myBlock[12], 7'i8, 0x6B901122'i32)
|
FF(a, b, c, d, myBlock[12], 7'u8, 0x6B901122'u32)
|
||||||
FF(d, a, b, c, myBlock[13], 12'i8, 0xFD987193'i32)
|
FF(d, a, b, c, myBlock[13], 12'u8, 0xFD987193'u32)
|
||||||
FF(c, d, a, b, myBlock[14], 17'i8, 0xA679438E'i32)
|
FF(c, d, a, b, myBlock[14], 17'u8, 0xA679438E'u32)
|
||||||
FF(b, c, d, a, myBlock[15], 22'i8, 0x49B40821'i32)
|
FF(b, c, d, a, myBlock[15], 22'u8, 0x49B40821'u32)
|
||||||
GG(a, b, c, d, myBlock[1], 5'i8, 0xF61E2562'i32)
|
GG(a, b, c, d, myBlock[1], 5'u8, 0xF61E2562'u32)
|
||||||
GG(d, a, b, c, myBlock[6], 9'i8, 0xC040B340'i32)
|
GG(d, a, b, c, myBlock[6], 9'u8, 0xC040B340'u32)
|
||||||
GG(c, d, a, b, myBlock[11], 14'i8, 0x265E5A51'i32)
|
GG(c, d, a, b, myBlock[11], 14'u8, 0x265E5A51'u32)
|
||||||
GG(b, c, d, a, myBlock[0], 20'i8, 0xE9B6C7AA'i32)
|
GG(b, c, d, a, myBlock[0], 20'u8, 0xE9B6C7AA'u32)
|
||||||
GG(a, b, c, d, myBlock[5], 5'i8, 0xD62F105D'i32)
|
GG(a, b, c, d, myBlock[5], 5'u8, 0xD62F105D'u32)
|
||||||
GG(d, a, b, c, myBlock[10], 9'i8, 0x02441453'i32)
|
GG(d, a, b, c, myBlock[10], 9'u8, 0x02441453'u32)
|
||||||
GG(c, d, a, b, myBlock[15], 14'i8, 0xD8A1E681'i32)
|
GG(c, d, a, b, myBlock[15], 14'u8, 0xD8A1E681'u32)
|
||||||
GG(b, c, d, a, myBlock[4], 20'i8, 0xE7D3FBC8'i32)
|
GG(b, c, d, a, myBlock[4], 20'u8, 0xE7D3FBC8'u32)
|
||||||
GG(a, b, c, d, myBlock[9], 5'i8, 0x21E1CDE6'i32)
|
GG(a, b, c, d, myBlock[9], 5'u8, 0x21E1CDE6'u32)
|
||||||
GG(d, a, b, c, myBlock[14], 9'i8, 0xC33707D6'i32)
|
GG(d, a, b, c, myBlock[14], 9'u8, 0xC33707D6'u32)
|
||||||
GG(c, d, a, b, myBlock[3], 14'i8, 0xF4D50D87'i32)
|
GG(c, d, a, b, myBlock[3], 14'u8, 0xF4D50D87'u32)
|
||||||
GG(b, c, d, a, myBlock[8], 20'i8, 0x455A14ED'i32)
|
GG(b, c, d, a, myBlock[8], 20'u8, 0x455A14ED'u32)
|
||||||
GG(a, b, c, d, myBlock[13], 5'i8, 0xA9E3E905'i32)
|
GG(a, b, c, d, myBlock[13], 5'u8, 0xA9E3E905'u32)
|
||||||
GG(d, a, b, c, myBlock[2], 9'i8, 0xFCEFA3F8'i32)
|
GG(d, a, b, c, myBlock[2], 9'u8, 0xFCEFA3F8'u32)
|
||||||
GG(c, d, a, b, myBlock[7], 14'i8, 0x676F02D9'i32)
|
GG(c, d, a, b, myBlock[7], 14'u8, 0x676F02D9'u32)
|
||||||
GG(b, c, d, a, myBlock[12], 20'i8, 0x8D2A4C8A'i32)
|
GG(b, c, d, a, myBlock[12], 20'u8, 0x8D2A4C8A'u32)
|
||||||
HH(a, b, c, d, myBlock[5], 4'i8, 0xFFFA3942'i32)
|
HH(a, b, c, d, myBlock[5], 4'u8, 0xFFFA3942'u32)
|
||||||
HH(d, a, b, c, myBlock[8], 11'i8, 0x8771F681'i32)
|
HH(d, a, b, c, myBlock[8], 11'u8, 0x8771F681'u32)
|
||||||
HH(c, d, a, b, myBlock[11], 16'i8, 0x6D9D6122'i32)
|
HH(c, d, a, b, myBlock[11], 16'u8, 0x6D9D6122'u32)
|
||||||
HH(b, c, d, a, myBlock[14], 23'i8, 0xFDE5380C'i32)
|
HH(b, c, d, a, myBlock[14], 23'u8, 0xFDE5380C'u32)
|
||||||
HH(a, b, c, d, myBlock[1], 4'i8, 0xA4BEEA44'i32)
|
HH(a, b, c, d, myBlock[1], 4'u8, 0xA4BEEA44'u32)
|
||||||
HH(d, a, b, c, myBlock[4], 11'i8, 0x4BDECFA9'i32)
|
HH(d, a, b, c, myBlock[4], 11'u8, 0x4BDECFA9'u32)
|
||||||
HH(c, d, a, b, myBlock[7], 16'i8, 0xF6BB4B60'i32)
|
HH(c, d, a, b, myBlock[7], 16'u8, 0xF6BB4B60'u32)
|
||||||
HH(b, c, d, a, myBlock[10], 23'i8, 0xBEBFBC70'i32)
|
HH(b, c, d, a, myBlock[10], 23'u8, 0xBEBFBC70'u32)
|
||||||
HH(a, b, c, d, myBlock[13], 4'i8, 0x289B7EC6'i32)
|
HH(a, b, c, d, myBlock[13], 4'u8, 0x289B7EC6'u32)
|
||||||
HH(d, a, b, c, myBlock[0], 11'i8, 0xEAA127FA'i32)
|
HH(d, a, b, c, myBlock[0], 11'u8, 0xEAA127FA'u32)
|
||||||
HH(c, d, a, b, myBlock[3], 16'i8, 0xD4EF3085'i32)
|
HH(c, d, a, b, myBlock[3], 16'u8, 0xD4EF3085'u32)
|
||||||
HH(b, c, d, a, myBlock[6], 23'i8, 0x04881D05'i32)
|
HH(b, c, d, a, myBlock[6], 23'u8, 0x04881D05'u32)
|
||||||
HH(a, b, c, d, myBlock[9], 4'i8, 0xD9D4D039'i32)
|
HH(a, b, c, d, myBlock[9], 4'u8, 0xD9D4D039'u32)
|
||||||
HH(d, a, b, c, myBlock[12], 11'i8, 0xE6DB99E5'i32)
|
HH(d, a, b, c, myBlock[12], 11'u8, 0xE6DB99E5'u32)
|
||||||
HH(c, d, a, b, myBlock[15], 16'i8, 0x1FA27CF8'i32)
|
HH(c, d, a, b, myBlock[15], 16'u8, 0x1FA27CF8'u32)
|
||||||
HH(b, c, d, a, myBlock[2], 23'i8, 0xC4AC5665'i32)
|
HH(b, c, d, a, myBlock[2], 23'u8, 0xC4AC5665'u32)
|
||||||
II(a, b, c, d, myBlock[0], 6'i8, 0xF4292244'i32)
|
II(a, b, c, d, myBlock[0], 6'u8, 0xF4292244'u32)
|
||||||
II(d, a, b, c, myBlock[7], 10'i8, 0x432AFF97'i32)
|
II(d, a, b, c, myBlock[7], 10'u8, 0x432AFF97'u32)
|
||||||
II(c, d, a, b, myBlock[14], 15'i8, 0xAB9423A7'i32)
|
II(c, d, a, b, myBlock[14], 15'u8, 0xAB9423A7'u32)
|
||||||
II(b, c, d, a, myBlock[5], 21'i8, 0xFC93A039'i32)
|
II(b, c, d, a, myBlock[5], 21'u8, 0xFC93A039'u32)
|
||||||
II(a, b, c, d, myBlock[12], 6'i8, 0x655B59C3'i32)
|
II(a, b, c, d, myBlock[12], 6'u8, 0x655B59C3'u32)
|
||||||
II(d, a, b, c, myBlock[3], 10'i8, 0x8F0CCC92'i32)
|
II(d, a, b, c, myBlock[3], 10'u8, 0x8F0CCC92'u32)
|
||||||
II(c, d, a, b, myBlock[10], 15'i8, 0xFFEFF47D'i32)
|
II(c, d, a, b, myBlock[10], 15'u8, 0xFFEFF47D'u32)
|
||||||
II(b, c, d, a, myBlock[1], 21'i8, 0x85845DD1'i32)
|
II(b, c, d, a, myBlock[1], 21'u8, 0x85845DD1'u32)
|
||||||
II(a, b, c, d, myBlock[8], 6'i8, 0x6FA87E4F'i32)
|
II(a, b, c, d, myBlock[8], 6'u8, 0x6FA87E4F'u32)
|
||||||
II(d, a, b, c, myBlock[15], 10'i8, 0xFE2CE6E0'i32)
|
II(d, a, b, c, myBlock[15], 10'u8, 0xFE2CE6E0'u32)
|
||||||
II(c, d, a, b, myBlock[6], 15'i8, 0xA3014314'i32)
|
II(c, d, a, b, myBlock[6], 15'u8, 0xA3014314'u32)
|
||||||
II(b, c, d, a, myBlock[13], 21'i8, 0x4E0811A1'i32)
|
II(b, c, d, a, myBlock[13], 21'u8, 0x4E0811A1'u32)
|
||||||
II(a, b, c, d, myBlock[4], 6'i8, 0xF7537E82'i32)
|
II(a, b, c, d, myBlock[4], 6'u8, 0xF7537E82'u32)
|
||||||
II(d, a, b, c, myBlock[11], 10'i8, 0xBD3AF235'i32)
|
II(d, a, b, c, myBlock[11], 10'u8, 0xBD3AF235'u32)
|
||||||
II(c, d, a, b, myBlock[2], 15'i8, 0x2AD7D2BB'i32)
|
II(c, d, a, b, myBlock[2], 15'u8, 0x2AD7D2BB'u32)
|
||||||
II(b, c, d, a, myBlock[9], 21'i8, 0xEB86D391'i32)
|
II(b, c, d, a, myBlock[9], 21'u8, 0xEB86D391'u32)
|
||||||
state[0] = state[0] +% a
|
state[0] = state[0] + a
|
||||||
state[1] = state[1] +% b
|
state[1] = state[1] + b
|
||||||
state[2] = state[2] +% c
|
state[2] = state[2] + c
|
||||||
state[3] = state[3] +% d
|
state[3] = state[3] + d
|
||||||
|
|
||||||
proc md5Init*(c: var MD5Context) =
|
proc md5Init*(c: var MD5Context) =
|
||||||
## initializes a MD5Context
|
## initializes a MD5Context
|
||||||
c.state[0] = 0x67452301'i32
|
c.state[0] = 0x67452301'u32
|
||||||
c.state[1] = 0xEFCDAB89'i32
|
c.state[1] = 0xEFCDAB89'u32
|
||||||
c.state[2] = 0x98BADCFE'i32
|
c.state[2] = 0x98BADCFE'u32
|
||||||
c.state[3] = 0x10325476'i32
|
c.state[3] = 0x10325476'u32
|
||||||
c.count[0] = 0'i32
|
c.count[0] = 0'u32
|
||||||
c.count[1] = 0'i32
|
c.count[1] = 0'u32
|
||||||
zeroMem(addr(c.buffer), sizeof(MD5buffer))
|
zeroMem(addr(c.buffer), sizeof(MD5buffer))
|
||||||
|
|
||||||
proc md5Update*(c: var MD5Context, input: cstring, len: int) =
|
proc md5Update*(c: var MD5Context, input: cstring, len: int) =
|
||||||
## updates the MD5Context with the `input` data of length `len`
|
## updates the MD5Context with the `input` data of length `len`
|
||||||
var input = input
|
var input = input
|
||||||
var Index = (c.count[0] shr 3) and 0x3F
|
var Index = int((c.count[0] shr 3) and 0x3F)
|
||||||
c.count[0] = c.count[0] +% toU32(len shl 3)
|
c.count[0] = c.count[0] + (uint32(len) shl 3)
|
||||||
if c.count[0] < (len shl 3): c.count[1] = c.count[1] +% 1'i32
|
if c.count[0] < (uint32(len) shl 3): c.count[1] = c.count[1] + 1'u32
|
||||||
c.count[1] = c.count[1] +% toU32(len shr 29)
|
c.count[1] = c.count[1] + (uint32(len) shr 29)
|
||||||
var PartLen = 64 - Index
|
var PartLen = 64 - Index
|
||||||
if len >= PartLen:
|
if len >= PartLen:
|
||||||
copyMem(addr(c.buffer[Index]), input, PartLen)
|
copyMem(addr(c.buffer[Index]), input, PartLen)
|
||||||
|
|
@ -196,7 +198,7 @@ proc md5Final*(c: var MD5Context, digest: var MD5Digest) =
|
||||||
Bits: MD5CBits
|
Bits: MD5CBits
|
||||||
PadLen: int
|
PadLen: int
|
||||||
decode(Bits, c.count)
|
decode(Bits, c.count)
|
||||||
var Index = (c.count[0] shr 3) and 0x3F
|
var Index = int((c.count[0] shr 3) and 0x3F)
|
||||||
if Index < 56: PadLen = 56 - Index
|
if Index < 56: PadLen = 56 - Index
|
||||||
else: PadLen = 120 - Index
|
else: PadLen = 120 - Index
|
||||||
md5Update(c, padding, PadLen)
|
md5Update(c, padding, PadLen)
|
||||||
|
|
@ -241,5 +243,3 @@ when isMainModule:
|
||||||
assert(getMD5("Frank jagt im komplett verwahrlosten Taxi quer durch Bayern") ==
|
assert(getMD5("Frank jagt im komplett verwahrlosten Taxi quer durch Bayern") ==
|
||||||
"7e716d0e702df0505fc72e2b89467910")
|
"7e716d0e702df0505fc72e2b89467910")
|
||||||
assert($toMD5("") == "d41d8cd98f00b204e9800998ecf8427e")
|
assert($toMD5("") == "d41d8cd98f00b204e9800998ecf8427e")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue