麻烦了解受阻的Perl方法

时间:2013-09-21 04:18:52

标签: perl

我正在尽力破译一些Perl代码并将其转换为C#代码,以便我可以将它与更大的程序一起使用。我已经能够将其中的大部分转换,但是我遇到了以下方法的问题:

sub dynk {  
    my ($t, $s, $v, $r) = (unpack("b*", $_[0]), unpack("b*", pack("v",$_[1])));  
    $v^=$t=substr($t,$r=$_*$_[($_[1]>>$_-1&1)+2]).substr($t,0,$r)^$s for (1..16);  
    pack("b*", $v);  
}

它被称为:

$sid = 0;  
$rand = pack("H*", 'feedfacedeadbeef1111222233334444');  
$skey = dynk($rand, $sid, 2, 3) ^ dynk(substr($dbuf, 0, 16), $sid, -1, -4);

除了这一部分,我理解其中的大部分内容:
$_*$_[($_[1]>>$_-1&1)+2]

我不确定在这种情况下如何使用$ _?如果有人可以解释,我想我可以得到其余的。

1 个答案:

答案 0 :(得分:5)

packunpack采用模式和一些数据,并根据模式转换此数据。例如,pack "H*", "466F6F"将数据视为任意长度的十六进制字符串,并将其解码为它所代表的字节。在这里:Foounpack函数执行相反的操作,并将二进制表示中的数据提取为特定格式。

"b*"模式生成位字符串 - unpack "b*", "42""0010110001001100"

v表示一个小端16位整数。

Perl相当混淆。这是一个简化某些方面的重写。

sub dynk {
  # Extract arguments: A salt, another parameter, and then two ints that determine rotation.
  my ($initial, $sid, $rot_a, $rot_b) = @_;

  # Unpack the initial value to a bitstring
  my $temp = unpack("b*", $initial);
  # Unpack the 16-bit number $sid to a bitstring
  my $sid_bits = unpack("b*", pack("v", $sid));
  my $v;  # an accumulator

  # Loop through the 16 bits of our $sid
  for my $bit_number (1..16) {
    # Pick the $bit_number-th bit from the $sid as an index for the data
    my $bit_value = substr($sid_bits, $bit_number-1, 1);
    # calculate rotation from one data argument
    my $rotation = $bit_number * ( $bit_value ? $rot_b : $rot_a );
    # Rotate the $temp bitstring by $rotation bits
    $temp = substr($temp, $rotation) . substr($temp, 0, $rotation);
    # XOR the $temp with $sid_bits
    $temp = $temp ^ $sid_bits;
    # ... and XOR with the $v accumulator
    $v = $v ^ $temp;
  }

  # Pack the bitstring back to binary data, return.
  return pack("b*", $v);
}

这似乎是某种加密或散列。它主要根据以下几个论点混淆了第一个论点。 $sid越大,使用的额外参数越多:至少一个,最多16个。每个位依次用作索引,因此只使用两个额外的参数。第一个参数的长度在此操作中保持不变,但输出至少为两个字节。

如果其中一个额外参数为零,则在该循环迭代期间不会发生旋转。单位化参数被认为是零。