Perl Cryptology:使用pack和unpack函数加密/解密ASCII字符



我需要帮助弄清楚这两个子例程是如何工作的,以及它们返回的值或数据结构。以下是代码的最小表示形式:

#!/usr/bin/perl
use strict; use warnings;
# an array of ASCII encrypted characters
my @quality = ("C~#p)eOA`/>*", "DCCec)ds~~", "*^&*"); # for instance
# input the quality
# the '@' character in front deferences the subroutine's returned array ref 
my @q = @{unpack_qual_to_phred(@quality)};
print pack_phred_to_qual(@q) . "n";
sub unpack_qual_to_phred{
    my ($qual)=@_;
    my $upack_code='c' . length($qual);
    my @q=unpack("$upack_code",$qual);
    for(my $i=0;$i<@q;$i++){
        $q[$i]-=64;
    }
    return(@q);
}
sub pack_phred_to_qual{
    my ($q_ref)=@_;
    @q=@{$q_ref};
    for(my $i=0;$i<@q;$i++){
        $q[$i]+=64;
    }
    my $pack_code='c' . int(@q);
    my $qual=pack("$pack_code",@q);
    return ($qual);
}

1;

根据我的理解,unpack_qual_to_phread()子程序显然对存储在@quality中的ASCII字符元素进行了解密。子程序读入一个包含ASCII字符元素的数组。数组的每个元素都经过处理并明显解密。然后,子程序返回一个数组ref,其中包含解密数组的元素。我理解这么多,但是我并不真正熟悉Perl函数packunpack。此外,我在网上找不到任何好的例子。

我认为pack_phred_to_qual子程序将质量数组ref转换回ASCII字符并打印它们。

谢谢。非常感谢您的任何帮助或建议。此外,如果有人能提供一个Perl的packunpack函数如何工作的简单例子,也会有所帮助。

不需要计算长度。这些功能可以简化为

sub unpack_qual_to_phred { [ map $_ - 64, unpack 'c*', $_[0] ] }
sub pack_phred_to_qual { pack 'c*', map $_ + 64, @{ $_[0] } }

就加密而言,这是一个疯狂的简单替代密码。它只是从每个字符的字符数中减去64。它可能被写成

sub encrypt { map $_ - 64, @_ }
sub decrypt { map $_ + 64, @_ }

打包/解包根本不考虑加密/解密;这只是对每个字节进行迭代的一种方式。

就包而言,它相当简单。Is正在调用unpack("c12", "C~#p)eOA/>*)`,它依次获取每个字母并找到该字母的ascii值,然后从该值中减去64(好吧,减去64是后处理步骤,与pack无关)。所以字母"C"是ascii 67,67-64是3。因此,该函数中的第一个值是3。接下来是"~",它是ascii 126。126-64是62。接下来是#,它是ascii 35,35-64是-29,等等

从您的脚本生成的完整数字集是:

3,62,-29,48,-23,37,15,1,32,-17,-2,-22

"加密"步骤只是颠倒了这个过程。添加64,然后转换为char。

这不是你问题的完整答案,但你读过perlpacktut吗?还是perldoc上的打包/解包文档?这些可能会在很大程度上帮助你理解。

编辑:

这里有一个简单的方法:假设内存中存储了一个4字节的数字,1234。如果它在perl标量$num中,那么

pack('s*', $num)

将返回

π♦

或者不管"1234"的实际内部存储值是什么。所以pack()将标量值视为字符串,并将其转换为数字的实际二进制表示(您可以看到打印出来的"pi菱形",因为这是该数字的ASCII表示)。相反,

unpack('s*', "π♦")

将返回字符串"1234"。


unpack_qual_to_phred()子程序的unpack()部分可以简化为:

my @q = unpack("c12", "C~#p)e0A`/>*");

它将返回ASCII字符对的列表,每个字符对对应于第二个自变量中的一个字节。

最新更新