2012-11-08 229 views
0

我有一串ASCII字符。我使用解壓函數將其轉換爲十六進制字符串。Perl中的十六進制計算

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

輸出不正確,也有幾個警告。

如果我們把字符串的第一個十六進制字節,「你好」作爲一個例子:

68 xor 12 = 7A 

但是,輸出其顯示爲86.輸出是不正確的,也是我不知道如何 它得到了86的輸出。

什麼是正確的做法呢?

+1

您使用的警告,但您試圖訪問其範圍以外$結果? – ugexe

回答

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; 
+0

謝謝,這很好,但我認爲只適用於ASCII字符。我正在處理一個二進制文件,這就是原因,我需要使用字節的十六進制表示。如果我理解它是正確的,你的方法將獲得每個字符的ASCII值並對其執行操作。我想用十六進制。 –

+1

@NeonFlash,不,它也適用於二進制字符串。 – cjm

+0

@Neon Flash,你錯了。 '^','ord'和'chr'完全不瞭解ASCII。他們都處理任意字符,這是一個數字的花哨詞。 – ikegami