加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

DES With Perl

发布时间:2020-12-16 00:32:09 所属栏目:大数据 来源:网络整理
导读:原本是要放在 NTLM Protocol - 2. DES 编码 这篇文章中,但不知是不是该章内容太大还是啥么原因,怎么也传不上,就拉出来单独放着. #!/usr/bin/perl -w# DES algorithm - reference to http://orlingrabbe.com/des.htmsub iteration_handle { my ($bitstring,$p

原本是要放在 NTLM Protocol - 2. DES 编码 这篇文章中,但不知是不是该章内容太大还是啥么原因,怎么也传不上,就拉出来单独放着.

#!/usr/bin/perl -w

# DES algorithm - reference to http://orlingrabbe.com/des.htm

sub iteration_handle {
  my ($bitstring,$pad) = @_;
  my $bitstringp = pack 'b*',$bitstring;
  my @bitarray = split(//,unpack('b*',$bitstringp));

  my @subkey;
  # perl give four zeros append the last of packed string
  my ($d1,$d2) = (scalar(@bitarray) - 4,scalar(@bitarray) - 1);
  delete @bitarray[$d1..$d2];

  #print "PAD=$padn";

  # handle last $pad bits
  for ($n=$pad; $n>0; $n--) {
    $subkey[scalar(@bitarray)-$n] = $bitarray[$pad - $n]; 
  }

  # handle head of bits
  for($i=0; $i<(scalar(@bitarray)-$pad); $i++) {
    #if ($i == $#bitarray) {
    #  $subkey[$i] = $bitarray[0];
    #} else {
    $subkey[$i] = $bitarray[$i+$pad];
    #}
    #print $i. ": ". $subkey[$i]. "n";
  }
  return join('',@subkey);
}

sub tobit {
  my $uncode = shift;
  my %codemap = ('0' => '0000','1' => '0001','2' => '0010','3' => '0011','4' => '0100','5' => '0101','6' => '0110','7' => '0111','8' => '1000','9' => '1001','A' => '1010','B' => '1011','C' => '1100','D' => '1101','E' => '1110','F' => '1111');
  my $coded = '';
  my @chars = split('',$uncode);
  foreach $c (@chars) {
      $coded .= $codemap{$c};
  }
  return $coded;
}


sub tohex {
  my $origin = shift;
  my @hexbits = split(//,$origin);
  my $ret = '';
  for ($j=0; $j<@hexbits; $j=$j+4) {
    $hex = join '',@hexbits[$j..($j+3)];
    $ret .=  sprintf ("%x",oct('0b' .$hex)); 
  }
  return $ret;
}

sub permuted {

  my $unpermuted = shift;

  # the first permutation chooser map table
  my @pc1map = (57,49,41,33,25,17,9,1,58,50,42,34,26,18,10,2,59,51,43,35,27,19,11,3,60,52,44,36,63,55,47,39,31,23,15,7,62,54,46,38,30,22,14,6,61,53,45,37,29,21,13,5,28,20,12,4);
 
  my $permuted = '';

  my @unpermutation = split(//,$unpermuted);
  foreach $d (@pc1map) {
    $permuted .= $unpermutation[$d-1]; # start from index 1

  }
  return $permuted; 
}

sub generate_subkey {
  my $origin = shift;
  
  # the second permutation chooser map table
  my @pc2map = (14,24,4,8,16,40,48,56,32); 

  my $permuted = '';
  my @unpermutation = split(//,$origin);
  foreach $d (@pc2map) {
    $permuted .= $unpermutation[$d-1]; # start from index 1
  }
  return $permuted; 
  
}

sub initial_permutation {
  my $origin = shift;

  # the initial permutation map table
  my @IP = (58,64,32,57,7);

  my $permuted = '';
  my @unpermutation = split(//,$origin);
  foreach $d (@IP) {
    $permuted .= $unpermutation[$d-1]; # start from index 1
  }
  return $permuted;
}

sub expand {
  my $origin = shift;

  # bit selection table
  my @selection_table = (32,1);  

  my $permuted = '';
  my @unpermutation = split(//,$origin);
  foreach $d (@selection_table) {
    #print "array of position $d: $unpermutation[$d-1]n";
    $permuted .= $unpermutation[$d-1]; # start from index 1
  }
  return $permuted;

}

sub subxor {
  my ($a,$b) = @_;
  my @as = split(//,$a);
  my @bs = split(//,$b);

  my @targets;

  for ($z=0; $z<@as; $z++) {
    if ($as[$z] eq '0' && $bs[$z] eq '0') {
      $targets[$z] = '0';
    } elsif ($as[$z] eq '1' && $bs[$z] eq '1') {
      $targets[$z] = '0';
    } else { 
      $targets[$z] = '1';
    }    
  }

  return join '',@targets;
}

sub cal_sboxes {
  my $origin = shift;
  
  my @sboxes;
 
  my @scalars = split(//,$origin);

  my @sb1 = (14,13);

  my @sb2 = (15,9);

  my @sb3 = (10,12);

  my @sb4 = ( 7,14);

  my @sb5 = ( 2,3);

  my @sb6 = (12,13);

  my @sb7 = ( 4,12);

  my @sb8 = (13,11);

  @sboxes = (@sb1,@sb2,@sb3,@sb4,@sb5,@sb6,@sb7,@sb8);

  my $ret = '';
  my $index = 0;
  for ($i=0; $i<@scalars; $i=$i+6,$index++) {
      $row = oct('0b'. join ('',@scalars[$i,($i+5)]));
      $col = oct ('0b'. join ('',@scalars[($i+1)..($i+4)]));
      #print "ROW: $row,COL= $coln";
      $sindex = $row == 0 ? ($row * 15 + $col) : ($row * 16 + $col);
      #print "SINDEX = $sindexn";
      #print "ROW= $row,COL= $col,V= $sboxes[$index][$sindex]n";
      #print sprintf("%04b",$sboxes[$index][$sindex]);
      $ret .= sprintf("%04b",$sboxes[$index][$sindex]);
  }

  return $ret;
}

sub second_permutation {
  my $origin = shift;

  # bit selection table
  my @sp = (16,25);

  my $permuted = '';
  my @unpermutation = split(//,$origin);
  foreach $d (@sp) {
    $permuted .= $unpermutation[$d-1]; # start from index 1
  }
  return $permuted;
}

sub handle_func {
  
  my ($rp,$key) = @_;

  # expand $rp[n-1] from 32 bits to 48 bits
  my $expands = expand $rp;
  #print "EXP= $expandsn";

  # XOR
  my $xor = subxor $key,$expands;

  #print "XOR= $xorn";
  my $ret = '';
  # calcute sboxes
  my $sbs = cal_sboxes($xor); 
  #print "SBS= $sbsn";
  
  $ret = second_permutation $sbs;
  #print "FP = $retn";

  return $ret;
}

sub final_permutation {
  my $origin = shift;

  # bit selection table
  my @fp = (40,$origin);
  foreach $d (@fp) {
    $permuted .= $unpermutation[$d-1]; # start from index 1
  }
  return $permuted;
}

# Step1: Create 16 subkeys,each of which is 48-bits long.
$original_key = '133457799BBCDFF1'; 
#print "KEY   = ". $original_key. "n";

my $keybits = tobit $original_key;

#print "K = ". $keybits. "n";

$permutation = permuted $keybits;

#print "K+ = ". $permutation. "nn";

my @subkeys;

$subkeys[0] = $permutation;

my @permutations = split(//,$permutation);

my @leftpart;
my @rightpart;

$leftpart[0] = join('',@permutations[0..27]);
$rightpart[0] = join ('',@permutations[28..55]);

#print "C0: ". $leftpart[0]. "n";
#print "D0: ". $rightpart[0]. "nn";

# irations table for shift N
my %iterations = (1 => 1,2 => 1,3 => 2,4 => 2,5 => 2,6 => 2,7 => 2,8 => 2,9 => 1,10 => 2,11 => 2,12 => 2,13 => 2,14 => 2,15 => 2,16 => 1);

for ($j=1; $j<=16; $j++) {
  $leftpart [$j] = iteration_handle $leftpart[$j-1],$iterations{$j};
  $rightpart[$j] = iteration_handle $rightpart[$j-1],$iterations{$j};
  #print "C". $j. " = ". $leftpart[$j]. "n";
  #print "D". $j. " = ". $rightpart[$j]. "nn";
  $subkeys[$j] = generate_subkey($leftpart[$j]. $rightpart[$j]);
  #print "K". $j. " = ". $subkeys[$j]. "n";
}

# Step 2: Encode each 64-bit block of data

my $data = '0123456789ABCDEF';
print "DATA  = ". $data. "n";
my $ip = initial_permutation(tobit($data));
#print "IP = ". $ip. "n";

# $ip = $lp[0] + $rp[0]

my (@lp,@rp);
$lp[0] = join '',(split(//,$ip))[0..31];
$rp[0] = join '',$ip))[32..63];

#print "L0 = ". $lp[0]. "n";
#print "R0 = ". $rp[0]. "n";

for ($x=1; $x<=16; $x++) {
  $lp[$x] = $rp[$x-1];
  #print "L". $x. " = ". $lp[$x]. "n";
  #print "R". ($x-1). " = ". $rp[$x-1]. "n";
  #print "K". $x. " = ". $subkeys[$x]. "n";
  #print "L". ($x-1). " = ". $lp[$x-1]. "n";
  $rp[$x] = subxor($lp[$x-1],handle_func($rp[$x-1],$subkeys[$x]));
  #print "R". $x. " = ". $rp[$x]. "n";
}

my $reverse = $rp[16]. $lp[16];
#print "R16L16 = ". $reverse. "n";

my $final = final_permutation $reverse;
$final = uc(tohex $final);

print "FINAL = $finaln";

其执行结果如下:

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读