1

我正在尝试读取二进制文件,将数据存储为十六进制值的字符串,使用正则表达式修改一些十六进制值,并将数据吐出到一个新的二进制文件中(这是原始文件的略微修改版本)。

除了最后一个,我可以完成所有这些步骤。当我在十六进制编辑器中打开新的二进制文件时,一切似乎都是错误的......我希望它与我的十六进制字符串完全相同,但在十六进制编辑器中。

这是我在创建新文件时尝试做的事情:

# Format data string into an array for file processing
@data_ary = unpack('H*', $data_str);

generate_new_file($filname, \@data_ary);


sub generate_new_file
{
     my $fname = "mod -" . shift(@_);
     my $aref = shift(@_);

     open(BIN, ">", $fname) or die;
     binmode(BIN);

     for my $nybble(@$aref)
     {
         print (BIN $nybble)
     }
     close(BIN);
}

我猜我的问题与我对unpack的使用有关。但我不太确定如何将一个巨大的十六进制字符串转换为一种实际上将被读取为十六进制而不是 ASCII 字符的形式。任何建议都非常感谢!

上面显示的代码仅用于尝试将数据输出到新文件中。我已经有了我想要在 $data_str 中输出的所有十六进制数。因此,解包是一种尝试将十六进制字符串放入十六进制值列表中。

我越来越近了。我从一开始就删除了解包,因为我的数据已经是一个十六进制字符串。所以我只是将它拆分并放入数组中。这至少现在可以正确地获取文件的大小。但是,我的新问题是它会裁剪每个字节的第二部分并将其替换为 0(在十六进制编辑器中查看时)......但是当我打印时,数组的元素会得到正确的数据。有任何想法吗?新代码如下:

# Format data string into an array for file processing
@data_ary = split //, $data_str;
generate_new_file($filname, \@data_ary);


sub generate_new_file
{
     my $fname = "mod -" . shift(@_);
     my $aref = shift(@_);

     open(BIN, ">", $fname) or die;
     binmode(BIN);

     for (my $i = 0; $i < @$aref; $i += 2)
     {
         my ($hi, $lo) = @$aref[$i, $i+1];
         print BIN pack "H", $hi.$lo;
     }

     close(BIN);
}

我想到了!我在调用pack时忘记了“*” ,所以它不仅仅是第一个字符!完成的代码如下。谢谢阿蒙!

# Format data string into an array for file processing
@data_ary = split //, $data_str;
generate_new_file($filname, \@data_ary);


sub generate_new_file
{
     my $fname = "mod -" . shift(@_);
     my $aref = shift(@_);

     open(BIN, ">", $fname) or die;
     binmode(BIN);

     for (my $i = 0; $i < @$aref; $i += 2)
     {
         my ($hi, $lo) = @$aref[$i, $i+1];
         print BIN pack "H*", $hi.$lo;
     }
     close(BIN);
}
4

1 回答 1

3

在这里,unpack返回单个字符串,而不是值数组。如果你想要一个十六进制字符数组(每个表示 4 位),那么你必须split得到结果字符串:

my @data = split //, unpack "H*", $data;

(用于split /..\K/, $data分割成字节等价物)

在将此数据打印到文件句柄之前,您还必须pack再次获取原始数据。我建议至少对原始数据的 8 位部分执行此操作:

for (my $i = 0; $i < @$aref; $i += 2) {
   my ($hi, $lo) = @$aref[$i, $i+1];
   print OUT pack "H*", $hi.$lo;
}
于 2013-07-25T14:44:29.313 回答