2

これら 2 つのサブルーチンがどのように機能し、どのような値またはデータ構造が返されるのかを理解する助けが必要です。コードの最小限の表現を次に示します。

#!/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()サブルーチンは に格納されている ASCII 文字要素を解読しているよう@qualityです。サブルーチンは、ASCII 文字の要素を含む配列を読み込みます。配列の各要素が処理され、明らかに復号化されます。次に、サブルーチンは、復号化された配列の要素を含む配列 ref を返します。これはよくわかります、Perl の関数packunpack. また、それらの良い例をオンラインで見つけることができませんでした。

pack_phred_to_qualサブルーチンは、品質配列 ref を ASCII 文字に変換して出力すると思います。

ありがとう。どんな助けや提案も大歓迎です。また、誰かが Perlpackunpack関数がどのように機能するかの簡単な例を提供できれば、それも役に立ちます。

4

3 に答える 3

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, @_ }

パック/アンパックは、暗号化/復号化をまったく考慮していません。これは、各バイトを反復処理する方法にすぎません。

于 2012-07-17T04:32:14.470 に答える
3

パックが進むにつれて、それはかなり単純です。Isはunpack("c12", "C~#p)eOA/>*) `を呼び出しています。これは、各文字を順番に取得し、その文字のASCII値を見つけて、値から64を減算します(64を減算することは後処理ステップであり、パックとは関係ありません)。したがって、文字「C」はASCII 67で、67-64は3です。したがって、その関数の最初の値は3です。次は「〜」で、ASCII126です。126-64は62です。次は#でASCII35です。 、および35-64は-29などです。

スクリプトから生成される数値の完全なセットは次のとおりです。

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

「暗号化」ステップは、このプロセスを単純に逆にします。64を加算してから、charに変換します。

于 2012-07-17T04:25:00.920 に答える
1

これはあなたの質問に対する完全な答えではありませんが、perlpacktutを読みましたか?または、perldocでドキュメントをパック/アンパックしますか?それらはおそらくあなたが理解するのを助けるのに大いに役立つでしょう。

編集:

これを考える簡単な方法は次のとおりです。4バイトの数値がメモリに格納されているとしましょう。1234。それがperlスカラーの場合、$ num、

pack('s*', $num)

戻るだろう

π♦

または、「1234」の実際の内部ストレージ値が何であれ。したがってpack()、スカラー値を文字列として扱い、それを数値の実際の2進表現に変換しました(「pi-diamond」はその数値のASCII表現であるため、出力されます)。逆に、

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

文字列「1234」を返します。


サブルーチンのunpack()一部は、次のunpack_qual_to_phred()ように簡略化できます。

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

これはASCII文字ペアのリストを返します。各ペアは2番目の引数のバイトに対応します。

于 2012-07-17T04:21:53.267 に答える