0

ASCII 文字列があります。unpack 関数を使用して、これを 16 進文字列に変換します。

#! /usr/bin/perl

use strict;
use warnings;

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

print $value,"\n";

**output:** 68656c6c6f

ここで、この出力を 16 進バイトの文字列として使用し、一度に 1 バイトずつ読み取り、それに対して何らかの計算を実行し、出力を別の変数に格納するとします。

例えば、

#! /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

出力が正しくなく、いくつかの警告もあります。

文字列の最初の 16 進バイト「hello」を例にすると、次のようになります。

68 xor 12 = 7A

ただし、出力は86と表示されます。出力は正しくなく、86の出力がどのように得られたのかもわかりません。

それを行う正しい方法は何ですか?

4

1 に答える 1

6

何かが 16 進数の場合、16 進数は人間が判読できる数字の表現であるため、必然的に文字列になります。文字列は必要ありません。一連の数値が必要です。これらの数値のそれぞれが char の数値です。ord文字ごとに数字を取得するために使用できますがunpack、手段も提供します。

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

必要な処理を行います。

$_ ^= $num for @bytes;

そして、文字列を再構成します:

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

上記の 3 つを組み合わせると、次のようになります。

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

次のようにすることもできます。

my $mask = chr($num) x length($str);
$str ^= $mask;
于 2012-11-08T02:22:03.243 に答える