Добавить комментарий

Delphi

Случайные числа в Delphi

Самый простой способ получить случайное число - функция Random. Как-то так:

i := random(50); // Число от 0 до 49.

Одна проблема. Оно псевдослучайное.
Внутри random что-то типа такого:

function Random(const ARange: Integer): Integer;
var
  Temp: Integer;
begin
  Temp := RandSeed * $08088405 + 1;
  RandSeed := Temp;
  Result := (UInt64(Cardinal(ARange)) * UInt64(Cardinal(Temp))) shr 32;
end;

Предыдущее псевдослучайное значение используется для генерации следующего. Зная одно, можно однозначно определить другое.

Текущее значение RandSeed доступно и для чтения и для записи, это просто глобальная переменная в модуле System.

Как-то улучшить ситуацию позволяет Randomize. Эта процедура записывает в RandSeed что-нибудь не слишком предсказуемое(на разных платформах по разному): количество тиков процессора от момента старта Windows или значение милисекунд текущего времени и т.д.
Не ахти, но пока вы не занимаетесь криптографией - хватает.

Начиная с процессоров поколения Ivy Bridge, в семействах Intel 64 и IA-32 появились команды для получения значений из аппаратного генератора, соответствующего криптографическим стандартам.

RDRAND

// Проверка поддержки инструкции процессором
function IsRdrandSupport: Boolean; 
asm
  mov eax, $01
  cpuid
  test ecx, 40000000h //тестируем 30-й бит
  setne al
end;

// Получение случайного значения.
function RDRand: DWord;
asm
  @Retry:
  db $0F, $C7, $F0 //RDRAND EAX (CF = 1 говорит о корректности данных)
  jnc @Retry
end;

RDSEED:

// Проверка поддержки инструкции процессором
function IsRdSeedSupport: Boolean;
asm
  mov ecx, 0
  mov eax, $07 // Обращаемся к листу 7
  cpuid
  test ebx, 40000h //тестируем 18-й бит
  setne al
end;

// Получение случайного значения. 
function RDSeed: DWord;
asm 
  @Retry: 
  db $0F, $C7, $F8 //RDSEED EAX (CF = 1 говорит о корректности данных) 
  jnc @Retry 
end;

Как говорит документация Intel, RDSEED более случайная... , что сказывается на времени работы. Она медленнее.

 

Filtered HTML

  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Допустимые HTML-теги: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Строки и абзацы переносятся автоматически.
  • Вы можете цитировать другие сообщения, используя тэг [quote]

Plain text

  • HTML-теги не обрабатываются и показываются как обычный текст
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Строки и абзацы переносятся автоматически.