Perl 为什么兰德($val)在$val>;时不发出警告;2**兰比特?
我使用Perl 为什么兰德($val)在$val>;时不发出警告;2**兰比特?,perl,Perl,我使用v5.16.2通过重复调用来构造一些伪数据。在经历了相当多的困惑之后,我发现因为我的perl的randbits=15,上面的表达式将只返回2**15或32768可能的值 >perl -V:randbits randbits='15'; 我的问题是: 当有人试图使用rand$valwhere$val>2**randbits时,为什么不返回警告 为什么不提这个问题呢?有一个附录说明了“rand()如何在加密方面不安全”。我认为,这也值得一份附录,并提出替代解决方案 设置 我试图创建
v5.16.2
通过重复调用来构造一些伪数据。在经历了相当多的困惑之后,我发现因为我的perl的randbits=15
,上面的表达式将只返回2**15
或32768
可能的值
>perl -V:randbits
randbits='15';
我的问题是:
- 当有人试图使用
whererand$val
时,为什么不返回警告$val>2**randbits
- 为什么不提这个问题呢?有一个附录说明了
。我认为,这也值得一份附录,并提出替代解决方案“rand()如何在加密方面不安全”
p
为(999\u 999/1\u 000\u 000)**20\u 000\u 000
或2.06e-9
。因此,任何整数不被选择的概率是.2%
我迅速拼凑出另一个脚本,以确认我的假数据生成器中没有缺陷:
use strict;
use warnings;
use List::Util qw(sum max min);
our $max_count = 1_000;
my %count;
while (1) {
my $val = int rand 1_000_000;
last if ++$count{$val} > $max_count;
}
my $sum = sum values %count;
my $max = max values %count;
my $min = min values %count;
my $count = scalar keys %count;
print "$sum interations. $count integers of expected 1mil with min $min, max $max\n";
产出:
28,958,579 interations. 32768 integers of expected 1mil with min 772, max 1001
显然,32768
是2
强大的一面巨大的红旗,因此快速搜索返回了以下有用的资源:
rand
SO post提供了一个不需要安装新模块的解决方案,只需调用rand
两次即可获得更多比特
use Config;
use constant RANDBITS => $Config{randbits};
use constant RAND_MAX => 2**RANDBITS;
sub double_rand {
my $max = shift || 1;
my $iv =
int rand(RAND_MAX) << RANDBITS
| int rand(RAND_MAX);
return $max * ($iv / 2**(2*RANDBITS));
}
使用Config;
使用常量RANDBITS=>$Config{RANDBITS};
使用常数RAND_MAX=>2**RANDBITS;
亚双色兰{
我的$max=shift | | 1;
我的四美元=
int rand(rand_MAX)你看过了吗?似乎有一些合适的资源。Math::BigInt::Random对于非常大的数字来说似乎是一个很好的资源。对于非加密目的,使用。具有很好的属性
您可以使用功能界面作为内置的rand
替代品:
面向功能的接口:
是时候升级perl了
从
rand
现在使用一致的随机数生成器
以前,perl将使用特定于平台的随机数生成器,在libc rand()、random()或drand48()之间变化
这意味着perl随机数的质量会因平台而异,从Windows上的15位rand()到POSIX平台上的48位,如Linux with drand48()
Perl现在在所有平台上都使用自己的内部drand48()实现。这并不能使Perl的rand
加密安全
我仍然希望旧版本的perl在使用rand
时,当值大于2**randbits
时会发出警告,但这是我所希望的最好结果
仍然需要注意Windows上的其他程序员,并继续推荐替代方案,例如如果他们无法升级。它是否应该为rand(1000)发出警告?因为这也是有偏见的。re“我是否安装了草莓Perl,以如此低的randbits结束?”,不,这是C库提供的。re“是否有更好的替代品替代兰德?”,如文件中所述,CPAN提供了加密质量的随机数生成器。@ikegami我认为,rand
文件已经在附录中提到了rand(1000)
不“加密安全”的偏向性“虚假声明是文档的第一句话“返回一个大于或等于0且小于EXPR值的随机分数”我不期望完美的随机性,但这确实意味着在0和EXPR之间可能存在32768个以上的值。但是文档中没有提到这一点。无论如何,“谢谢”为了快速反馈。明天某个时候我会打电话给PM。@Miller,这是另一个问题。rand(1000)
有偏见,因为1000不是2的幂。
use Math::Random::MT qw(srand rand irand);
# now use srand() and rand() as you usually do in Perl