【发布时间】:2015-06-03 11:50:32
【问题描述】:
我正在尝试为 Perl 中的每个用户会话生成会话 cookie 的随机 ID。当然,我搜索了 cpan 和 google,发现了许多相似的主题和相同的弱点。使用最多的模块是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:
Digest::SHA1::sha1_hex(rand() . $$ . {} . time)
所以简而言之,我想生成一个唯一的问题可能是最多 64 字节长的会话 id 保证在高流量下工作。
【问题讨论】:
-
您担心只有 1000 个并发用户的冲突?
-
总的来说我很担心,我说的是高流量,但以 1000 为例,并没有夸张地说 100_000 或 1000_000 个并发用户。我基本上想知道如果你有 100 个 FCGI 进程,每个进程只服务 5 个用户,随机 id 生成器将如何工作?
-
关于“从这些生成的 id 似乎是唯一的”,我们假设它们是唯一的。那还不够好。它们几乎总是需要不可预测的。
-
rand(Time::HiRes::time())没有任何意义。可以很容易地说rand(1400000000),这就引出了一个问题:为什么是这个数字???使用rand()或pack('d',rand())。 -
@ikegami 为什么它没有任何意义?这以微秒为单位返回时间,这意味着随机字符串的好机会。
标签: perl