2013-03-08 1 views
2

구문 분석 할 수 있어야하는 바이너리 파일이 있습니다. 내가 뭘 찾고 오프셋을 지정하고 그 프로그램을 그 위치에서 바이트 값을 반환합니다.Perl - 바이너리 파일 구문 분석 및 지정된 오프셋에서 값 반환

내가 어떻게되는지는 잘 모르겠다. 파일을 열어 봤지만 프로그램을 그 위치로 가져 오는 방법을 모르겠습니다.

도움을 주시면 감사하겠습니다.

감사합니다.

+0

지금까지 시도한 것을 보여줄 수 있습니까? – gpojd

+2

['perldoc -f seek'] (http://search.cpan.org/perldoc?perlfunc#seek) – mob

+0

나는 찾고있다. 그러나 나는 정말로 그것을 어떻게 해야할지 몰랐다. 인쇄 할 변수가 필요합니까? 아니면 실제로 바이트 데이터를 가져올 다른 것이 필요합니까? –

답변

5
use Fcntl qw(:seek); 

my($fh, $filename, $byte_position, $byte_value); 

$filename  = "/some/file/name/goes/here"; 
$byte_position = 42; 

open($fh, "<", $filename) 
    || die "can't open $filename: $!"; 

binmode($fh) 
    || die "can't binmode $filename"; 

sysseek($fh, $byte_position, SEEK_CUR) # NB: 0-based 
    || die "couldn't see to byte $byte_position in $filename: $!"; 

sysread($fh, $byte_value, 1) == 1 
    || die "couldn't read byte from $filename: $!"; 

printf "read byte with ordinal value %#02x at position %d\n", 
    ord($byte_value), $byte_position; 
+1

tchrist, 넌 대단해. 그것이 내가 필요한 것입니다. –

+0

당신은 autodie를 의지하고 가르치고 그 SLOC를 반으로 줄일 수 있습니다. https://rt.cpan.org/Public/Bug/Display.html?id=54777이 수정되었습니다. – daxim

+2

@ daxim 매번'autodie v2.12 사용 '을 쓰는 것이 정말로 신중할 때만, 나는 사람들이 할 수있는 것을 정말로 믿지 않는다. 이것은 기본 공급 업체 인 Perl 설치에서 실행되어야 함을 기억하십시오. 나는 또한 사람들이 그것없이 조각을 잘라내는 것에 대해 걱정하고 있는데,이 경우에는 정말 큰 문제가있다. 그것은 quickies에 대한 귀여운 기능이지만, 당신은 매우 그러한 조언을주의해야합니다. – tchrist

1

사용 seek

#! /usr/bin/env perl 

use bytes; 
use strict; 
use warnings; 

use Fcntl ':seek'; 

open my $fh, "<", $0 or die "$0: open: $!"; 

seek $fh, 0, SEEK_END or die "$0: seek: $!"; 

my $last = tell $fh; 
die "$0: tell: $!" if $last < 0; 

for (1 .. 20) { 
    my $offset = int rand($last + 1); 
    seek $fh, $offset, SEEK_SET or die "$0: seek: $!"; 
    defined read $fh, my $byte, 1 or die "$0: read: $!"; 
    $byte = "\\$byte" if $byte eq "'" || $byte eq "\\"; 
    printf "offset %*d: \\x%02x%s\n", 
     length $last, $offset, 
     unpack("C", $byte), 
     $byte =~ /[[:print:]]/a ? " '$byte'" : ""; 
} 
__DATA__ 
      
: ℞:  
          
             
¡ƨdləɥ ƨᴉɥʇ ədoɥ puɐ ʻλɐp əɔᴉu ɐ əʌɐɥ ʻʞɔnl poo⅁ 

샘플에서와 Fcntl 모듈에서 편리 상수 출력 :

offset 47: \x65 'e' 
offset 392: \x20 ' ' 
offset 704: \xf0 
offset 427: \x5c '\'' 
offset 524: \x61 'a' 
offset 1088: \x75 'u' 
offset 413: \x20 ' ' 
offset 1093: \xbb 
offset 1112: \xc9 
offset 377: \x24 '$' 
offset 64: \x46 'F' 
offset 361: \x62 'b' 
offset 898: \xf0 
offset 566: \x5d ']' 
offset 843: \xf0 
offset 1075: \xc9 
offset 280: \x20 ' ' 
offset 3: \x2f '/' 
offset 673: \x8a 
offset 153: \x20 ' '

UTF 처리하기위한 Tom’s excellent suggestions에서 차용 된 __DATA__ 섹션의 내용 -8 Perl 프로그램에서.

+1

아마도 이러한 바이트를 문자로 인쇄해서는 안됩니다. 인코딩을 모를 것입니다. 또한 PERL_UNICODE를 S로 설정 한 경우 Perl은이를 코드 포인트로 처리하여 단지 1로만 생각한다고 생각하는 곳에 여러 바이트를 쓸 수 있습니다. – tchrist

+0

@tchrist 공정한 포인트; 업데이트되었습니다. –