2009-03-27 3 views
5

Я пишу функцию kid sister encryption, и мне нужен PRNG, который дает согласованные результаты по всем операционным системам (поэтому нет математики с плавающей запятой, используя аппаратное обеспечение или программное обеспечение на уровне системы). Было бы неплохо, но не обязательно, поскольку PRNG имел период более 2 .Мне нужен портативный, последовательный генератор псевдослучайных чисел

Я в настоящее время использую 32 бит Xorshift:

#!/usr/bin/perl 

use strict; 
use warnings; 

{ 
    use integer; #use integer math 
    my $x = 123456789; 
    my $y = 362436069; 
    my $w = 88675123; 
    my $z = 521288629; 

    sub set_random_seed { 
     $w = shift; 
    } 

    sub random { 
     my $t = $x^($x << 11); 
     $x = $y; 
     $y = $z; 
     $z = $w; 
     my $rand = $w = ($w^($w >> 19))^($t^($t >> 8)); 
     return $rand % 256; #scale it back to a byte at a time 
    } 
} 

set_random_seed(5); 
print map { random(), "\n" } 1 .. 10; 

Но я волнуюсь, потому что я не очень понимаю, как это работает. Например, исходный источник не имел возможности устанавливать семя, поэтому я добавил его, но я не знаю, выбрал ли я правильную переменную для семени.

Таким образом, все, что сводится к

  1. Вы знаете модуль на CPAN, который соответствует моим потребностям?
  2. Если нет, знаете ли вы алгоритм, который соответствует моим потребностям?

ответ

7

Math::Random::Auto является модулем CPAN, реализующим хорошо известный Mersenne twister PRNG.

+0

Но неужели это согласовано? Если я засеваю его 5, он даст те же результаты в Linux, BSD, OS X, Win32 и т. Д. –

+0

Если вы прочтете эту ссылку в Википедии, вы заметите, что первое, что говорится в «Заявке», заключается в том, что она не подходит для криптографии. – cjm

+0

@cjm: если вы прочтете эту шифрующую ссылку на сестру ребенка, вы заметите, что это, вероятно, не имеет значения. – ysth

7

Попробуйте использовать LFSR - Linear Feedback Shift Register.. T he first link на внешних ссылках имеет все необходимое для создания любого количества бит случайности. Самое приятное в этом состоит в том, что его легко реализовать и можно сделать, используя все математические целые числа.

Я использовал его с успехом на проекте 8051. С perl это будет быстро.

Update:

Вот быстрое внедрение Perl из 8 битного LFSR:

use strict; 
use warnings; 

use List::Util qw(reduce); 
use vars qw($a $b); 

print 'Taps: ', set_taps(8, 7, 2, 1), "\n"; 
print 'Seed: ', seed_lfsr(1), "\n"; 
print read_lfsr(), "\n" for 1..10; 

BEGIN { 
    my $tap_mask; 
    my $lfsr = 0; 

    sub read_lfsr { 
     $lfsr = ($lfsr >> 1)^(-($lfsr & 1) & $tap_mask); 

     return $lfsr; 
    } 

    sub seed_lfsr { 
     $lfsr = shift || 0; 
     $lfsr &= 0xFF; 
    } 

    sub set_taps { 
     my @taps = @_; 

     $tap_mask = reduce { $a + 2**$b } 0, @taps; 

     $tap_mask >>= 1; 

     $tap_mask &= 0xFF; 

     return $tap_mask; 
    } 
} 

Этот код просто прототип. Если бы я хотел использовать его в процессе производства, я бы, вероятно, обернул его в объект и сделал размер регистра настраиваемым. Тогда мы избавимся от этих досадных общих переменных.

+0

Щелчок по вики показывает целое семейство увлекательных функций. Это просто аккуратно. – jettero

Смежные вопросы