@penpen
Thanks for
I have same error on windows 7 32bit.
I have done tests and seems that the code work well, nevertheless.
@Magialisk
I have rewritten the intermediary code for improve understanding. I'm not very good at explaining how does Antonio
. In general, I expect questions from others ...
This is the precedent version that I develop and can be used in the original main without modification (I hope...)
This version is fast and small. Can be used in a macro , but this is next step.
Includes a progress indicator with speed in Bytes/s. The overhead is minimal. If not necessary is possible remove only that part that begin with
(It does not create problem if it is removed)
Code: Select all
(
:do_md5
setlocal
set block=%~1
:: Break the input block into sixteen 32-bit words
set "A=0" & (For /L %%a in (120,-8,0) DO set /a M_!A!=0x!block:~%%a,8!, A+=1) & set block=
:: Initialize this chunk's digest to the running digest value. Initialize Shift-Rotate(S) value
set /a A=!digA0!, B=!digB0!, C=!digC0!, D=!digD0!, S=2
:: Round 1
:: F = (b & c) | ((~b) & d). Wikipedia report F=D xor (B and (C xor D)) faster, but in Dos Set seems slower.
:: Shift-Rotate(S): 7 12 17 22 . Replace variable X with ?
FOR /L %%i IN (0,1,15) DO set /a "S=(S-2) %% 20 +7, ?=A + (B & C | ~B & D) + !Radians[%%i]! + M_%%i, A=D, D=C, C=B, B+=((? << S) | ((? & 0x7FFFFFFF) >> (32-S)))+( (?>>31) & (1<< (S-1)) )"
:: Round 2
:: G = (B & D) | (C & (~D) )
:: Shift-Rotate 5 9 14 20
FOR /L %%i IN (16,1,31) DO (
set /a "S=(%%i %% 4+2)*(%%i %% 4+5)/2, g=(5*%%i+1)%%16"
set /a "?=A + (B & D | C & ~D) + !Radians[%%i]! + M_!g!, A=D, D=C, C=B, B+=((? << S) | ((? & 0x7FFFFFFF) >> (32-S)))+( (?>>31) & (1<< (S-1)) )"
)
:: Round 3
:: 4, 11, 16, 23
:: H = b ^ c ^ d
FOR /L %%i IN (32,1,47) DO (
set /a "S=4+%%i %% 2*7+12*(%%i>>1&1), g=(3*%%i+5)%%16"
set /a "?=A+(B ^^ C ^^ D)+!Radians[%%i]!+M_!g!, A=D, D=C, C=B, B+=((? << S) | ((? & 0x7FFFFFFF) >> (32-S)))+( (?>>31) & (1<< (S-1)) )"
)
:: Round 4
:: 6, 10, 15, 21
:: I = c ^ (b | (~d))
FOR /L %%i IN (48,1,63) DO (
set /a "S=(%%i %% 4+2)*(%%i %% 4+5)/2+1, g=(7*%%i)%%16"
set /a "?=A+(C ^^ (B | ~D))+!Radians[%%i]!+M_!g!, A=D, D=C, C=B, B+=((? << S) | ((? & 0x7FFFFFFF) >> (32-S)))+( (?>>31) & (1<< (S-1)) )"
)
)
:: Add this chunk's result to the running digest value
(endlocal & set /a digA0+=%A%, digB0+=%B%, digC0+=%C%, digD0+=%D%)
::performance i ~ Bytes committed
if "!i:~-2!"=="00" (
if not defined t0 (
for /f %%a in ('copy /Z "%~f0" nul') do set "_CR=%%a"
set t0=!time!
) else (
set "t1=!time!"
for /F "tokens=1-8 delims=:.," %%a in ("!t0: =0!:!t1: =0!") do set /a "A=(((1%%e-1%%a)*60)+1%%f-1%%b)*6000+1%%g%%h-1%%c%%d, A+=(A>>31) & 8640000, _Bytes=i-1600-64, _Bytes+=64, _Bytes_s=_Bytes*100/A"
<nul set/p"=Bytes: !i! - Bytes/s: !_Bytes_s! !_CR!"
set _Bytes_s=
set _Bytes=
set t1=
)
)
exit /b
I'm working on the next version. I have touched the 2000Bytes/s !
This is the average speed for the part that is measured with the code above (::Performance)
There are modification to do in the main for reduce the env for achieve this speed.
I think that you can still squeeze enough!
(My goal is 4096Byte/s
)
Edit: I have seen now Carlos's replay:
@Carlos
Thanks, I have read. The part of code that you have signed is the patch for the Shift Rotate Left. In this part I have included an IF for negative number (ie number with bit number 31 at 1) is this part:" ?>>31 & " it is equivalent at IF !?! lss 0 .....
May look the Antonio's post.
And for the Set /a with a one line is the same that i came to do for achieve higher performace. Thanks for the TipS!
einstein1969