1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
{ ******************************************************************
UVAG The Universal Virtual Array Generator
by Alex Hay zenjew@hotmail.com
Adapted to TPMath by Jean Debord
******************************************************************
In practice, Cardinal (6-7 times the output of Word) is the
IntType of choice, but to demonstrate UVAG's scalability here,
IntType can be defined as any integer data type. IRanUVAG globally
provides (as rndint) an effectively infinite sequence of IntTypes,
uniformly distributed (0, 2^(8*sizeof(IntType))-1). Output (bps)
is dependent solely on IntSize=sizeof(IntType) and CPU speed. UVAG
cycles at twice the speed of the 64-bit Mersenne Twister in a tenth
the memory, tests well in DIEHARD, ENT and NIST and has a huge period.
It is suitable for cryptographic purposes in that state(n) is not
determinable from state(n+1). Most attractive is that it uses integers
of any size and requires an array of only 255 + sizeof(IntType) bytes.
Thus it is easily adapted to 128 bits and beyond with negligible
memory increase. Lastly, seeding is easy. From near zero entropy
(s[]=0, rndint > 0), UVAG bootstraps itself to full entropy in under
300 cycles. Very robust, no bad seeds.
****************************************************************** }
unit uranuvag;
interface
type
IntType = LongInt;
procedure InitUVAGbyString(KeyPhrase : string);
{ Initializes the generator with a string }
procedure InitUVAG(Seed : IntType);
{ Initializes the generator with an integer }
function IRanUVAG : IntType;
{ Returns a 32-bit random integer }
implementation
const
IntSize = SizeOf(IntType);
type
TByteArray = array[0..(255 + IntSize)] of Byte;
var
s : TByteArray;
sp : ^IntType; { Pointer to random IntType somewhere in s }
sindex : Byte;
rndint : IntType;
procedure InitUVAGbyString(KeyPhrase : string);
var
i, kindex, lk : Word;
temp, tot : Byte;
begin
lk := Length(KeyPhrase);
kindex := 1;
tot := 0;
{ Initialize array }
for i := 0 to 255 do
s[i] := i;
for i := 256 to (255 + IntSize) do
s[i] := i - 256;
{ Shuffle array on keyphrase }
for i := 0 to (255 + IntSize) do
begin
tot := tot + Ord(KeyPhrase[kindex]);
temp := s[i];
s[i] := s[tot];
s[tot] := temp;
kindex := kindex + 1;
if kindex > lk then kindex := 1; { wrap around key }
end;
sindex := s[0];
rndint := 0
end;
procedure InitUVAG(Seed : IntType);
var
S : string;
begin
Str(Seed, S);
InitUVAGbyString(S);
end;
function IRanUVAG : IntType;
begin
sindex := sindex + 1;
sp := @s[s[sindex]];
sp^ := sp^ + rndint;
rndint := rndint + sp^;
IRanUVAG := rndint
end;
end.
|