我需要帮助弄清楚这两个子程序如何工作以及它们返回的值或数据结构。这是代码的最小代表:
#!/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
函数如何工作也会有所帮助。
答案 0 :(得分:3)
这很简单,就像打包一样。是调用unpack("c12", "C~#p)eOA
/&gt; *)`依次取每个字母并找到该字母的ascii值,然后从该值中减去64(好吧,减去64是一个后处理步骤,没有给做包装)。所以字母“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。
答案 1 :(得分:3)
计算长度是不必要的。这些功能可以简化为
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, @_ }
pack / unpack根本不考虑加密/解密;它只是迭代每个字节的一种方式。
答案 2 :(得分:1)
这不是你问题的完整答案,但是你读过perlpacktut吗?或pack上的unpack / perldoc文档?这些可能会帮助你理解。
编辑:
这是一个想到它的简单方法:假设你有一个4字节的数字存储在内存中,1234。如果那是在perl标量,$ num,那么
pack('s*', $num)
将返回
π♦
或“1234”的实际内部存储值。因此pack()
将标量值视为字符串,并将其转换为数字的实际二进制表示形式(您看到“pi-diamond”打印出来,因为这是该数字的ASCII表示)。相反,
unpack('s*', "π♦")
将返回字符串“1234”。
unpack()
子例程的unpack_qual_to_phred()
部分可以简化为:
my @q = unpack("c12", "C~#p)e0A`/>*");
将返回ASCII字符对列表,每对对应于第二个参数中的一个字节。