- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In case anyone is trying to use the code from this forum post:
https://community.intel.com/t5/Intel-Fortran-Compiler/MD5-Hash/td-p/801183
I wanted to let folks know that there was a bug I fixed that might be helpful to someone in the future.
I changed this line of code:
character*((int(len(string)/64)+1)*64) newString
to:
character*((int((len(string)+8)/64)+1)*64) newString
The inclusion of the "+8" allows for the 8 bit length portion of the MD5 padding spec to be accounted for and prevent string overflows for strings that need fewer than 8 bits of padding.
Not that this code is being used many places....I just recently used it and had to debug/fix the issue so figured I'd post about it just in case.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for that fix! Also had to fix the "blank" rather than "0" bug in the original code -- using a "z8.8" format.
Then turned it into a module. Here it is:
module md5_hash
contains
! **********************************************************************
character*32 function md5(string)
! ---------------------------------------------------------------------*
! Programmierer : VEZ2/Pieper *
! Version : 1.0 *
! letzte nderung : 07.05.2010 *
! Aufgabe : Erzeugt aus einem String einen MD5 Hashwert *
! **********************************************************************
implicit none
character*(*), intent(in) :: string
character*((int((len(string)+8)/64)+1)*64) newString
character*8 wtmp
integer(kind=4) j,n1,n2,n3,n4,pos
integer(kind=4) r(64),k(64),h0,h1,h2,h3,a,b,c,d,f,g,temp,w(16),i,intLen
integer(kind=8) hoch32
real(kind=8) sinus,absolut,real8i
r = [ 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, &
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, &
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, &
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]
do i=1,64
real8i = floatk(int8(i))
sinus = dsin(real8i)
absolut = dabs(sinus)
hoch32 = 2.**32.
k(i) = int8(absolut * floatk(hoch32))
enddo
h0 = #67452301
h1 = #EFCDAB89
h2 = #98BADCFE
h3 = #10325476
j = len(string)+1
newString(:j) = string // char(128)
i = mod(j, 64)
do while(i /= 56)
j = j + 1
newString(j:j) = char(0)
i = mod(j, 64)
enddo
intLen = len(string)*8
do i = 0,3
temp = intLen .and. #FF
j = j + 1
newString(j:j) = char(temp)
intLen = shiftr(intLen, 8)
enddo
do i = 1,4
j = j + 1
newString(j:j) = char(0)
enddo
do i = 1,int(len(newString)/64)
do j = 1,16
pos = (j-1)*4+(i-1)*64
n1 = ichar(newString(4+pos:4+pos))
n2 = ichar(newString(3+pos:3+pos))
n3 = ichar(newString(2+pos:2+pos))
n4 = ichar(newString(1+pos:1+pos))
write(wtmp,'(4(z2.2))') n1,n2,n3,n4
read(wtmp,'(z8)') w(j)
enddo
a = h0
b = h1
c = h2
d = h3
do j = 1,64
if (j >= 1 .and. j <= 16) then
f = (b .and. c) .or. ((.not. b) .and. d)
g = j
else if (j >= 17 .and. j <= 32) then
f = (d .and. b) .or. ((.not. d) .and. c)
g = mod(5*(j-1) + 1, 16) + 1
else if (j >= 33 .and. j <= 48) then
f = ieor(b, ieor(c, d))
g = mod(3*(j-1) + 5, 16) + 1
else if (j >= 49 .and. j <= 64) then
f = ieor(c, (b .or. (.not. d)))
g = mod(7*(j-1), 16) + 1
endif
temp = d
d = c
c = b
b = b + leftrotate((a + f + k(j) + w(g)) , r(j))
a = temp
enddo
h0 = h0 + a
h1 = h1 + b
h2 = h2 + c
h3 = h3 + d
enddo
h0 = umdrehen(h0)
h1 = umdrehen(h1)
h2 = umdrehen(h2)
h3 = umdrehen(h3)
write(md5,'(4(z8.8))') h0,h1,h2,h3
return
endfunction
! **********************************************************************
pure function leftrotate (x, c) result(i4value)
! ---------------------------------------------------------------------*
! Programmierer : VEZ2/Pieper *
! Version : 1.0 *
! letzte nderung : 07.05.2010 *
! Aufgabe : Fhrt ein Leftrotate der Bits durch *
! **********************************************************************
implicit none
integer*4, intent(in) :: x, c
integer*4 :: i4value
integer*4 result1,result2
result1 = shiftl(x,c)
result2 = shiftr(x, (32-c))
i4value = result1 .or. result2
return
endfunction
! **********************************************************************
pure function umdrehen(zahl_input) result(i4value)
! ---------------------------------------------------------------------*
! Programmierer : VEZ2/Pieper *
! Version : 1.0 *
! letzte nderung : 07.05.2010 *
! Aufgabe : Macht aus Big Endian -> Little Endian Bits *
! **********************************************************************
implicit none
integer*4, intent(in) :: zahl_input
integer*4 :: i4value
integer*4 i,tmp,zahl
zahl = zahl_input
i4value = 0
do i = 1,4
i4value = shiftl(i4value, 8)
tmp = zahl .and. #FF
i4value = i4value + tmp;
zahl = shiftr(zahl, 8)
enddo
return
endfunction
endmodule
Here is a test program:
program md5_test
use md5_hash
character*32 md5_test_1 / "9EAB500708CAD82AAD8E156BDA5ED03A" /
character*32 md5_test_2 / "F2F8F10BE9359F85503A242DE2E0665B" /
character*32 md5_test_3 / "7215EE9C7D9DC229D2921A40E899EC5F" /
character*32 c32
character*100 ctest
ctest = "TestString1"
c32 = md5(trim(ctest))
if( c32 /= md5_test_1 )then
write(*,'(4A)') 'Mismatch! md5=',c32,' vs ',md5_test_1
else
write(*,'(4A)') 'Test #1 of md5 is Ok! md5("',trim(ctest),'") is: ',c32
endif
write(*,*)
ctest = "SecondTestString"
c32 = md5(trim(ctest))
if( c32 /= md5_test_2 )then
write(*,'(4A)') 'Mismatch! md5=',c32,' vs ',md5_test_2
else
write(*,'(4A)') 'Test #2 of md5 is Ok! md5("',trim(ctest),'") is: ',c32
endif
write(*,*)
c32 = md5(" ")
if( c32 /= md5_test_3 )then
write(*,'(4A)') 'Mismatch! md5=',c32,' vs ',md5_test_3
else
write(*,'(4A)') 'Test #3 of md5 is Ok! md5(" ") is: ',c32
endif
endprogram
Which I compared to output from the Windows certutil utility program:
certutil -hashfile testfile.txt md5

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page