2

我有一个需要能够解析的二进制文件。我要做的是指定一个偏移量,然后让程序返回该位置的字节值。

我不确定如何去做。我有文件打开部分,但我不知道如何让程序跳转到该位置。

任何帮助,将不胜感激。

谢谢。

4

2 回答 2

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;
于 2013-03-08T17:02:45.420 回答
2

使用Fcntl模块中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⅁ 

样本输出:

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

该部分的内容是从Tom 的关于在 Perl 程序中处理 UTF-8的优秀建议__DATA__中借用的。

于 2013-03-08T17:12:07.590 回答