3

誰かが perl で作成した crypt 関数を php コードに変換するタスクがあります。これを除いて、すべて正常に動作します:

パール:

$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)));

一部の文字列では、php バージョンは問題なく動作します。しかし、「2010-01-01T00:00:00.000」のようなものがある場合、perl バージョンはエラーなしで動作し、php バージョンは「PHP 警告: pack(): タイプ H: 不正な 16 進数」を出力します。

誰かがphpバージョンのエラーを見つけることができれば、私は非常に感謝しています.

編集:

これは、php に変換する完全な関数です。もう私たちとは仕事をしていない会社のプログラマーによって作成されたので、当初の意図が何であったかはよくわかりません。

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;
}
4

2 に答える 2

7

エラーは実際には両方のバージョンにあるようです。フォーマット コードHは 16 進数を探しますが、PHP エラーに記載されているように、(正当な) 1 つは見つかりません。犯人は次の式のようです。

chr(16 - ($len % 16))

Perl のバージョンの pack は、文字が 16 進数であるかどうかに関係なく文字を変換するため、Perl のバージョンは文句を言いません (これはあなたが望むものではないかもしれません)。ドキュメントには、実際に何が起こるかについての詳細が記載されています。

エラーを回避するには、代わりにこれを試してください。

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

注:これで発生しているエラーは修正されるはずですが、Perl コードの元の作成者の正確な意図がわからないため、許容できる解決策であるかどうかはわかりません。

于 2009-11-23T18:37:45.123 に答える
6

の Perl 実装はpack()、入力文字列内の無効な 16 進数を許容しているようですが、PHP バージョンは明らかにそうではありません。

検討:

print pack("H*", "ZZ");

これ3は(何らかの理由で)Perlで出力されますが、PHPで言及したエラーが発生します。

Perl がこれらの「桁」で何をしているのか正確にはわかりませんが、PHP と同じではないことは間違いありません。

編集: Perl は実際に 16 進数のドメインを文字セットに「ロール」するようです。あれは:

0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ  #-- Give this to Perl...
0123456789ABCDEF0123456789ABCDEF0123  #-- .. and it's treated as this hex digit

したがって、"ZZ" は "33" と同じなので、3. ドキュメントによると、この動作は明確に定義されていないことに注意してください。したがって、Perl の元の実装は、明確に定義されていない動作に依存しているため、バグがあると見なすことができます。

于 2009-11-23T18:33:21.217 に答える