2010-11-23 36 views
2

私が抱えている問題は、STDIN経由でデータを読み取っているPerlスクリプトがあり、ストリームにラインターミネータ "0A"が含まれているためです。その後、私は16進データを変換すると、それは壊れています(16進形式の0Aがありません)。だから、私はどのようにPerlでラインフィード "0A"の "ウィンドウ"バージョンを検出できますか?Perlがバイナリストリームを16進数に変換する

注:LinuxのOS(Perlが)のWindows PE

!usr/bin/perl 

while($line = <STDIN>) 
{ 
    chomp($line); 
    @bytes = split //, $line; 
    foreach (@bytes) 
    { 
     printf "%02lx", ord $_; 
    } 
} 

使用例読んでいる:あなたのループでは

[[email protected] test]# cat test.exe | perl encoder.pl > output 

答えて

6

を、あなたは、各入力ライン上のchompを実行しています。これにより、現在の行の末尾にある$/にある値はすべて削除されます。チャンスは0x0aです。これが価値のあるところです。ループからchomp($line)を削除してみてください。一般的に

、行指向の読み込みを使用すると、行指向そのものではありませんバイナリファイルのための意味がありません。あなたは、それらのバイトが何であるかを気にせず、ファイルからバイトのブロックを読み取ることができ、より低いレベルread機能を見てみる必要があります。その後、データを行ではなくブロックで処理することができます。

+0

うわー、それは恥ずかしいです。私は 'binmode()'を使いこなすことにまっすぐ夢中になり、 'chomp'も見ていませんでした。 –

+2

また、 'unpack( 'H *'、$ binary_string)'は 'split'や' printf '%02x'より効率的です。 ! – cjm

+0

は のbinmode(STDIN)変更#/ usr/bin/perlを作っ。 一方() {#printの$ _。 push(@bytes、$ _); } foreachの(@bytes) {printfの "%の02lx"、ORDの$ _。 } – ekronnenburg

1
#With split 
cat magic.exe | perl -e 'print join("", map { sprintf("\\x%02x", ord($_)) } split(//, join("", <STDIN>)))' > hex_encoded_binary 

#With pack 
cat magic.exe| perl -e 'print join("", map { "\\x" . $_ } unpack("H*", join("", <STDIN>)) =~ /.{2}/gs)' > hex_encoded_binary 
関連する問題