perl

时间:2015-12-22 11:16:44

标签: perl hash iteration replicate

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

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

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

1 个答案:

答案 0 :(得分:6)

首先

sort

foreach my $key (  sort keys %hash ) { 

}

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

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

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这样的有序哈希机制。

  

我在迭代方面提出了问题,但也许它不是对哈希的迭代,而是哈希构建过程是非确定性的。我可以设置一些初始化来以确定性和可复制的方式构建哈希吗?

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

你也许可以搞乱(如文章中提到的)PERL_HASH_SEEDPERL_PERTURB_KEYS,但这绝对不是一个好习惯。

PERL_HASH_SEED=0 ./somescript.pl 

但是你应该记住,哈希排序仍然无法保证 - 密钥的排序可能仍会改变。尽管如此,它会比以前更加一致。这绝对不是在生产中使用的好东西,或者仅仅依赖于调试。

  

请注意:哈希种子是敏感信息。哈希是随机的,以防止针对Perl代码的本地和远程攻击。通过手动设置种子,可以部分或完全丧失此保护。