perl-如何将字符串视为二进制数?

时间:2014-07-26 05:55:04

标签: perl

读取包含地址和数据的文件,如下所示:

@0, 12345678
@1, 5a5a5a5a
...

我的目标是阅读地址和数据。考虑我读取的数据是十六进制格式,然后我需要将它们解压缩为二进制数。 因此12345678将成为00010010001101000101011001111000 然后,我需要进一步将传输的二进制数解包到另一个级别。 所以它变成了,00000000000000010000000000010000000000000001000100000001000000000000000100000001000000010001000000000001000100010001000000000000

我的方式就像下面的

while(<STDIN>) {
 if (/\@(\S+)\s+(\S+)/) {
    $addr = $1;
    $data = $2;
    $mem{$addr} = ${data};
 } 
}

foreach $key (sort {$a <=> $b} (keys %mem)) {

  my $str = unpack ('B*', pack ('H*',$mem{$key}));
  my $str2 = unpack ('B*', pack ('H*', $str));
  printf ("@%x ", $key);
  printf ("%s",$str2);
  printf ("\n"); 
}

然而,它的工作原理是我的下一步是对传输的位进行一些数值运算。 如按位或移位。我试过&lt;&lt;和|运算符,两者都是数字,而不是字符串。所以我不知道如何解决这个问题。

如果您有更好的想法,请留下您的意见。谢谢。

3 个答案:

答案 0 :(得分:2)

您可以使用metaCPAN中的Bit::Vector模块

use strict;
use warnings;
use Bit::Vector;

my $str = "1111000011011001010101000111001100010000001111001010101000111010001011";
printf "orig str: %72s\n", $str;

#only 72 bits for better view
my $vec = Bit::Vector->new_Bin(72,$str);
printf "vec     : %72s\n", $vec->to_Bin();

$vec->Move_Left(2); 
printf "left 2  : %72s\n", $vec->to_Bin();

$vec->Move_Right(4); 
printf "right 4 : %72s\n", $vec->to_Bin();

打印:

orig str:   1111000011011001010101000111001100010000001111001010101000111010001011
vec     : 001111000011011001010101000111001100010000001111001010101000111010001011
left 2  : 111100001101100101010100011100110001000000111100101010100011101000101100
right 4 : 000011110000110110010101010001110011000100000011110010101010001110100010

如果您需要以任意精度进行数学运算,您还可以使用Math::BigIntuse biginthttp://perldoc.perl.org/bigint.html

答案 1 :(得分:2)

十六进制和二进制是数字的 text 表示。移位和位操作是数值操作。你想要一个数字,而不是文本。

my $hex = '5a5a5a5a';
$num = hex($hex);               # Convert to number.
$num >>= 1;                     # Manipulate the number.
$hex = sprintf('%08X', $num);   # Convert back to hex.

在评论中,您提到要处理256位数字。原生数字不支持,但您可以使用Math :: BigInt。

答案 2 :(得分:0)

我对此的最终解决方案是忘记将它们视为数字,只需将它们视为字符串即可。我使用子串和字符串浓度而不是shift。然后对于或操作,我只是添加字符串的每一位,如果它为0则结果为0,否则为1.

这可能不是解决此问题的最佳方法。但这就是我最终使用的方式。