エントロピーが必要な32,678kbの暗号化されたbinファイルがあります。私はより大きなプロジェクトの一部としてPerlを使用しています。
私はこれまでに次の「テクニック」を使用しました。
use Shannon::Entropy qw/entropy/;
my $file = "test.bin";
open(my $bin, "<", $file) or die $!; binmode $bin;
seek($bin, 0x000000, 0);
read($bin, my $entropy, 0x01FFFFF0);
print entropy($entropy);
これにより、30分以上経過するとあきらめるまで、ほぼ無限の待機時間が発生します。
ファイル全体のエントロピーをテストすることから逸脱することはできません。
もっと速い方法はありますか?それを分割し、エントロピーし、奇妙な数学を使用して再び組み合わせると、1つのファイルであるかのように同じエントロピーになりますか?
これは、すべてのマップ呼び出しを回避するために書き直されたエントロピー関数です。
sub entropy {
my ($entropy, $len, $p, %t) = (0, length($_[0]));
my @chars = split '', $_[0];
$t{$_}++ foreach @chars;
foreach (values %t) {
$p = $_/$len;
$entropy -= $p * log $p ;
}
return $entropy / log 2;
}
それはあなたのためにより速くうまくいくかもしれません
私はこれについて考え直しました。実際にファイルをメモリに丸呑みする必要はありません。$len
取得することができるファイルの長さ-s $file_name
と%t
時間のブロックに読み取ることによって計算することができる周波数テーブルです。したがって、ファイルのエントロピーを計算する関数のバージョンは次のようになります。
sub file_entropy {
my ($file_name) = @_;
# Get number of bytes in file
my $len = -s $file_name;
my ($entropy, %t) = 0;
open (my $file, '<', $file_name) || die "Cant open $file_name\n";
binmode $file;
# Read in file 1024 bytes at a time to create frequancy table
while( read( $file, my $buffer, 1024) ) {
$t{$_}++
foreach split '', $buffer;
$buffer = '';
}
foreach (values %t) {
my $p = $_/$len;
$entropy -= $p * log $p ;
}
return $entropy / log 2;
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加