读取包含地址和数据的文件,如下所示:
@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;和|运算符,两者都是数字,而不是字符串。所以我不知道如何解决这个问题。
如果您有更好的想法,请留下您的意见。谢谢。
答案 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::BigInt或use bigint
(http://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.
这可能不是解决此问题的最佳方法。但这就是我最终使用的方式。