perl 中散列的可复制迭代

Replicable iteration over a hash in perl

众所周知如何在 perl 中迭代散列(例如,参见 What's the safest way to iterate through the keys of a Perl hash?)。但是,键和值的顺序未确定,实际上每个 perl 脚本 运行 的顺序都不同。

有没有办法确保相同输入数据上相同 perl 脚本的每个 运行 都产生相同的迭代顺序?我只关心这个意义上的可复制性---顺序不需要由人类预测。

编辑:我根据迭代提出了问题,但也许不是哈希上的迭代而是哈希构建过程是不确定的。我可以设置一些初始化来以确定性和可复制的方式构建哈希吗?

sort 他们第一:

foreach my $key (  sort keys %hash ) { 

}

注意:默认排序是字母顺序,而不是数字。但是 sort 将采用一个自定义函数,让您可以按照您想要命名的几乎任何顺序进行排序。

或者,捕获数组中的顺序并使用 that 提取输出顺序。

my %content_for;
my @ordered_id; 

while ( <$input_filehandle> ) { 
    my ( $id, $content ) = split; 
    push ( @ordered_id, $id ); 
    $content_for{$id} = $content; 
}

print join ( "\n", @content_for{@ordered_id} ),"\n"

;

或者像 Hash::OrderedTie::IxHash 这样的有序哈希机制。

I formulated the question in terms of iteration, but maybe it is not the iteration over the hash but the hash building process that is non-deterministic. Can I set some inititialisation to build the hash in a deterministic and replicable way?

没有。哈希不是那样工作的。有关原因的解释,请参见 - perlsec。它得到 更多 随机与较新版本的 perl,但它始终是一个无序的数据结构。

您也许可以随意使用(如文章中所述)PERL_HASH_SEED and PERL_PERTURB_KEYS,但这绝对不是一个好的做法。

PERL_HASH_SEED=0 ./somescript.pl 

但您应该记住,散列顺序仍然无法保证 - 键的顺序可能仍会改变。不过,它会比以前更加一致。这绝对不是在生产中使用的好东西,或者除了调试之外的任何事情都依赖它。

PLEASE NOTE: The hash seed is sensitive information. Hashes are randomized to protect against local and remote attacks against Perl code. By manually setting a seed, this protection may be partially or completely lost.