TomY has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I wrote a simple DES in ECB mode implementation in Perl based on W.Stallings book... When I tried to compare it with online calc. I didnt get exactly the same outputs(lets focus on encryption as the process is idenctical) what do I mean is, we know DES works on blocks of 8 bytes and both my script and online calcs. give the same result for the first 2 blocks only! so I came to the conclusion that I am not reading the input file as 8 byte chunks correctly or as them.... Please help me understand why(again assumption is the read from file func is somehow wrong)?? remarks: -I am a Perl beginner -For those who are interested this is a self project intended to be shown to my class mates if my teacher would allow me i.e. this not an assignment or work related...just for my own fun after reading the book ch. -code may not be optimal or good :( In advance tnxxx all helpers and advises !
#!/usr/bin/perl #--------------------------------------------------------------------- +------------------------ # @Script CLI args@ # 1) action: "e" or "d", as one char string # 2) password: "myDesPass", as a string # 3) input file: "filePath1", as a string, should contain the message + to encrypt # 4) output file: "filePath2", as a string, where the encrypted messag +e will be saved #--------------------------------------------------------------------- +------------------------ #--------------------------------------------------------------------- +------------------------ # Ctyptography and Network Security 4th edition by Willian Stallings # # DES online calculator: # https://www.emvlab.org/descalc # # Perl tutorial: # https://www.tutorialspoint.com/perl/ # http://www.perlmonks.org/ # # unpack/pack: # https://www.tutorialspoint.com/perl/perl_unpack.htm # # perl references: # https://perlmaven.com/array-references-in-perl # # Programmatic Conversions: # http://perltips.wikidot.com/convert-hex-dec-oct-bin # https://stackoverflow.com/questions/288900/how-can-i-convert-a-strin +g-to-a-number-in-perl # # Online Conversions: # http://www.rapidtables.com/convert/number/hex-to-ascii.htm # http://www.asciitohex.com/ # #--------------------------------------------------------------------- +------------------------ #--------------------------------------------------------------------- +------------------------ # DES Internal Conversion Tables #--------------------------------------------------------------------- +------------------------ @SBOXES = ( #S1 [ [14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7], [0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8], [4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0], [15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13] ], #S2 [ [15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10], [3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5], [0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15], [13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9] ], #S3 [ [10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8], [13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1], [13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7], [1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12] ], #S4 [ [7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15], [13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9], [10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4], [3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14] ], #S5 [ [2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9], [14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6], [4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14], [11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3] ], #S6 [ [12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11], [10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8], [9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6], [4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13] ], #S7 [ [4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1], [13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6], [1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2], [6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12] ], #S8 [ [13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7], [1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2], [7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8], [2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11] ] ); my @IP = ( 58,50,42,34,26,18,10,2, 60,52,44,36,28,20,12,4, 62,54,46,38,30,22,14,6, 64,56,48,40,32,24,16,8, 57,49,41,33,25,17, 9,1, 59,51,43,35,27,19,11,3, 61,53,45,37,29,21,13,5, 63,55,47,39,31,23,15,7 ); my @IP_INVERSE = ( 40,8,48,16,56,24,64,32, 39,7,47,15,55,23,63,31, 38,6,46,14,54,22,62,30, 37,5,45,13,53,21,61,29, 36,,4,44,12,52,20,60,28, 35,3,43,11,51,19,59,27, 34,2,42,10,50,18,58,26, 33,1,41,9,49,17,57,25 ); my @E = ( 32,1,2,3,4,5, 4,5,6,7,8,9, 8,9,10,11,12,13, 12,13,14,15,16,17, 16,17,18,19,20,21, 20,21,22,23,24,25, 24,25,26,27,28,29, 28,29,30,31,32,1 ); my @P = ( 16,7,20,21,29,12,28,17, 1,15,23,26,5,18,31,10, 2,8,24,14,32,27,3,9, 19,13,30,6,22,11,4,25 ); my @PC_1 = ( 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 @PC_2 = ( 14,17,11,24,1,5,3,28, 15,6,21,10,23,19,12,4, 26,8,16,7,27,20,13,2, 41,52,31,37,47,55,30,40, 51,45,33,48,44,49,39,56, 34,53,46,42,50,36,29,32 ); my @ScheduleOfLeftShifts = (1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, +2, 1); #--------------------------------------------------------------------- +------------------------ #--------------------------------------------------------------------- +------------------------ # Globals and CLI args #--------------------------------------------------------------------- +------------------------ my $action = checkAction($ARGV[0]); my $subKeysRef = createRoundKeys($ARGV[1]); my $InputFileName = $ARGV[2]; my $OutputFileName = $ARGV[3]; # this is an array where each element is a ref to a bits-array of the +index/round sub-key # @$: dereference a refrence to an array my @SubKeys = @$subKeysRef; # holds data to read/write from/to file my @FileArray = (); #--------------------------------------------------------------------- +------------------------ #--------------------------------------------------------------------- +------------------------ # #--------------------------------------------------------------------- +------------------------ sub checkAction { my $action = $_[0]; if( ($action eq "e") or ($action eq "d") ) { return $action; } else { die "#ERROR: action parameter is wrong (\"e\"=encryption, \"d\ +"=decryption)#\n"; } } #--------------------------------------------------------------------- +------------------------ #--------------------------------------------------------------------- +------------------------ # #--------------------------------------------------------------------- +------------------------ sub createRoundKeys { my $key = $_[0]; if(length $key != 8) { die "#ERROR: DES key is not 64 bit#\n";} my $i, $j; # to hold references to sub-keys for each round according to array + index. # the function returns a reference of this array to be farther use +d. my @subKeys = (); # unpack returns the key string as a corresponding bit string # 64 bit where B indicates highest first my @tempArr = unpack("B64", $key); # split bit string to corresponding bits array my @keyBitsArr = split("", $tempArr[0]); #convert to numeric bits for ($j=0; $j<=$#keyBitsArr; $j++) { $keyBitsArr[$j]+=0; } #------------------------------------------------------------ # permuted choice one(@PC_1) # each index in the keyBitsArr56_PC1 gets some bit from the 64-bit + original key according to some mapping, PC-1 my @keyBitsArr56_PC1 = (); for ($i=0; $i<=$#PC_1; $i++) { $keyBitsArr56_PC1[$i] = $keyBitsArr[$PC_1[$i]-1]; } # split permuted choice 1 outcome @keyBitsArr56_PC1 to two 28 bit +arrays, left and right my @leftBitsArr = (); my @rightBitsArr = (); for($i=0; $i<28; $i++) { $leftBitsArr[$i] = $keyBitsArr56_PC1[$i]; } for(; $i<56; $i++) { $rightBitsArr[$i-28] = $keyBitsArr56_PC1[$i]; } #------------------------------------------------------------ #------------------------------------------------------------ # create sub-keys for each round @tempArr = (); for($i=0; $i<16; $i++) { # shift each part individually for($j=0; $j<$ScheduleOfLeftShifts[$i]; $j++) { # shift left part according to round push(@leftBitsArr, shift(@leftBitsArr)); # shift right part according to round push(@rightBitsArr, shift(@rightBitsArr)); } # PC_2, get 48 bit round sub key # unite to one 56 bits arr for($j=0; $j<28; $j++) { $tempArr[$j] = $leftBitsArr[$j]; $tempArr[$j+28] = $rightBitsArr[$j]; } # permuted choice two for ($j=0; $j<=$#PC_2; $j++) { # save round key ${$subKeys[$i]}[$j] = $tempArr[$PC_2[$j]-1]; } } #------------------------------------------------------------ return \@subKeys; } #--------------------------------------------------------------------- +------------------------ #--------------------------------------------------------------------- +------------------------ # #--------------------------------------------------------------------- +------------------------ sub des { my $i, $j, $k, $tempVar, @tempArr; # iterate over input file in chunks of 64 bit, DES ECB-mode of ope +ration for($i=0; $i<=$#FileArray; $i++) { # convert block read from file to its binary rep $tempVar = unpack("B64", $FileArray[$i]); #---------------------------------------- # DEBUG/PoC print("$FileArray[$i]\n"); $hex = sprintf('%X', oct("0b$tempVar")); print("$hex\n"); #---------------------------------------- # an array of bits as numeric values, the block rep as numeric + binary numbers my @bitsArray = split("", $tempVar); #convert to numeric bits for ($j=0; $j<=$#bitsArray; $j++) { $bitsArray[$j]+=0; } # initial permutation (IP) for each block/64 bit chunk before +the 16 rounds my @bitsArray_ip = (); for ($j=0; $j<=$#IP; $j++) { $bitsArray_ip[$j] = $bitsArray[$IP[$j]-1]; } # split to: left and right my @leftBitsArr = (); my @rightBitsArr = (); for ($j=0; $j<32; $j++) { $leftBitsArr[$j] = $bitsArray_ip[$j]; $rightBitsArr[$j] = $bitsArray_ip[$j+32]; } # 16 DES rounds per 64 bit chunk treated as two 32 bit chunks for($j=0; $j<16; $j++) { my @nextLeftBitsArr = @rightBitsArr; # curr right bits chunk expansion/permutation (E) my @bitsArray_E = (); for($k=0; $k<=$#E; $k++) { $bitsArray_E[$k] = $rightBitsArr[$E[$k]-1]; } @rightBitsArr = @bitsArray_E;# copy back # XOR with round sub-key: check function bool param for en +cryption/decryption action my $ref; if($action eq "e") { $ref = $SubKeys[$j];# j - index of curr round } elsif($action eq "d") { $ref = $SubKeys[15-$j];# j - index of curr round reve +rsed } my @roundSubKey = @$ref;# de-ref to bits-array for($k=0; $k<48; $k++) { $rightBitsArr[$k]^=$roundSubKey[$k]; } # S-box my $sBoxResStr = ""; for($k=0; $k<8; $k++) { @tempArr = unpack("N", pack("B32", ("0"x30).join("",($ +rightBitsArr[$k*6], $rightBitsArr[$k*6+5])))); my $sBoxRow = $tempArr[0]; @tempArr = unpack("N", pack("B32", ("0"x28).join("",($ +rightBitsArr[$k*6+1], $rightBitsArr[$k*6+2], $rightBitsArr[$k*6+3], $ +rightBitsArr[$k*6+4])))); my $sBoxCol = $tempArr[0]; my $sBoxOutput = $SBOXES[$k][$sBoxRow][$sBoxCol]; @tempArr = unpack("B32", pack("N", $sBoxOutput)); $sBoxResStr.=substr($tempArr[0], -4); } @rightBitsArr = split("", $sBoxResStr);# now 32 bits, $sBo +xResStr was loop concat. #convert to numeric bits for ($k=0; $k<=$#rightBitsArr; $k++) { $rightBitsArr[$k]+=0; } # permutation(P) my @bitsArray_p = (); for ($k=0; $k<=$#P; $k++) { $bitsArray_p[$k] = $rightBitsArr[$P[$k]-1]; } @rightBitsArr = @bitsArray_p;# now 32 bits # XOR result on curr right bits chunk with curr left bits +chunk, put res to next right chunk for($k=0; $k<32; $k++) { $rightBitsArr[$k] ^= $leftBitsArr[$k]; } # assign next values @leftBitsArr = @nextLeftBitsArr; } # swap two sides @temp = @leftBitsArr; @leftBitsArr = @rightBitsArr; @rightBitsArr = @temp; # merge and inverse initial permutation --> output 64 bit chun +k cipher-text for($k=0; $k<32; $k++) { $bitsArray[$k] = $leftBitsArr[$k]; $bitsArray[$k+32] = $rightBitsArr[$k]; } my @bitsArray_ip_inverse = (); for ($k=0; $k<=$#IP_INVERSE; $k++) { $bitsArray_ip_inverse[$k] = $bitsArray[$IP_INVERSE[$k]-1]; } #save manipulated chunk to same index in @FileArray $tempVar = join("", @bitsArray_ip_inverse); $FileArray[$i] = pack("B64", $tempVar); } } #--------------------------------------------------------------------- +------------------------ #--------------------------------------------------------------------- +------------------------ # I/O functions #--------------------------------------------------------------------- +------------------------ sub readInputToArray { open(FILEHANDLER, "<".$InputFileName) or die "#ERROR: can't open i +nput file#\n"; my $i = 0; while(1) { # read a block of data, block size is 8 bytes/64 bits $bytes = read (FILEHANDLER, $chunk, 8); if($bytes == 0) { last; } else { $FileArray[$i] = $chunk; $i++; } } close(FILEHANDLER) or die "#ERROR: couldn't close input file prope +rly#\n"; if($action eq "e"){ # padding at the end to fit 8 byte/64 bit chunks for DES block +s my $lastBlockSize = length $FileArray[$#FileArray]; my $diff = 0; if( $lastBlockSize < 8) { $diff = 8 - $lastBlockSize; # create the padding string my $padding = "0" x $diff; # concat last block to pedding string $FileArray[$#FileArray].=$padding; } open(FILEHANDLER, ">.DES_PROPERTIES.txt") or die "#ERROR: can' +t open .DES_PROPERTIES.txt file#\n"; print FILEHANDLER "des_padding_diff\n$diff\n"; close(FILEHANDLER) or die "#ERROR: couldn't close .DES_PROPERT +IES.txt file properly#\n"; } } sub writeOutputToFile { if($action eq "d"){ open(FILEHANDLER, "<.DES_PROPERTIES.txt") or die "#ERROR: can' +t open DES_PROPERTIES.txt file#\n"; @lines = <FILEHANDLER>; $diff = $lines[1]; close(FILEHANDLER) or die "#ERROR: couldn't close DES_PROPERTI +ES.txt file properly#\n"; } open(FILEHANDLER, ">".$OutputFileName) or die "#ERROR: can't open +output file#\n"; for(my $i=0; $i<=$#FileArray; $i++) { if($i == $#FileArray) { $FileArray[$i] = substr($FileArray[$i], 0, length($FileArr +ay[$i])-$diff); } print FILEHANDLER $FileArray[$i]; } close(FILEHANDLER) or die "#ERROR: couldn't close output file prop +erly#\n"; } #--------------------------------------------------------------------- +----------- #--------------------------------------------------------------------- +----------- # Execute #--------------------------------------------------------------------- +----------- readInputToArray(); des(); writeOutputToFile(); #--------------------------------------------------------------------- +-----------

Replies are listed 'Best First'.
Re: DES in Perl
by hippo (Archbishop) on Nov 14, 2017 at 09:51 UTC

    Caveat: I know next to nothing about the DES algorithm so am not going to comment on it here.

    so I came to the conclusion that I am not reading the input file as 8 byte chunks correctly or as them

    Ordinarily, that would mean you would just look at the readInputToArray() subroutine. However, the lack of strict and the profusion of global variables (such as $bytes and @FileArray) is going to make the debugging very difficult. Please do yourself a massive favour and limit the scope of your variables and make your subroutines as self-contained as possible. eg. have readInputToArray() return @FileArray so that the subroutine can be tested in isolation.

    All that said, this line is concerning me:

    my $padding = "0" x $diff;

    Unfamiliar as I am with DES, this shows that you are padding the read string with "0"s - that is a string with each character being ASCII character "0" (dec 48 or hex 0x30) when what I can only guess you actually want is dec 0 or hex 0x00 which is the ASCII NUL. Is this a/the flaw? You tell me :-)

      I will try to improve code quality! tnxx for that. But as far as padding, maybe I am wrong but, if I have say a 7 byte string at hand and I want it to be padded to 8 byte string I should add 1 byte i.e. 1 char say "0"... Correction: I think I get it now.... The char '0' in binary is far from being just seq. of 0 in bin!, and the DES algo' appends exactly those dec 0 you meant to the binary representation of a specific chunk.....? Hmm worth checking!! tnxx again:) Also found just now :( found this: https://asecuritysite.com/encryption/padding_des
        Also found just now :( found this: https://asecuritysite.com/encryption/padding_des
Re: DES in Perl
by johngg (Canon) on Nov 14, 2017 at 11:32 UTC
    my @IP_INVERSE = ( 40,8,48,16,56,24,64,32, 39,7,47,15,55,23,63,31, 38,6,46,14,54,22,62,30, 37,5,45,13,53,21,61,29, 36,,4,44,12,52,20,60,28, 35,3,43,11,51,19,59,27, 34,2,42,10,50,18,58,26, 33,1,41,9,49,17,57,25 );

    Did you intend the double comma on the fifth line of values?

    Update: Also just noticed a leading comma on the second line of values here.

    my @PC_1 = ( 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 );

    Cheers,

    JohnGG

Re: DES in Perl
by Laurent_R (Canon) on Nov 14, 2017 at 13:30 UTC
    Hi TomY

    You might want to look at this pure Perl implementation of the DES encryption algorithm: Crypt::DES_PP.

Fun with map and array slices (was Re: DES in Perl)
by roboticus (Chancellor) on Nov 14, 2017 at 21:03 UTC

    TomY:

    Pretty interesting! Since you've put a lot of work into your code, and I've never bothered to look at DES source code before, I spent a bit of time going over your code.

    Beginners remarks

    I've looked over your code and from a beginner's perspective, and I have only one thing I would mention: Be sure to use strict and warnings in your code to help perl alert you to possible issues. When I added strict and warnings, perl alerted me to a few undefined variables ($blocks, $chunk, etc.) as well as some missing parenthesis on some declarations. Specifically in createRoundKeys you have:

    my $i, $j;

    Instead of what you probably wanted:

    my ($i, $j);

    The same is true in the des subroutine.

    Advanced remarks: the map operator

    I realize you're a beginner, but I thought it might be helpful to show you some more intermediate and advanced idioms you can use in perl. Please note that I'm not razzing you or anything. My intent is more like "Hey, here are some nifty tricks you can look forward to using as you get more familiar with perl!".

    In the beginner stage, you'll use the heck out of for loops. Later, you'll start seeing opportunities to simplify your code with some more advanced techniques. But until you know these techniques well, you won't notice the opportunity. As I was working though your code, I found a few places where I could simplify things using techniques you're not yet familiar with.

    In your createRoundKeys subroutine, you're converting a buffer into a bit array and then ensuring that the values in the array are numeric with code like this:

    my @tempArr = unpack("B64", $key); my @keyBitsArr = split("", $tempArr[0]); for ($j=0; $j<=$#keyBitsArr; $j++) { $keyBitsArr[$j] += 0; }

    Essentially you're splitting $tempArr[0] into a list, storing it into an array, and then making a simple transformation on the data in the array. Perl has a beautiful operator that can help you here: map It takes a bit of code and a list. For each value in the list, it assigns it to $_, then executes the bit of code, and then puts the result into a new list. So if you replace your for loop with a use of the map operator, your code would look like this:

    my @tempArr = unpack("B64", $key); my @keyBitsArr = split("", $tempArr[0]); @keyBitsArr = map { $_ + 0 } @keyBitsArr;

    So here, it takes the array @keyBitsArr as a list. Then, for each element in the list, it adds 0 to it. Finally the entire list is assigned to @keyBitsArr.

    Even nicer is that map doesn't need an array on the right, it just needs a list. So you can save a little more code by converting it to this:

    my @tempArr = unpack("B64", $key); my @keyBitsArr = map { $_ + 0 } split("", $tempArr[0]);

    Now you're splitting $tempArr[0] into a list of strings, adding 0 to each of them, and then assigning the resulting list of numbers to your @keyBitsArr array.

    Another thing I see you doing fairly often is using an array as a list of bit positions you use to permute a bit array into a different order. Let's take a look at one:

    my @keyBitsArr56_PC1 = (); for ($i=0; $i<=$#PC_1; $i++) { $keyBitsArr56_PC1[$i] = $keyBitsArr[$PC_1[$i]-1]; }

    Normally C-style for loops are a signal that there may be a better way to do things. All you're really needing here is a list of the values 0 to $#PC_1, and you can use the range operator (..) with for to make a perl-style for loop:

    my @keyBitsArr56_PC1 = (); for my $i (0 .. $#PC_1) { $keyBitsArr56_PC1[$i] = $keyBitsArr[$PC_1[$i]-1]; }

    Now, since we have a list of values 0 .. $#PC_1 and you're loading values into an array in that order and you have a simple expression to convert your value into another value, then the map operator can help you out here as well, giving you:

    my @keyBitsArr56_PC1 = map { $keyBitsArr[$PC_1[$_]-1] } 0 .. $#PC_1;

    Map's brother grep

    It takes time to get comfortable with using map, bit it's worth your time. When you're learning map, you'll probably want to learn grep along with it. It also takes a bit of code and a list. The grep operator will also assign each value in the incoming list to $_ and execute the bit of code. The difference is that if the result is true, then the original input value gets placed in the output list, otherwise the input value is skipped.

    Here's a bit of goofy code--the first statement uses map to double the values 0..10 to build a list of even numbers from 0 to 20, and the second line builds a list of even numbers from 0 to 10 by filtering out the odd values.

    my @even_from_0_to_20 = map { $_*2 } 0 .. 10; my @even_from_0_to_10 = grep { is_even($_) } 0 .. 10; sub is_even { my $val = shift; return 0 == $val % 2; }

    You can use map and grep multiple times with each other to accomplish some pretty interesting things. The secret to understanding map and grep is to read from the right to the left. At the right is a list of stuff and a chunk of code that you'll apply to your map or grep operator. Then you may find another bit of code and a map or grep operator. For example:

    my @foo = map { sprintf "% 4u", $_ } grep { is_prime($_) } 0 .. 1000;

    Starting from the end, we find that we have a list of numbers from 0 to 1000. Then using grep we're keeping only the ones that happen to be prime. The result of that is another list that we're sending to map to format them to four-character long strings, and the final result is going into our @foo array.

    Joining and splitting arrays

    Another thing I see you doing is joining and splitting arrays. You're joining a pair of arrays like this:

    for ($k=0; $k<32; $k++) { $bitsArray[$k] = $leftBitsArr[$k]; $bitsArray[$k+32] = $rightBitsArr[$k]; }

    Since you simply want all the values in @leftBitsArr followed by all the values in @rightBitsArr, you can do it like this:

    @bitsArray = (@leftBitsArr, @rightBitsArr);

    perl likes to flatten lists, so on the right side, we're making a list out of two lists and then placing the final list into @bitsArray.

    For splitting lists, you're typically splitting them in half, like this:

    my @leftBitsArr = (); my @rightBitsArr = (); for ($j=0; $j<32; $j++) { $leftBitsArr[$j] = bitsArray_ip[$j]; $rightBitsArr[$j] = $bitsArray_ip[$j+32]; }

    There's an interesting trick in perl: You can create a list of values from an array and a list of indices. This is called array slicing (you'll find it described in perlvar). Using the range operator in conjunction with array slicing we can turn your code into:

    my @leftBitsArr = @bitsArray_ip[0 .. 31]; my @rightBitsArr = @bitsArray_ip[32 .. 63];

    Sorry, but I'm out of time for the moment. I've done a few other things to your code (such as removing some pack and unpack operations that were confusing me). If yo have any questions about anything I've written, please let me know, and I'll try to clarify things. The modifications I've made to your code while playing around with it:

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: DES in Perl
by Laurent_R (Canon) on Nov 15, 2017 at 08:53 UTC