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 - 08:52:43 CEST

And finally here it is...

A working version of delphi's random function in pure delphi.

I still don't understand the overflow problem... and I am getting quite
tired of all this shit ;)

So I simply took the lazy way and copied the problem variables to larger
variables to do the multiplication etc.

So far version 0.03 is working quite nicely...

The only thing left to do now is create a 64 bit version which should be
quite easy... or maybe... I'll get another round of integer overflow
problems with larger values... that would suck ;) since there are no 128
bit types in delphi... oh oh. Or maybe a double could fix the problem.. or
some other method ;)

Here is the update code:

*** Begin of Code ***

program Project1;

{

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 ;)

version 0.01 created on 28 april 2006 by Skybuck Flying.

Routine version 0.03 is the fixed routine and produces the same results
so far ;)

}

{$APPTYPE CONSOLE}

uses
  SysUtils;

// version 0.01, problem integer overflow.
function PureDelphiRandom1( ParaRange : integer ) : integer;
type
 TcombinedRegisters = packed record
 case integer of
  0 :
  (
   EAX : longword;
   EDX : longword;
  );
  1 :
  (
   Large : int64;
  );
 end;
var
 vCombinedRegisters : TcombinedRegisters;
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 := RandSeed * $08088405;

// INC EDX
  EDX := EDX + 1;

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

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

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

// MOV EAX,EDX
  Result := EDX;

// POP EBX
  // not necessary
 end;
end;

// version 0.02, problem still integer overflow.
function PureDelphiRandom2( ParaRange : integer ) : integer;
type
 TcombinedRegisters = packed record
 case integer of
  0 :
  (
   EAX : longword;
   EDX : longword;
  );
  1 :
  (
   Large : int64;
  );
 end;
var
 vCombinedRegisters1 : TcombinedRegisters;
 vCombinedRegisters2 : TcombinedRegisters;
begin

 with vCombinedRegisters1 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 := RandSeed * $08088405;

// INC EDX
  EDX := EDX + 1;

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

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

  // *** problem code, still integer overflow ***
  // problem seems to be with multiplication itself
  // variables too small ? strange
  // going to inspect it.
  vCombinedRegisters2.Large := int64(EAX * EDX);

// MOV EAX,EDX
  Result := vCombinedRegisters2.EDX;

// POP EBX
  // not necessary
 end;
end;

// version 0.03, fixed the problem the lazy way ;)
function PureDelphiRandom3( ParaRange : integer ) : integer;
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 := RandSeed * $08088405;

// INC EDX
  EDX := EDX + 1;

// MOV [EBX].RandSeed,EDX
  RandSeed := 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;

var
 mTransferSize : int64;
 mOffset : int64;
 CopyOfRandSeed : longint;
 I : integer;
begin
 mTransferSize := 1024*1024*10; // 10 MB ;) well in range of 32 bits.

// CopyOfRandSeed := 0;

 for I := 1 to 10 do
 begin
  CopyOfRandSeed := RandSeed; // store original randseed
  mOffset := Random( mTransferSize );
  writeln( 'Original Random: ', mOffset );

  // call to flawed version
{
  RandSeed := CopyOfRandSeed; // restore original rand seed
  mOffset := PureDelphiRandom1( mTransferSize );
  writeln( 'Pure Delphi Random: ', mOffset );
}

  // call to corrected/fixed version
  RandSeed := CopyOfRandSeed; // restore original rand seed
  mOffset := PureDelphiRandom3( mTransferSize );
  writeln( 'Pure Delphi Random: ', mOffset );

  writeln;
 end;

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

*** End of Code ***

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