【问题标题】:Perl generate random session id for high trafficPerl 为高流量生成随机会话 id
【发布时间】: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


【解决方案1】:

您可以安全地使用Data::UUID,您不必担心重复,您不会遇到它们。

此外,rand() 在随后调用时不会返回相同的数字,即使假设它在同一时刻被调用也是如此。伪随机算法根据其当前状态和先前生成的值生成下一个数字。真正的随机数发生器通常不单独使用,而是与伪随机数发生器结合使用。在任何一种情况下,随后生成的数字在实际情况下在最近的时钟滴答之间重复的可能性都可以忽略不计。在您的示例中,您可能希望使用rand(2**32)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-02
    • 2011-02-02
    • 2021-09-16
    • 2020-11-03
    • 1970-01-01
    • 1970-01-01
    • 2011-10-17
    • 1970-01-01
    相关资源
    最近更新 更多