Up \SpecFunc
unit uIsaac;
{@abstract(High-quality pseudo-random number generator algorithm by © Bob Jenkins, March 1996
Delphi version by Sébastien SAUVAGE http://www.bigfoot.com/)
Modified by Nikolai V. Shokhirev http://www.shokhirev.com/nikolai.html)
Addes function IntRand(N: integer): integer; - get a random value between 0 and N-1
created: June 06, 2002)
last modified: June 06, 2002) }
//Sébastien SAUVAGE
{$OVERFLOWCHECKS OFF}
{ This is ISAAC, a high-quality pseudo-random number generator.
ISAAC is crypto-secure.
ISAAC has no bias.
ISAAC has a minimal garanteed period of 2^40.
ISAAC average period is 2^8295.
ISAAC algorithm is the property of Bob Jenkins.
ISAAC is freely reusable.
ISAAC can be used for encryption (mainly stream cipher).
ISAAC has a 8192 bits seed (read: 8192 bits key for encryption).
ISAAC Object-oriented Delphi implementation version 1.0.0
by Sébastien SAUVAGE <sebsauvage@bigfoot.com>
http://www.bigfoot.com/~sebsauvage
The ISAAC algorihm is freely reusable.
This implementation of ISAAC is freely reusable.
Please let me know if you make interesting uses of this implementation.
Please mention:
ISAAC algorithm by Bob Jenkins (http://burtleburtle.net/bob/)
Delphi ISAAC implementation by Sébastien SAUVAGE <sebsauvage@bigfoot.com>
http://www.bigfoot.com/~sebsauvage
This implementation was tested under Delphi 4, but should work with no
great changes in other versions of Delphi.
This is a readable (not fast) implementation. Code is not optimized.
To get exactly the same results as the C version, you will have to:
- change FALSE to TRUE at line £££1 in code (look for £££1 in code).
- use the following program:
x : TIsaac;
i : integer;
x.InitZero;
x.Isaac; // This is needed to get the same results as readable.c
for i:=0 to 20 write(IntToHex(x.val,8));
Cause : the C implementation inits with a seed although the seed is zero.
The C implementation makes an additional call to Isaac() before reading
values (which is unneeded because Isaac() is called within Init()).
For normal use, you should NOT call Isaac(). This will be done automatically
when needed by val(). You also should leave the boolean value to FALSE
at £££1. This will speedup initialisation at no cost for security.
To Do list:
- faster implementation (unfold loops, etc.)
- even faster implementation (x86 ASM ?)
- create a sample program using this class
- create a utility program that generate an x bytes random data file
with a good seed (time/date/keyboard/mouse?).
- documentation
- methods for gathering random data (time/date/keyboard/mouse/other ?)
- methods to seed with a String, with an integer.
- TIsaacStream ?
- Self-test method, with exception raising on problem.
- TIssacCrypt ? (encryption with a 'password' used as the key.)
I'm no programming God, so please let me know if you find any bug
in this implementation.
Any question regarding this implementation should be sent directly
to sebsauvage@bigfoot.com, *not* to Bob Jenkins.
Bob Jenkins is not responsible for this implementation.
Any question regarding the ISAAC algorithm should be sent directly
to Bob Jenkins, *not* sebsauvage@bigfoot.com.
I'm not responsible for the design of ISAAC.
Paper and C/C++/Modula-2/Java implementations available here:
http://burtleburtle.net/bob/rand/isaac.html
Quote from the author of the ISAAC algorithm:
> My random number generator, ISAAC.
> (c) Bob Jenkins, March 1996
> You may use this code in any way you wish, and it is free. No warrantee.
History:
May, 16th 2000, version 1.0.0
- First implementation.
Usage example:
var
i: integer;
x: TIsaac;
begin
x.Create;
for i:=1 to 20 do Memo1.Lines.Add(IntToHex(x.val, 8));
x.reSeed; // reseed exactly as in Create()
for i:=1 to 20 do Memo1.Lines.Add(IntToHex(x.val, 8)); // get the same values
end;
}
interface
type
TIsaac = class(TObject)
{ private methods }
private
rsl : array[0..255] of Cardinal; { the results given to the user }
mem : array[0..255] of Cardinal; { the internal state }
count: integer; { count through the results in rsl[] }
aa : Cardinal; { accumulator }
bb : Cardinal; { the last result }
cc : Cardinal; { counter, guarantees cycle is at least 2**40 }
procedure Init(flag : boolean); // Initialize the object ;
// should not be called : call }
// Cardinals are unsigned 32 bits values.
// Integers are signed 32 bits values.
{ public methods }
public
constructor Create; overload;
constructor Create(s: array of Cardinal); overload;
procedure reSeed; overload; { Re-seed with a zeroed seed }
procedure reSeed(s: array of Cardinal); overload;{ Re-seed with a given seed }
procedure Isaac(); { generate new numbers }
function val : Cardinal; { get 1 random value }
function IntRand(N: integer): integer; { get a random value between 0 and N-1}
end;
implementation
end.
Up \SpecFunc