perl - 读取二进制数据并将其转换为十六进制
问题描述
我是 perl 的新手。我正在尝试编写从二进制文件中读取数据并以特定格式返回的代码。它可以是十进制、无符号、十六进制……我的二进制文件在十六进制编辑器中打开时看起来像这样:
7C 00 48 00 D6 00 E4 07 04 07 14 36 39 00 00 36 00 D6 00 44 CD 08 FF 00 00 00 00 FF 00 00 00 00 FF 00 00 00 00 FF 00 00 00 00 7C 00 48 00 D6 00 E4 07 04 07 14 37 02 00 00 36 00 D6 00 44 CE 07 FF 00 00 00 00 FF 00 00
我知道文件中的每 9 个字节代表 1 个完整单元,其中包含 6 个变量:开始一个 1 字节无符号整数、Devtype 1 字节有符号整数和 4 个字节hexDevUID,年一个 2 字节无符号整数,月和日每个都是 1 字节无符号整数。这是我的代码无法正常运行:
#!/usr/bin/perl
use feature qw(say);
use strict;
use warnings;
use constant BUFSIZE => 9;
my @input_file;
@input_file = 'path\ZONE0.txt';
open (my $BIN, "<:raw", $input_file[$i]) or die "can't open the file @input_file: $!";
my $buffer;
while (1) {
my $bytes_read = sysread $BIN, $buffer, BUFSIZE;
die "Could not read file @input_file: $!" if !defined $bytes_read;
last if $bytes_read <= 0;
my @decimal= map { unpack "C", $_ } split //, $buffer;
my $start= $decimal[0];
my $DevType = $decimal[1];
my @DevUID =@decimal[5,4,3,2];
my $string_DevUID = join('', $string_DevUID);
my $hexDevUID =sprintf("0x%x",$string_DevUID);
my @year=@decimal[6,7];
my $month=$decimal[8];
my $day = $decimal[9];
say $start;
say $DevType;
say $hexDevUID;
say @year;
say $month;
say $day;
}
我的想法是一次读取 9 个字节,然后分别处理变量,但我确信我在split 和 unpack之间丢失了正确的值。我能够获得一些数据,但值不正确,它们与我的十六进制编辑器显示的不匹配。我还尝试一次读取一个字节并加入超过 1 个字节的变量的值,但我仍然以某种方式弄乱了这些值,关于我做错了什么有什么想法吗?
更新:我猜拆分返回一个字符数组,格式可能会在该步骤中丢失,但我不知道另一种从 $buffer 中获取数组的方法。如果(如下所示)我尝试直接解压缩缓冲区而不进行拆分,我的代码会生成此错误。:
Use of uninitialized value in join or string
解决方案
一旦有了缓冲区,就不要将 is 视为字符串。unpack
立即使用正确的格式。不要将它作为字符拆开,只是为了让它回到整数:
use v5.10;
my $buffer =
"\x7C" . "\x00\x48\x00\xD6" . "\x00" .
"\xE4\x07" . "\x04" . "\x07";
my @values = unpack 'CNCSCC', $buffer;
say "@values";
那N
可能是一个V
. 查看pack
文档以了解您希望八位位组采用哪种方式。
unpack
然后,一旦你有了数字,就用它们做数字的事情(没有任何顺序和移位是有意义的。如果你合适的话,你不需要做这部分:
my @array = @decimal[5,4,3,2];
my $string_DevUID;
while( my( $i, $v ) = each @array ) {
$string_DevUID += $v << ($i+1)
}
推荐阅读
- python - python脚本在我的谷歌云上获取面向外部的ips
- ios - 'realm/util/features.h' 文件未找到 重新安装 Pod 时偶尔发生。领域-JS
- opengl - 如何将着色器中的值传递给 CPU?
- mysql - 其他笔记本电脑上的用户拒绝 MySQL 访问
- wordpress - WP - 重力表格/用户注册 - 映射多选和复选框
- bash - 使用本地配置分支进行 Git 涂抹和清理
- python - 打印列表中所有目标出现的索引的函数
- c++ - C ++将指针设置为NULL值的正确方法
- sql - 如何在一次选择中从不同子查询中获取子查询计数器的一部分?
- visual-studio-code - 在 vscode 上配置 clang++-9