我正在尝试为Perl中的每个用户会话生成会话cookie的随机ID。当然,我搜索了cpan和谷歌,发现了许多类似的主题和相同的弱点。使用的大多数模块是Digest::SHA和Data::UUID以及内部使用Data :: UUID的模块Data::GUID。
以下是我可以总结cpan上模块中使用的大多数方法的代码:
#!/usr/bin/perl
use v5.10;
use Digest::SHA;
use Data::UUID;
use Data::GUID;# uses Data::UUID internally, so no need for it
use Time::HiRes ();
for (1..10) {
#say generate_sha(1); # 1= 40 bytes, 256=64 bytes, 512=128 bytes, 512224, 512256
say generate_uuid();
#say generate_guid();
}
sub generate_sha {
my ($bits) = @_;
# SHA-1/224/256/384/512
return Digest::SHA -> new($bits) -> add($$, +{}, Time::HiRes::time(), rand(Time::HiRes::time()) ) -> hexdigest;
}
sub generate_uuid {
return Data::UUID->new->create_hex(); #create_str, create_b64
}
sub generate_guid {
# uses Data::UUID internally
return Data::GUID->guid;
}
以下是Data :: UUID模块的示例输出:
0x0217C34C6C0710149FE4C7FBB6FA663B
0x0218665F6C0710149FE4C7FBB6FA663B
0x0218781A6C0710149FE4C7FBB6FA663B
0x021889316C0710149FE4C7FBB6FA663B
0x021899E16C0710149FE4C7FBB6FA663B
0x0218AB2B6C0710149FE4C7FBB6FA663B
0x0218BB1D6C0710149FE4C7FBB6FA663B
0x0218CABD6C0710149FE4C7FBB6FA663B
0x0218DB786C0710149FE4C7FBB6FA663B
0x0218ED396C0710149FE4C7FBB6FA663B
从这些生成的id似乎是唯一的,但我所关心的是关于高流量或并发性,如果一个1000只是没有说1000,000个用户同时连接来自同一个过程就像在FCGI下运行(比如说每个FCGI进程只服务10个用户)或者从像CGI模式运行的单独进程一样。
在SHA中,我使用了这个随机字符串:
($$, +{}, Time::HiRes::time(), rand(Time::HiRes::time())
它包含匿名哈希引用地址和Time::HiRes::time的当前时间(以微秒为单位)。有没有其他方法可以制作随机字符串。
我已经阅读了添加远程用户的主机名和IP地址的主题,但其他人说可以使用代理。
我看到Plack::Session::State模块使用这个简单的代码生成id' s:
Digest::SHA1::sha1_hex(rand() . $$ . {} . time)
因此,简而言之,我想生成一个唯一的问题可能是长达64字节的会话ID,保证可以处理高流量。
答案 0 :(得分:3)
您可以安全地使用Data::UUID
并且您不应该担心重复项,您将不会遇到它们。
即使假设在同一时刻调用它,rand()
也会在后来调用时返回相同的数字。伪随机算法基于其当前状态和先前生成的值生成下一个数字。真正的随机发生器通常不单独使用,而是与伪随机数发生器结合使用。在任何一种情况下,实际上随后产生的数字在最近的时钟标记之间重复的可能性是可以忽略的。在您的示例中,您可能希望使用rand(2**32)
。