我需要帮助弄清楚这两个子例程是如何工作的,以及它们返回的值或数据结构。以下是代码的最小表示形式:
#!/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函数pack
和unpack
。此外,我在网上找不到任何好的例子。
我认为pack_phred_to_qual
子程序将质量数组ref转换回ASCII字符并打印它们。
谢谢。非常感谢您的任何帮助或建议。此外,如果有人能提供一个Perl的pack
和unpack
函数如何工作的简单例子,也会有所帮助。
不需要计算长度。这些功能可以简化为
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字符对的列表,每个字符对对应于第二个自变量中的一个字节。