Re: 63/64 bit version of Delphi's function random( aRange : integer ) : integer; ?
Available news archives: comp.lang.tcl - comp.lang.python - comp.security.firewalls - sci.crypt - comp.lang.php - comp.lang.javascript
Google
 
Web news.hping.org


sci.crypt archive

Re: 63/64 bit version of Delphi's function random( aRange : integer ) : integer; ?

From: Skybuck Flying <spam@hotmail.com>
Date: Fri Apr 28 2006 - 12:50:28 CEST

This is also an interesting deviation of the test program.

The maximum value is always inputted into the random function and the max
result is recorded ;)

The rest is the same but what the fuck here is the complete code one more
time:

*** Begin of Code ***

program RandomSanityCheck;

{

Reverse Enginering Delphi's Random function from assembler back to pure
delphi.

Mostly to create a 63/64 bit version of the same random function ;)

Mission impossible sir !

Need to known the algorithm to make a 64 bit version ;)

Check out Lehmer's pseudo random number generator alghorithm for thez
algorithm hehe.

}

{

version 0.02 created on 28 april 2006 by Skybuck Flying.

This signed vs unsigned shit is driving me crazy.

Time to cut off some crap code and time to test it to death...

ME MUST KNOW THE ANSWER BEFORE I STOP ;)

CANT GET IT OF MY MIND lol.

MUST GO ON hehehehe.

The VENDETTA music is playing now... messing with my concentration..

but this is not so a difficult task no sir bob...

It's just the last straw =D Wieeeeeeeeeeeeeeee.

Can do that with music on ;) Yes sir bob ! =D

Only doubt is int64 multiplication which will always be signed ?!

Delphi lacks unsigned int64 !?

}

{$APPTYPE CONSOLE}

uses
  SysUtils;

// version 0.04 based on version 0.03
// signed version
var
 vSignedRandSeed : integer;

function RandomSignedSanityCheck( ParaRange : integer ) : integer;
type
 TcombinedRegisters = packed record
 case integer of
  0 :
  (
   // if these are changed to integers many errors occur... ! ;)
// EAX : integer;
// EDX : integer;

   EAX : longword;
   EDX : longword;
  );
  1 :
  (
   Large : int64;
  );
 end;
var
 vCombinedRegisters : TcombinedRegisters;
 vLargeEAX : int64;
 vLargeEDX : int64;
begin

 with vCombinedRegisters do
 begin

  // EAX is probably initialized with the parameter of the function.
  EAX := ParaRange;

// PUSH EBX
  // not necessary

// XOR EBX, EBX
  // not necessary

// IMUL EDX,[EBX].RandSeed,08088405H
  EDX := vSignedRandSeed * $08088405;

// INC EDX
  EDX := EDX + 1;

// MOV [EBX].RandSeed,EDX
  vSignedRandSeed := EDX;

// MUL EDX
// EDX:EAX := EAX * EDX;

  // *** problem code, integer overflow ***
// Large := EAX * EDX;

  vLargeEAX := EAX;
  vLargeEDX := EDX;

  Large := vLargeEAX * vLargeEDX;

// MOV EAX,EDX
  Result := EDX;

// POP EBX
  // not necessary
 end;

end;

// version 0.04 based on version 0.03
// unsigned version
var
 vUnsignedRandSeed : longword;

function RandomUnsignedSanityCheck( ParaRange : longword ) : longword;
type
 TcombinedRegisters = packed record
 case integer of
  0 :
  (
   EAX : longword;
   EDX : longword;
  );
  1 :
  (
   Large : int64;
  );
 end;
var
 vCombinedRegisters : TcombinedRegisters;
 vLargeEAX : int64;
 vLargeEDX : int64;
begin

 with vCombinedRegisters do
 begin

  // EAX is probably initialized with the parameter of the function.
  EAX := ParaRange;

// PUSH EBX
  // not necessary

// XOR EBX, EBX
  // not necessary

// IMUL EDX,[EBX].RandSeed,08088405H
  EDX := vUnsignedRandSeed * $08088405;

// INC EDX
  EDX := EDX + 1;

// MOV [EBX].RandSeed,EDX
  vUnsignedRandSeed := EDX;

// MUL EDX
// EDX:EAX := EAX * EDX;

  // *** problem code, integer overflow ***
// Large := EAX * EDX;

  vLargeEAX := EAX;
  vLargeEDX := EDX;

  Large := vLargeEAX * vLargeEDX;

// MOV EAX,EDX
  Result := EDX;

// POP EBX
  // not necessary
 end;

end;

procedure Main;
var
 vTestMeToDeath : longword;
 vDeath : longword;
 vIndication : longword;

 vSignedResult : integer;
 vUnsignedResult : longword;

 vMaxResult : longword;
begin
 vDeath := $FFFFFFFF;

 vIndication := round(vDeath / 1000);

 vMaxResult := 0;

 // engage ;)
 for vTestMeToDeath := 0 to vDeath do
 begin
// if vIndication > 0 then // dirty little hack to prevent division by zero
by mod ??!!?? weird... but ok.
  if vTestMeToDeath mod vIndication = 0 then
  begin
   writeln('progress: ', ( (vTestMeToDeath / vDeath) * 100 ): 3:1, '%' );
  end;

// vSignedResult := RandomSignedSanityCheck( vTestMeToDeath );
// vUnsignedResult := RandomUnsignedSanityCheck( vTestMeToDeath );

  vSignedResult := RandomSignedSanityCheck( vDeath );
  vUnsignedResult := RandomUnsignedSanityCheck( vDeath );

  if not CompareMem( @vSignedResult, @vUnsignedResult, 4 ) then
  begin
   writeln('Difference detected at index: ', vTestMeToDeath );
   writeln('Signed result is: ', vSignedResult, ' longword typecast:',
longword(vSignedResult) );
   writeln('Unsigned result is: ', vUnsignedResult, ' longword typecast:',
longword(vUnsignedResult) );
   writeln;
   writeln('press enter to continue');
   readln;
  end else
  begin
   if vUnsignedResult > vMaxResult then
   begin
    vMaxResult := vUnsignedResult;
    writeln;
    writeln('Maximum result so far: ', vMaxResult );
    writeln('Absolute maximum is : ', vDeath );
    writeln;
    writeln('Results are the same bitwise');
    writeln('Signed result is: ', vSignedResult, ' longword typecast:',
longword(vSignedResult) );
    writeln('Unsigned result is: ', vUnsignedResult, ' longword typecast:',
longword(vUnsignedResult) );
    writeln;
   end;
  end;

 end;

 writeln('done.');
 writeln;

 writeln( 'press enter to continue' );
 readln;
end;

begin
 try
  Main;
 except
  on E : Exception do
  begin
   writeln('big fucking error happened:');
   writeln( E.Message );

   writeln( 'press enter to continue' );
   readln;
  end;
 end;
end.

*** End of Code ***

The absolute maximum result was indeed generated.

Bye,
  Skybuck.
Received on Mon May 1 02:05:36 2006