В общем я когда-то перерыл и перелопатил весь инет и так и не нашёл толковой информации по этой теме, особенно на Delphi.
И тут я, значит, брожу по гуглу и ищу инфу по одной теме и случайно тыкаю не на ту ссылку. И попадаю на известный блог: http://www.manhunter.ru/assembler/ И что я вижу! "Расчет энтропии на Ассемблере" и думаю: "Там, наверное, килотонны кода". Открываю и охреневаю от компактности кода. Дальше я быстро принимаюсь переписывать его на Delphi. Благо моих скромных познаний асма на это хватило.
Вот по этой формуле ведётся расчёт (Хотя я в математике дуб-дубом)
А вот и сам код:
Код
function CalcMemoryEntropy(const Memory: Pointer; Size: Cardinal): Extended;
var
Prob, Log2: Extended;
I, Sum, Chr: Integer;
Code: array[0..255] of Byte;
begin
Result:=0;
if (Memory=nil)or(Size=0) then
Exit
else
begin
for I:=0 to(Length(Code)-1) do
Code[I]:=0;
I:=0;
Sum:=0;
while (Cardinal(I)<Size) do
begin
Chr:=(Cardinal(PChar(Memory)[I]));
Inc(Code[Chr]);
Inc(Sum);
Inc(I);
end;
Log2:=Math.Log2(2.0);
for I:=0 to(Length(Code)-1) do
begin
if (Code[I]>0) then
begin
Prob:=Code[I]/Sum; // P(i) = SUM(i)/total
Result:=(Result-(Prob*(Math.Log2(Prob))/Log2)); // H(i) = -P(i)*log2(P(i))
end;
end;
end;
end;
Как видим, код получился достаточно простым.
Вот расчет для строки:
Код
function CalcStringEntropy(Str: string): Extended;
begin
Result:=CalcMemoryEntropy(PChar(Str), (Length(Str)));
end;
И примеры:
Без округлений энтропии:
Код
MessageBox(0, PChar(FloatToStr(CalcStringEntropy('123456789'))), nil, 0);
И с округлением до двух чисел после запятой:
Код
MessageBox(0, PChar(FormatFloat('#.##', CalcStringEntropy('123456789'))), nil, 0);
В первом случае результат будет: 3.169925000144231, а во втором 3.17.
Для чего это нужно и кому это надо? Это пригодится, например, для определения пакованности файла (как это делает PeID или DiE) и т.д.
P.S. Для вычисления энтропии файла достаточно немного изменить код.
P.S.S. Информация по теме: Wikipedia
-------------------------------------------------------------
Забыл сказать. Для работы требуется модуль Math.