Perl中的十六进制计算

时间:2012-11-08 02:10:17

标签: perl xor unpack

我有一串ASCII字符。我使用解包函数将其转换为十六进制字符串。

#! /usr/bin/perl

use strict;
use warnings;

my $str="hello";
my $value=unpack("H*",$str);

print $value,"\n";

**output:** 68656c6c6f

现在,让我们说,我想将此输出用作十六进制字节的字符串,一次读取一个字节并对其执行一些计算并将输出存储在另一个变量中。

例如,

#! /usr/bin/perl

use strict;
use warnings;

my $str="hello";
my $value=unpack("H*",$str);

my $num=0x12;
my $i=0;

while($i<length($value))
{
    my $result.=(substr($value,$i,2)^$num);
    $i+=2;
}

print $result,"\n";

**output:**

Argument "6c" isn't numeric in bitwise xor (^) at test.pl line 13.
Argument "6c" isn't numeric in bitwise xor (^) at test.pl line 13.
Argument "6f" isn't numeric in bitwise xor (^) at test.pl line 13.
8683202020

输出不正确,还有几个警告。

如果我们取字符串的第一个十六进制字节,“hello”作为例子:

68 xor 12 = 7A

然而,输出显示为86.输出不正确,我也不知道如何 它的输出为86。

这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:6)

如果某些内容是十六进制的,那么它必然是一个字符串,因为十六进制是数字的人类可读表示。你不需要一个字符串;你想要一系列数字,其中每个数字都是char的数值。您可以使用ord逐个字符获取数字,但unpack也提供了方法:

my @bytes = unpack 'C*', $str;

进行所需的处理:

$_ ^= $num for @bytes;

重新组成字符串:

$str = pack 'C*', @bytes;

以上三者合并:

$str = pack 'C*', map $_ ^ $num, unpack 'C*', $str;

您也可以按照以下方式执行此操作:

my $mask = chr($num) x length($str);
$str ^= $mask;