なんとなく、以下のような感じでしょうか
#!/usr/bin/perl use strict; use warnings; use Data::Dumper; my $SEED_BASE = '(3hvKT1w0!W5xA}_/9^eDpR{Gt4S[coPNMnkHiL' 'jUmY27r).Xz]lZFyECs=qgBaOVbId8~-J6Qfu'; my $PCP_TABLE = {}; my $FIXED_NUM = 383; main(); sub main { my $encoded = pcp_encode('end0tknr','crt'); print "$encoded\n"; my $decoded = pcp_decode($encoded,'crt'); print "$decoded\n"; } sub pcp_encode { my($comment,$key_str) = @_; $comment .="\0" if length($comment) % 2; my @key = split(//,$key_str); my $j = pcp_make_table(@key); my $i = 0; $comment =~ s/./sprintf("%03o",ord($&)^(ord($key[$i++ % @key])+($j++ % $FIXED_NUM)))/ges; $comment=~ s/../$PCP_TABLE->{$&}/g; return $comment; } sub pcp_decode { my($comment,$key_str) = @_; $comment = $_[0]; my @key = split(//,$key_str); my $j = pcp_make_table(@key); $comment=~ s/./$PCP_TABLE->{$&}/g; my $i = 0; $comment =~ s/.../sprintf("%c",oct($&)^(ord($key[$i++ % @key]) +($j++ % $FIXED_NUM)))/ges; $comment=~s/\0$//; return $comment; } sub pcp_make_table{ my(@key) = @_; my @list; my @seed = split(//,$SEED_BASE); my $k = scalar(@key); my $init_j=0; for(my $i=0;$i<64;$i++){ my $j=ord($key[$i % $k]); $init_j +=$j; $list[$i]=splice(@seed,(($j+$k) % (64-$i)),1); } $k=0; for(my $i=0;$i<8;$i++){ for(my $j=0;$j<8;$j++,$k++){ $PCP_TABLE->{"$i$j"}=$list[$k]; $PCP_TABLE->{$list[$k]}="$i$j"; } } return ($init_j % $FIXED_NUM); }