【问题标题】:Convert byte to sequence of bits (binary) in Perl在 Perl 中将字节转换为位序列(二进制)
【发布时间】:2012-07-27 23:12:39
【问题描述】:

在过去的几个小时里,我一直在思考这个问题;这里有很多类似的问题,但没有完全相同,而且我见过的技术似乎都没有奏效。

我有一个字节序列(整数),这些字节是从程序中的输入生成的——每个字节代表 BMP 图像中像素的红色、绿色或蓝色值。我本质上需要提取每个字节的比特流表示;也就是那个字节的二进制序列。

我一直在使用pack()unpack() 的许多不同变体,但我没有得出正确的结果。

例如:

sub convertToBinary {
    my $str = unpack("B32", pack("N", shift));
    return $str;
}

我也试过了:

my $str = unpack("b8", shift);,

my $str = unpack("B8", shift);,

my $str = unpack("b*", shift);

还有许多其他变体;他们似乎都没有工作。我不觉得提取一个字节的位模式应该太难了..只有八个'1'或'0',对吧?

我在这里错过了什么?

【问题讨论】:

  • 你能给出可能的输入和期望输出的具体例子吗?
  • 当然 - 这会有所帮助。目标是找到在 .BMP 中编码的字符 - 速记练习。 .BMP 中的每个像素都有一个红色、绿色和蓝色值,每个值都用一个代码字节表示。在每个字节中,最低有效位将设置为零,然后使用新值编码作为消息的一部分。我主要有我需要的东西,但我很难提取每个字节的按位值。
  • 您不想要位表示。您可以使用按位& 检查是否设置了位。也就是说,您的输入仍然非常模糊
  • 好吧,我会尽量具体一点。我的输入是一个 .BMP 文件。整个文件。我读了它,并使用$offset = unpack("L", substr($bmp, 10, 4)); 来查找实际像素数据的开始位置。所以它是一个字符串开头。然后,在for 循环中,我使用$byte = unpack("CCC",substr($bmp, $offset + $counter, 1)); 拉出每个字节 - 所以我最终得到一个代表红色、绿色数量的三个字符(或 3 个数字,我不确定)的值,或某个像素的蓝色。我正在尝试将包含该值的字节转换为位序列,以便查找隐藏字符
  • 虽然很有可能在该步骤之前的某个地方我做了一些导致我丢失编码到每个字节中的消息位

标签: perl byte bit


【解决方案1】:

我想你在找sprintf

sub convertToBinary {
  return sprintf '%08b', shift;
}

【讨论】:

  • 成功了——谢谢!至少,它允许我获得正确的二进制表示。不过,我仍然有点卡住了-我在上面更具体地写了。我现在有了二进制表示,但我不确定我是否已经以指数方式丢失了未使用的位(它本来可以容纳消息),或者我是否仍在错误地提取它。
【解决方案2】:

根据评论,您实际上想检查是否设置了字节的最低有效位。

解决方案取决于您所说的字节。

如果你有一个 8 位字符:

if (ord("\xAC") & 0x01)

如果你有一个 8 位数字:

if (0xAC & 0x01)

原答案:

听起来你想要一个字节的二进制表示。解决方案取决于您所说的字节。

如果你有一个 8 位字符:

unpack('B8', "\xAC")

sprintf('%08b', ord("\xAC"))

sprintf('%08b', unpack('C', "\xAC"))

如果你有一个 8 位数字:

sprintf('%08b', 0xAC)

unpack('B8', chr(0xAC))

unpack('B8', pack('C', 0xAC))

以上所有都产生字符串10101100

【讨论】:

  • 如果我错了,请您更准确地指定输入和输出。
  • sprintf 方法用于返回二进制表示!谢谢。
  • 我还是有一些困难;我在上面的评论中写了更多关于它的内容。有点困惑:当我执行print unpack('B8', 10); 时,它会产生 00110001。当我将其插入到十进制的转换器中时,我得到 49 - 不确定那里发生了什么
  • @Nik,这不是我为 8 位数字提出的三个解决方案之一。您正在使用需要 8 位字符的解决方案之一。
  • @Nik,发生的事情是您传递了两个字节/字符“10”(“\x31\x30”)。 Perl 继续给出前 8 个位的表示(“00110001”)
猜你喜欢
  • 2021-12-05
  • 2017-11-22
  • 2019-03-14
  • 2012-07-16
  • 1970-01-01
  • 1970-01-01
  • 2013-03-06
  • 2011-02-18
  • 1970-01-01
相关资源
最近更新 更多