2009-03-27 12 views
5

Tôi đang viết một hàm kid sister encryption và tôi cần một PRNG tạo ra kết quả nhất quán trên các hệ điều hành (vì vậy không có toán học dấu chấm động, tận dụng phần cứng hoặc phần mềm hệ thống). Nó sẽ là tốt đẹp, nhưng không cần thiết, cho PRNG có một khoảng thời gian dài hơn 2 .Tôi cần một bộ tạo số giả ngẫu nhiên, phù hợp

Tôi hiện đang sử dụng 32 bit 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; 

Nhưng tôi lo lắng vì tôi không thực sự hiểu thế nào nó hoạt động. Ví dụ, nguồn gốc không có khả năng thiết lập hạt giống, vì vậy tôi đã thêm vào, nhưng tôi không biết liệu tôi có chọn đúng biến cho hạt giống hay không.

Vì vậy, tất cả điều đó nắm để

  1. Bạn có biết của một module trên CPAN phù hợp với nhu cầu của tôi?
  2. Nếu không, bạn có biết thuật toán nào phù hợp với nhu cầu của tôi không?

Trả lời

7

Math::Random::Auto là mô-đun CPAN triển khai Mersenne twister PRNG nổi tiếng.

+0

Nhưng nó có nhất quán không? Nếu tôi gieo nó với 5 nó sẽ tạo ra kết quả tương tự trên Linux, BSD, OS X, Win32, v.v. –

+0

Nếu bạn đọc liên kết Wikipedia, bạn sẽ nhận thấy điều đầu tiên mà nó nói trong "Ứng dụng" là nó không phù hợp cho mật mã. – cjm

+0

@cjm: nếu bạn đọc liên kết mã hóa em gái đó, bạn sẽ nhận thấy điều đó có thể không liên quan. – ysth

7

Thử sử dụng LFSR - Linear Feedback Shift Register.. T he first link trên các liên kết bên ngoài có mọi thứ bạn cần để tạo ra bất kỳ số lượng bit ngẫu nhiên nào. Điều tốt đẹp về điều này là nó rất dễ thực hiện và có thể được thực hiện bằng cách sử dụng tất cả các toán học số nguyên.

Tôi đã sử dụng nó với thành công trên dự án 8051. Với perl nó sẽ là một snap.

Cập nhật:

Dưới đây là một việc thực hiện perl nhanh chóng của một LFSR 8 bit:

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

Mã này chỉ là một nguyên mẫu. Nếu tôi muốn sử dụng nó trong sản xuất tôi có thể quấn nó trong một đối tượng và làm cho kích thước đăng ký cấu hình. Sau đó, chúng tôi sẽ loại bỏ các biến được chia sẻ pesky đó.

+0

Nhấp qua wiki sẽ hiển thị toàn bộ các chức năng hấp dẫn. Đây chỉ là gọn gàng. – jettero