Генератор псевдослучайных чисел. Повышаем криптостойкость. Алгоритмы шифрования
В это статье я расскажу, как можно улучшить генератор псевдослучайных чисел, а именно как сделать так чтобы числа были более случайными.Все знают что криптостойкость некоторых алгоритмов шифрования (или почти всех) сильно зависит от того насколько непредсказуемы числа выдаваемые генератором псевдо-случайных чисел (ГПСЧ), который использует тот или иной алгоритм шифрования. В связи этим возникает понятие криптостойкости ГПСЧ, чем более непредсказуем ГСПЧ тем выше его криптостойкость. Другими словами я расскажу, как можно повысить криптостойкость генератора псевдо-случайных чисел.
Для начала надо разобраться с общим принципом работы ГПСЧ. У любого ГПСЧ есть некоторое значение (переменная), которое текущее значение которой и является случайным значением, назовём эту переменную RandSeed, его также принято называть инициализатором ГПСЧ (по крайнем мере я его так называю, вы называйте, как хотите смысл не меняется). При вызове функции Randomize() происходит присваивание переменной RandSeed некоторого значения, которое извлекается от системного таймера или другого источника, значение которого трудно предсказать. В разных языках программирования всё по разному, в некоторых надо самому передать функции Randomize инициализирующее значение. При вызове функции Random происходят некоторые операции со значением RandSeed, операции могут быть любыми, всё зависит от реализации ГПСЧ, важно то, что вычисления всегда одни и те же, отсюда и предсказуемость ГПСЧ. Новое значение RandSeed и будет являться результатом выполнения функции Random. В некоторых языках надо самому подгонять полученное значение в нужный диапазон в некоторых, функция Random сама подгонит результат в нужный диапазон. Но почти всегда это будет остаток от деления, полученного случайного значения на диапазон.
Теперь ближе к делу, попробуем написать свой собственный ГПСЧ.
int Random()
{
RandSeed = (214013* RandSeed +2531011);
return (RandSeed >>16)&0x7FFF;
}
Эта функция возвращает случайное 16-битное значение.
Получение случайного 32-битного значения будет выглядеть так:
@@random32:
call @@random16
push eax
call @@random16
shl eax, 16
or eax, [esp]
add esp, 4
ret
Если нам нужно случайное значение от 0 до 100, то достаточно просто разделить полученное значение разделить на 100, остаток от деления и будет необходимым случайным значением. Теперь необходимо протестировать всю эту красоту.
procedure TForm1.TestRandom(RandFunc: TRandFunc; InitVal:DWORD);
var
i, j, v :integer;
counts:array[0..255] of Integer;
str:string;
avg:double;
begin
MyRandomize(InitVal);
avg:=0;
for i:=1 to 1000000 do
avg:=avg+ (RandFunc() mod 100);
avg:=avg/1000000;
lblAVG_Val.Caption:='Среднее значение '+FloatToStr(avg);
for i:=0 to 255 do
counts:=0;
MyRandomize(InitVal);
for i:=1 to 100000 do
begin
v:=RandFunc() mod 256;
inc(counts[v]);
Canvas.Pixels[counts[v], v+ 50]:=clBlack;
end;
MyRandomize(InitVal);
//ShowMessage(inttostr(InitVal));
for i:=1 to 10000 do
Canvas.Pixels[RandFunc() mod 200, 320+(RandFunc() mod 200)]:=clBlack;
mmoVals.Clear;
for i:=1 to 100 do
begin
MyRandomize(InitVal);
str:=inttostr(RandFunc() mod 100);
for j:=2 to 24 do RandFunc();
str:=str+' '+ IntToStr(RandFunc() mod 100);
for j:=26 to 99 do RandFunc();
str:=str+' '+ IntToStr(RandFunc() mod 100);
mmoVals.Lines.add(str);
end;
end;
0 комментариев