Perl - Pack复杂的16位字

时间:2014-06-09 01:04:44

标签: perl binary pack

我必须将一个复杂的消息打包成一个16位字,其定义如下:

  • 第1部分:错误状态(最低有效字节)
    • 位0:错误类型A(最低位)
    • 位1:错误类型B
    • 位2:错误类型C
    • 第3位:错误类型D
    • 第4位:错误类型E
    • 第5位:错误类型F
    • 位6:错误类型G
    • 位7:错误类型H(最高有效位)
  • 第2部分:模式/状态附加状态定义如下:
    • 模式:模式包含在最高有效字节的最低有效4位中。模式编号为0 - 11.
    • 第12位:状态类型A
    • 第13位:状态类型B
    • 位14:状态类型C
  • 附加状态:
    • 位15:重置开启/关闭

我似乎无法正确获取pack()命令。我想打包: 错误类型E,模式7,状态类型B,附加状态ON

my $msg = pack("n",
    pack("C", 0, 0, 0, 0, 1, 0, 0, 0), #error state
    pack("C", 7, 0, 1, 0, 1)
);

Perl doc,http://perldoc.perl.org/functions/pack.html,在包装字符时没有说小/大端。

2 个答案:

答案 0 :(得分:1)

您可以尝试使用vec代替打包。 例如:

vec($i, 0,1) = 1;               # set bit zero
print unpack('b*', $i), "\n";   # 10000000
vec($i, 1,1) = 1;               # set bit 1 
print unpack('b*', $i), "\n";   # 11000000
vec($i, 4,1) = 1;               # set bit 4
print unpack('b*', $i), "\n";   # 11001000
vec($i, 15,1) = 1;              # set bit 15
print unpack('b*', $i), "\n";   # 1100100000000001

答案 1 :(得分:1)

pack为每个输入生成1个或更多字节,因此它不能接受位。首先构建你的单词,然后传递给pack。

my $word = 0;

$word |= 1 << 0 if $error_type_A;
$word |= 1 << 1 if $error_type_B;
$word |= 1 << 2 if $error_type_C;
$word |= 1 << 3 if $error_type_D;
$word |= 1 << 4 if $error_type_E;
$word |= 1 << 5 if $error_type_F;
$word |= 1 << 6 if $error_type_G;
$word |= 1 << 7 if $error_type_H;

$word |= $mode << 8;

$word |= 1 << 12 if $status_type_A;
$word |= 1 << 13 if $status_type_B;
$word |= 1 << 14 if $status_type_C;

$word |= 1 << 15 if $reset;

pack 'n', $word