perl中哈希值的可复制迭代

jkn*_*ica 0 iteration perl hash replicate

众所周知如何迭代perl中的哈希(例如,参见Perl哈希键的最安全的迭代方法是什么?).但是,键和值的顺序是不确定的,实际上每个perl脚本的运行都是不同的.

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

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

Sob*_*que 6

sort 他们先:

foreach my $key (  sort keys %hash ) { 

}
Run Code Online (Sandbox Code Playgroud)

注意:默认排序是按字母顺序排列,而不是数字.但是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"
Run Code Online (Sandbox Code Playgroud)

;

或像一个有序的散列机制类似Hash::OrderedTie::IxHash.

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

不,哈希不像那样工作.请参阅 - perlsec了解原因.随着更新版本的perl,它变得越来越随机,但它总是一个无序的数据结构.

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

PERL_HASH_SEED=0 ./somescript.pl 
Run Code Online (Sandbox Code Playgroud)

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

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

  • 否.哈希是一组无序的键值对.这是因为它如何安排在内存中(用于有效的随机访问).如果你愿意,你可以处理非哈希的东西,但是你_gnot_max可以神奇地再次排序无序的数据结构. (2认同)
  • [Tie :: Hash :: Indexed](https://metacpan.org/pod/Tie::Hash::Indexed)提供与Tie :: IxHash相同的功能,但速度要快得多. (2认同)