Sign in Join
Wiki copytemporary

Delphi compatible LCG Random: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11### Delphi compatible random numbers
22
33Many Free Pascal programmers also maintain sourcecode in Delphi.\
44Even if you have moved to Free Pascal from Delphi you may have data that relies on Delphi's Random.\
55Here are cross-platform functions that generate Delphi-identical pseudo-random numbers given the same RandSeed:
66
77``` pascal
88unit lcg_random;
99// Delphi compatible LCG random number generator routines for Free Pascal.
1010// (c)2017, Thaddy de Koning. Use as you like
1111// Algorithm, Delphi multiplier and increment taken from:
1212// https://en.wikipedia.org/wiki/Linear_congruential_generator
1313// The default Delphi RandomSeed is determined as zero.
1414{$ifdef fpc}{$mode objfpc}{$endif}
1515
1616interface
1717
1818function LCGRandom: extended; overload;inline;
1919function LCGRandom(const range:longint):longint;overload;inline;
2020
2121implementation
2222
2323function IM:cardinal;inline;
2424begin
2525 RandSeed := RandSeed * 134775813 + 1;
2626 Result := RandSeed;
2727end;
2828
2929function LCGRandom: extended; overload;inline;
3030begin
3131 Result := IM * 2.32830643653870e-10;
3232end;
3333
3434function LCGRandom(const range:longint):longint;overload;inline;
3535begin
3636 Result := IM * range shr 32;
3737end;
3838
3939end.
4040```
4141
42-\
4342A small demo
4443
4544``` pascal
4645program lcgdemo;
4746// Compile and run in both Delphi and FPC and compare the output.
4847// It is exactly the same
4948{$ifdef fpc}{$mode objfpc}
5049{$Macro on}{$define random := LCGRandom}
5150{$endif}
5251{$ifdef mswindows}{$apptype console}{$endif}
5352uses lcg_random;
5453
5554var i:integer;
5655begin
5756 RandSeed := 999; // default delphi randseed is zero
5857 for i := 1 to 20 do
5958 begin
6059 write(Random(100):4); // Delphi: Random FPC:LCGRandom. See macro
6160 if i mod 5 = 0 then writeln;
6261 end;
6362
6463 RandSeed := 999; // default delphi randseed is zero
6564 for i := 1 to 20 do
6665 begin
6766 write(Random:4:8,' ');// Delphi: Random FPC:LCGRandom
6867 if i mod 5 = 0 then writeln;
6968 end;
7069 Readln;
7170end.
7271```
7372
7473Here is another one with the randseed factored out. You can use that for non-delphi compatible purposes:
7574
7675``` pascal
7776unit lcg_random2;
7877// Delphi compatible LCG random number generator routines for Freepascal.
7978// (c)2017, Thaddy de Koning. Use as you like
8079// Algorithm, Delphi multiplier and increment taken from:
8180// https://en.wikipedia.org/wiki/Linear_congruential_generator
8281// The default Delphi RandomSeed is determined as zero.
8382//
8483// In this version the system randseed is factored out.
8584{$ifdef fpc}{$mode objfpc}{$endif}{$J+}
8685
8786interface
8887const
8988 RandSd:cardinal = 0;
9089
9190function LCGRandom: extended; overload;inline;
9291function LCGRandom(const range:longint):longint;overload;inline;
9392
9493implementation
9594
9695function IM:cardinal;inline;
9796begin
9897 RandSd := RandSd * 134775813 + 1;
9998 Result := RandSd;
10099end;
101100
102101function LCGRandom: extended; overload;inline;
103102begin
104103 Result := IM * 2.32830643653870e-10;
105104end;
106105
107106function LCGRandom(const range:longint):longint;overload;inline;
108107begin
109108 Result := IM * range shr 32;
110109end;
111110
112111end.
113112```
114113
115114You can use this for example for simple encryption and decryption based on the predictability and repeatability of a any Pseudo Random Number Generator:
116115
117116``` pascal
118117program cryptrandom;
119118{$mode objfpc}{$modeswitch typehelpers}{$H+}
120119{ This is demo that you can actually use random to encrypt/decrypt.
121120 This is due to the nature of a Pseudo Random Number Generator,
122121 where given a certain random seed, the sequence is predictable.
123122 Here I use the Random Seed as a key to encrypt/decrypt a string.
124123 The same code would also work with the Default random from FreePascal,
125124 but it is better not to touch system.randseed, So I used a different
126125 Random.
127126
128127 Have fun, Thaddy}
129128uses
130129lcg_random2;
131130
132131
133132function Crypt(const value:AnsiString;const Key:Cardinal):AnsiString;
134133var
135134 i:integer;
136135begin
137136 RandSd := Key;
138137 SetLength(Result,Length(Value));
139138 for i := 1 to length(Value) do
140139 Result[i] := Chr(Ord(Value[i]) xor lcgrandom(255));
141140end;
142141
143142var
144143 a:AnsiString;
145144begin
146145 a:='This is the text to encrypt/decrypt.';
147146 writeln(a);
148147 writeln('Encrypting..');
149148 a:=Crypt(a, 12345);
150149 writeln(a);
151150 writeln('Decrypting..');
152151 a:=Crypt(a, 12345);
153152 writeln(a);
154153end.
155154```
156155
157156### See also
158157
1591581. [LCG on wikipedia](https://en.wikipedia.org/wiki/Linear_congruential_generator)
1601592. [[Generating Random Numbers]]
161160
162161## See also
163162
164163- [Wikipedia article on the linear congruential generator algorithm](http://en.wikipedia.org/wiki/Linear_congruential_generator)
165164
166165---
167166*From the Free Pascal wiki, page "Delphi compatible LCG Random", as it stood on 2024-05-14 after a change by Alextp, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
168167Category: Modelling and Simulation
169168Category: Statistical algorithms

Back to history