5

私はキッド シスター暗号化関数を作成しています。OS 間で一貫した結果を生成する PRNG が必要です (ハードウェアやシステム レベルのソフトウェアを利用した浮動小数点演算は必要ありません)。PRNG の期間が 2 30よりも長いため、必要ではありません。

現在、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. そうでない場合、私のニーズに合ったアルゴリズムを知っていますか?
4

2 に答える 2

7

Math::Random::Autoは、有名なメルセンヌ ツイスターPRNG を実装する CPAN モジュールです。

于 2009-03-27T14:09:49.270 に答える
7

LFSR -リニア フィードバック シフト レジスタを使用してみてください。. 外部リンクの最初のリンクには、任意のビット数のランダム性を生成するために必要なものがすべて含まれています。これの良いところは、実装が簡単で、すべての整数演算を使用して実行できることです。

私は 8051 プロジェクトでそれを使用して成功しました。perl を使えば簡単です。

アップデート:

以下は、8 ビット LFSR の簡単な perl 実装です。

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;
    }
}

このコードは単なるプロトタイプです。本番環境で使用したい場合は、おそらくオブジェクトでラップし、レジスタ サイズを構成可能にします。次に、それらの厄介な共有変数を取り除きます。

于 2009-03-27T14:12:25.067 に答える