Need help with "pack" for perl and php

pack, perl, php

Solution

It looks like the error is actually in both versions. The format code `H` looks for a hex digit, and as noted in the PHP error, it isn't finding (a legal) one. The culprit appears to be this expression:

chr(16 - ($len % 16))

The Perl version isn't complaining because Perl's version of pack will convert the character regardless of whether or not it is a hex digit (which may not be what you want). The documentation goes into more detail about what actually happens.

To prevent the error, try this instead:

sprintf('%x', 16 - ($len % 16))

Note: While this should fix the error you are getting, I don't know if it's an acceptable solution because I don't know the exact intent of the original author of the Perl code.

Problem

I've the task to convert a crypt function someone made in perl into php code. Everything works okay except this: Perl: ``` $wert = Encode::encode( "utf8", $wert ); $len=length $wert; $pad = ($len % 16)?"0".chr(16 - ($len % 16)):"10"; $fuell = pack( "H*", $pad x (16 - $len % 16)); ``` PHP: ``` $wert = utf8_encode($wert); $len = mb_strlen($wert); $pad = ( $len%16 ) ? '0'.chr(16 - ($len%16)) : '10'; $fuell = pack("H*", str_repeat($pad, (16 - $len % 16))); ``` The php version works okay for some strings. But when I have something like '2010-01-01T00:00:00.000' the perl version works without any error and the php version prints "PHP Warning: pack(): Type H: illegal hex digit". I'm very grateful if someone can spot the error in the php version. Edit: This is the complete function I've to convert into php. It was made by a programmer of a company which doesn't work for us anymore so I can't really tell what the original intention was. ``` sub crypt { my $self = shift; my ($wert,$pw)= @_; $wert = Encode::encode( "utf8", $wert ); $pw = Encode::encode( "utf8", $pw ); $len=length $wert; $pad = ($len % 16)?"0".chr(16 - ($len % 16)):"10"; $fuell = pack( "H*", $pad x (16 - $len % 16)); $wert=$wert.$fuell; $lenpw=length $pw; $fuell = ($lenpw % 16)? pack ("H*", "00" x (16 - $lenpw % 16)):""; $pw=$pw.$fuell; $cipher = new Crypt::Rijndael $pw, Crypt::Rijndael::MODE_CBC; $cipher->set_iv($pw); $crypted = encode_base64($cipher->encrypt($wert),""); return $crypted; } ```

Original source