【问题标题】:How to make pack to fill data with zeroes from the beginning?如何使包从一开始就用零填充数据?
【发布时间】:2012-09-19 14:50:47
【问题描述】:

我在 perl 中使用pack / unpack 将十六进制值转换为十进制,如下所示:

print unpack "S", reverse pack "H4", "1230";
> 4656

一切都很好,而数据是 4 个十六进制符号。 如果数据长度不足以适应请求的格式包,则在末尾添加零。

像这样:

print unpack "b*", pack "H4", "FF";
> 1111111100000000

导致:

print unpack "S", reverse pack "H4", "123";
> 4656

虽然我希望它与oct 相同:

print oct("0x123");
> 291

print unpack "S", reverse pack "H4", "0123";
> 291

当数据长度不足以适应格式时,如何使pack在数据的开头添加零?

常见问题解答

你想做什么? 我有一堆函数来处理不同类型的数据(floatshortlongushortulong 等)。所有转换均使用pack/unpack 完成。需要这些函数来转换第三方生成的数据。

为什么不使用octhex 因为我必须处理有符号整数和浮点数。而且我希望所有函数都相似,以便更好地理解代码。

您能否提供更多示例?这里是:

示例 1: 有符号短整数(收到完整数据)。系统从第三方接收十六进制数据018F。这个数据应该是signed short,所以按如下方式处理:

print unpack "s", reverse pack "H4", "018F";
> 399

示例 2: 有符号短整数(接收到一半数据)。系统从第三方接收十六进制数据8F8F 只有 1 个字节,而形成短整数则需要 2 个字节。处理方式相同:

print unpack "s", reverse pack "H4", "8F";
> -28928

但是第三方是指008F而不是8F00

print unpack "s", reverse pack "H4", "008F";
> 143

print unpack "s", reverse pack "H4", "8F00";
> -28928

字节序呢? 在所有示例中,接收到的数据都是big-endian,而我的系统是little-endian,这就是使用reverse 的原因。

你现在怎么处理?我正在使用 sprintf 加零。

print unpack "s", reverse pack "H4", sprintf "%04s", "8F";
> 143

你使用什么版本的 perl? 5.8.8

【问题讨论】:

  • 对我来说似乎是XY Problem。你想做什么 ? printf("%04d",hex("123")) 否则就足够了。
  • 感谢您的指点XY Problem。我在我的问题中添加了简短常见问题解答部分以提供更多信息。希望现在更清楚了。

标签: perl hex pack


【解决方案1】:

您知道有一个内置的hex 函数可以将十六进制值转换为十进制,不是吗?

$ perl -e 'print hex("123")'
291

【讨论】:

  • hex 函数只能用于无符号整数(据我所知)。但我也必须处理有符号整数。
【解决方案2】:

如果问题只是字节序,请在解压缩模板中使用 <> 修饰符。 见perldoc -f pack。 Perl 的设计者对这些问题并非一无所知:

print unpack "s", reverse pack "H4", "008F";
> 143        (on little-endian system)

print unpack "s>", pack "H4", "8F";
> 143

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    • 2020-06-29
    • 1970-01-01
    • 2021-11-25
    • 2023-02-09
    • 1970-01-01
    • 2020-10-31
    相关资源
    最近更新 更多