为什么这个哈希是从一个常量列表创建的,"以不同的顺序"每次运行程序?

时间:2015-02-18 19:36:13

标签: perl hash

以下是Perl中的小脚本。每次运行此代码时,我都会得到不同的输出。

任何人都可以帮助我理解哈希变量的存储基础知识,即如何为Perl的哈希变量的键值对进行索引。

#!/usr/bin/perl

%data = ('John Paul' => 45, 'Lisa' => 30, 'Kumar' => 40);
@names = keys %data;
print "$names[0]\n";
print "$names[1]\n";
print "$names[2]\n";

2 个答案:

答案 0 :(得分:12)

行为记录在perlsecAlgorithmic Complexity Attacks


哈希是链表的数组。散列函数将密钥转换为一个数字,该数字用作存储值的数组元素(“bucket”)的索引。多个密钥可以散列到相同的索引(“冲突”),这是由链表处理的情况。

如果恶意用户知道散列算法,他可以设计散列到同一索引的值,从而导致散列退化为链接列表。这可能导致某些应用程序中巨大的性能下降,因此可以用作拒绝服务(DoS)攻击的一部分。

采取两项措施来避免这种情况。一种方法是将散列算法加盐以随机化存储元素的顺序,另一种方法是通过扰乱迭代器访问散列元素的顺序来更难检测盐。

$ perl -E'
   my @k = "a".."z";
   for (1..3) {
      my %h = map { $_ => 1 } @k;
      say keys %h;
   }
'
iocmbygdkranwxfejuqpzvltsh
bmcoigdywrankujfxezpqlvths
juexfwarnkgdybmcoihstlvzpq

答案 1 :(得分:3)

perldoc -f keys

中描述了此行为
  

哈希条目以明显随机的顺序返回。实际的随机顺序特定于给定的哈希值;两个哈希值上完全相同的一系列操作可能会导致每个哈希值的顺序不同。任何插入哈希都可以改变顺序,任何删除也是如此,除了可以删除每个或多个键返回的最新密钥而不改变顺序。只要给定的哈希值未经修改,您就可以依赖键,值和每个哈希值来重复返回相同的顺序。

..以防止Algorithmic Complexity Attacks