3

我正在尽我最大的努力破译一些 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]

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

4

1 回答 1

5

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

"b*"模式代表产生一个位串- unpack "b*", "42"is "0010110001001100"

表示一个小端序的v16 位整数。

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,使用的额外参数越多:至少1个,最多16个。每个位依次用作索引,因此只使用了两个额外的参数。第一个参数的长度在此操作中保持不变,但输出至少有两个字节长。

如果额外参数之一为零,则在该循环迭代期间不发生旋转。Unitializes 参数被认为是零。

于 2013-09-21T07:59:27.100 回答