请问 delphi 的 random 算法的随机数是怎样产生的?为什么还要初始化,不初始化的话得出来的数都是一样的?(50分)

  • 主题发起人 microwave
  • 开始时间
M

microwave

Unregistered / Unconfirmed
GUEST, unregistred user!
每次使用随机随机函数时都要写:
Randomize;
n=random(rang);
要是不加:Randomize;
每次运行得出的数都是一样的序列;
 
random只是一个随机数函数,输入为一个“种子”,根据“随机数种子”得到一个序列。
randomize就是获取一个种子的,一般取时钟的毫秒值做种子,这样得到的种子本身也有
很大的随机性。
 
DELPHI的随机数是伪随机数,实际上是完全相同的序列。
对于相同的种子,得到的序列相同
randomize就是为了随机产生一个种子,这样子就会好一些,产生的数字更像是随机数。
 
random的算法是怎样的?为什么产生相同的序列?有没有好一点的随机算法?
 
至于算法,这些语言大同小异,你不必考虑,随机真的很难,但是这样的随机已经够用了,
如果你想增加不可控性,除非是多些不可控的种子,例如可以按键盘两次,每次取得一个
毫秒值,然后用他们的平均数做种子。
 
可否描述一下 Random 算法?
 
用了一个RandSeed种子变量, 一般是再以种子为基础, 取一个很大的质数来取模

在delphi目录中搜索system.pas, 搜索Randomize可以找到以下函数:

procedure Randomize;
{$IFDEF LINUX}
begin
RandSeed := _time(nil);
{$ENDIF}
{$IFDEF MSWINDOWS}
var
systemTime :
record
wYear : Word;
wMonth : Word;
wDayOfWeek : Word;
wDay : Word;
wHour : Word;
wMinute : Word;
wSecond : Word;
wMilliSeconds: Word;
reserved : array [0..7] of char;
end;
asm
LEA EAX,systemTime
PUSH EAX
CALL GetSystemTime
MOVZX EAX,systemTime.wHour
IMUL EAX,60
ADD AX,systemTime.wMinute { sum = hours * 60 + minutes }
IMUL EAX,60
XOR EDX,EDX
MOV DX,systemTime.wSecond
ADD EAX,EDX { sum = sum * 60 + seconds }
IMUL EAX,1000
MOV DX,systemTime.wMilliSeconds
ADD EAX,EDX { sum = sum * 1000 + milliseconds }
MOV RandSeed,EAX
{$ENDIF}
end;


procedure _RandInt;
asm
{ ->EAX Range }
{ <-EAX Result }
PUSH EBX
{$IFDEF PIC}
PUSH EAX
CALL GetGOT
MOV EBX,EAX
POP EAX
MOV ECX,[EBX].OFFSET RandSeed
IMUL EDX,[ECX],08088405H
INC EDX
MOV [ECX],EDX
{$ELSE}
XOR EBX, EBX
IMUL EDX,[EBX].RandSeed,08088405H
INC EDX
MOV [EBX].RandSeed,EDX
{$ENDIF}
MUL EDX
MOV EAX,EDX
POP EBX
end;

procedure _RandExt;
const two2neg32: double = ((1.0/$10000) / $10000)
// 2^-32
asm
{ FUNCTION _RandExt: Extended
}

PUSH EBX
{$IFDEF PIC}
CALL GetGOT
MOV EBX,EAX
MOV ECX,[EBX].OFFSET RandSeed
IMUL EDX,[ECX],08088405H
INC EDX
MOV [ECX],EDX
{$ELSE}
XOR EBX, EBX
IMUL EDX,[EBX].RandSeed,08088405H
INC EDX
MOV [EBX].RandSeed,EDX
{$ENDIF}

FLD [EBX].two2neg32
PUSH 0
PUSH EDX
FILD qword ptr [ESP]
ADD ESP,8
FMULP ST(1), ST(0)
POP EBX
end;

在sysUtils.pas文件中有这一段:
Note: Do not use the generic uuid_generate function in libuuid.so.
In the current implementation (e2fsprogs-1.19), uuid_generate
gives preference to generating guids entirely from random number
streams over generating guids based on the NIC MAC address.
No matter how "random" a random number generator is, it will
never produce guids that can be guaranteed unique across all
systems on the planet. MAC-address based guids are guaranteed
unique because the MAC address of the NIC is guaranteed unique
by the manufacturer.

 
顶部