我有一串ASCII字符.我使用unpack函数将其转换为十六进制字符串.
#! /usr/bin/perl
use strict;
use warnings;
my $str="hello";
my $value=unpack("H*",$str);
print $value,"\n";
**output:** 68656c6c6f
Run Code Online (Sandbox Code Playgroud)
现在,让我们说,我想将此输出用作十六进制字节的字符串,一次读取一个字节并对其执行一些计算并将输出存储在另一个变量中.
例如,
#! /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
Run Code Online (Sandbox Code Playgroud)
输出不正确,还有几个警告.
如果我们取字符串的第一个十六进制字节,"hello"作为示例:
68 xor 12 = 7A
Run Code Online (Sandbox Code Playgroud)
但是,输出显示为86.输出不正确,我也不确定它的输出是86.
做正确的方法是什么?
如果某些东西是十六进制的,那么它必然是一个字符串,因为十六进制是一个人类可读的数字表示.你不需要一个字符串; 你想要一系列数字,其中每个数字都是char的数值.您可以使用ord逐字符来获取数字,但unpack也提供了以下方法:
my @bytes = unpack 'C*', $str;
Run Code Online (Sandbox Code Playgroud)
做你想要的处理:
$_ ^= $num for @bytes;
Run Code Online (Sandbox Code Playgroud)
并重新组成字符串:
$str = pack 'C*', @bytes;
Run Code Online (Sandbox Code Playgroud)
以上三项合并:
$str = pack 'C*', map $_ ^ $num, unpack 'C*', $str;
Run Code Online (Sandbox Code Playgroud)
您也可以这样做:
my $mask = chr($num) x length($str);
$str ^= $mask;
Run Code Online (Sandbox Code Playgroud)