如何在Perl中将十六进制值字符串输出到二进制文件中?
我试图读入一个二进制文件,将数据存储为一个十六进制值字符串,用它修改一些十六进制值,然后将数据输出到一个新的二进制文件中(这是对原始文件稍加修改的版本) 除了最后一步,我可以完成所有这些步骤。当我在十六进制编辑器中打开新的二进制文件时,一切似乎都错了。。。我希望它完全是我的十六进制字符串,但在十六进制编辑器 以下是我在创建新文件时尝试执行的操作:如何在Perl中将十六进制值字符串输出到二进制文件中?,perl,file-io,Perl,File Io,我试图读入一个二进制文件,将数据存储为一个十六进制值字符串,用它修改一些十六进制值,然后将数据输出到一个新的二进制文件中(这是对原始文件稍加修改的版本) 除了最后一步,我可以完成所有这些步骤。当我在十六进制编辑器中打开新的二进制文件时,一切似乎都错了。。。我希望它完全是我的十六进制字符串,但在十六进制编辑器 以下是我在创建新文件时尝试执行的操作: # Format data string into an array for file processing @data_ary = unpack('
# 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);
}
我猜我的问题与我使用。但我真的不知道如何将一个巨大的十六进制字符串转换成一种形式,在这种形式下,它实际上将被读取为十六进制而不是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);
}
#将数据字符串格式化为数组以进行文件处理
@data_ari=split/,$data_str;
生成新文件($filname,\@data\u ari);
子生成新文件
{
my$fname=“mod-”.shift(@);
我的$aref=班次(@);
打开(BIN,“>”,$fname)或死亡;
BIN模式(BIN);
对于(我的$i=0;$i<@$aref;$i+=2)
{
我的($hi,$lo)=@$aref[$i,$i+1];
打印垃圾箱包装“H”$hi.$lo;
}
关闭(垃圾箱);
}
我知道了!我打电话时忘记了“*”,所以它不仅仅是第一个字符!完成的代码如下。谢谢阿蒙
# 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);
}
#将数据字符串格式化为数组以进行文件处理
@data_ari=split/,$data_str;
生成新文件($filname,\@data\u ari);
子生成新文件
{
my$fname=“mod-”.shift(@);
我的$aref=班次(@);
打开(BIN,“>”,$fname)或死亡;
BIN模式(BIN);
对于(我的$i=0;$i<@$aref;$i+=2)
{
我的($hi,$lo)=@$aref[$i,$i+1];
打印箱子包装“H*”,$hi.$lo;
}
关闭(垃圾箱);
}
此处,解包
返回单个字符串,而不是值数组。如果希望有一个十六进制字符数组(每个字符表示4位),则必须拆分
结果字符串:
my @data = split //, unpack "H*", $data;
(使用split/。\K/,$data
拆分为字节等价物)
在将此数据打印到文件句柄之前,您还必须对其进行打包
以再次获取原始数据。我建议至少在原始数据的8位部分执行此操作:
for (my $i = 0; $i < @$aref; $i += 2) {
my ($hi, $lo) = @$aref[$i, $i+1];
print OUT pack "H*", $hi.$lo;
}
for(我的$i=0;$i<@$aref;$i+=2){
我的($hi,$lo)=@$aref[$i,$i+1];
打印出包装“H*”,$hi.$lo;
}
如果您解包
,通常需要打包
才能获得相同的格式。为了澄清一下,它是如何返回单个字符串的?那个解包不应该在标量上下文中,因为分配给了数组,对吗?我现在真的很困惑lol。只是尝试实现这个,我得到了一个不同的结果,但仍然不正确。结果文件的大小应该是原文件的两倍。它在十六进制编辑器中也完全混乱了。因为H
模式创建了一个十六进制字符串,所以只返回一个值;与上下文无关。它不会创建类似于qw/00A097/
的列表,而是“00A097”
。当我们将这个字符串拆分为nybles(qw/0a097/
)时,我们必须在打包之前加入它。这就是我的循环。如果我们不这样做,我们将创建一个等价的“\x00\x00\xA0\x00\x90\x70”
,这很有意义。我越来越近了。我从一开始就删除了解包,因为我的数据已经是一个十六进制字符串。所以我就把它拆分,放到数组中。至少现在文件的大小是正确的。然而,我的新问题是,它正在裁剪每个字节的第二部分,并将其替换为0。。。有什么想法吗?很抱歉。我已经用我现在使用的代码对问题进行了编辑。这基本上是你建议的,但是没有第一次解包。我的错,只要使用模式H*
,它应该可以正常工作。(很抱歉,没有看到您的编辑)