web-dev-qa-db-fra.com

Comment calculer l'entropie d'un fichier?

Comment calculer l'entropie d'un fichier? (ou disons juste un tas d'octets)
J'ai une idée, mais je ne suis pas sûre qu'elle soit mathématiquement correcte.

Mon idée est la suivante:

  • Créez un tableau de 256 entiers (tous des zéros).
  • Parcourez le fichier et pour chacun de ses octets,
    incrémente la position correspondante dans le tableau.
  • À la fin: calculez la valeur "moyenne" du tableau.
  • Initialiser un compteur avec zéro,
    et pour chacune des entrées du tableau:
    ajoutez la différence de l'entrée à "moyenne" au compteur.

Eh bien, maintenant je suis coincé. Comment "projeter" le résultat du compteur de telle manière que tous les résultats se situent entre 0,0 et 1,0? Mais je suis sûr, l'idée est de toute façon incohérente ...

J'espère que quelqu'un a des solutions meilleures et plus simples?

Remarque: j'ai besoin de tout pour faire des hypothèses sur le contenu du fichier:
(texte en clair, balisage, compressé ou binaire, ...)

67
  • À la fin: calculez la valeur "moyenne" du tableau.
  • Initialisez un compteur avec zéro, et pour chacune des entrées du tableau: ajoutez la différence de l'entrée à "moyenne" au compteur.

Avec quelques modifications vous pouvez obtenir l'entropie de Shannon:

renommer "moyenne" en "entropie"

(float) entropy = 0
for i in the array[256]:Counts do 
  (float)p = Counts[i] / filesize
  if (p > 0) entropy = entropy - p*lg(p) // lgN is the logarithm with base 2

Edit: Comme Wesley l'a mentionné, nous devons diviser l'entropie par 8 afin de l'ajuster dans la plage .. 1 (ou alternativement, nous pouvons utiliser la base logarithmique 256) .

47
Nick Dandoulakis

Une solution plus simple: gzipez le fichier. Utilisez le rapport entre les tailles de fichier: (taille du fichier compressé)/(taille de l'original) comme mesure du caractère aléatoire (c'est-à-dire l'entropie).

Cette méthode ne vous donne pas la valeur absolue exacte de l'entropie (car gzip n'est pas un compresseur "idéal"), mais elle est assez bonne si vous avez besoin de comparer l'entropie de différentes sources.

31
Igor Krivokon

Pour calculer l'entropie d'informations d'une collection d'octets, vous devrez faire quelque chose de similaire à la réponse de tydok. (La réponse de tydok fonctionne sur une collection de bits.)

On suppose que les variables suivantes existent déjà:

  • byte_counts est une liste de 256 éléments du nombre d'octets avec chaque valeur dans votre fichier. Par exemple, byte_counts[2] est le nombre d'octets qui ont la valeur 2.

  • total est le nombre total d'octets dans votre fichier.

J'écrirai le code suivant en Python, mais cela devrait être évident ce qui se passe.

import math

entropy = 0

for count in byte_counts:
    # If no bytes of this value were seen in the value, it doesn't affect
    # the entropy of the file.
    if count == 0:
        continue
    # p is the probability of seeing this byte in the file, as a floating-
    # point number
    p = 1.0 * count / total
    entropy -= p * math.log(p, 256)

Il y a plusieurs choses importantes à noter.

  • Le chèque pour count == 0 n'est pas seulement une optimisation. Si count == 0, puis p == 0, et log ( p ) ne seront pas définis ("infini négatif"), provoquant une erreur.

  • Le 256 dans l'appel à math.log représente le nombre de valeurs discrètes possibles. Un octet composé de huit bits aura 256 valeurs possibles.

La valeur résultante sera comprise entre 0 (chaque octet unique dans le fichier est le même) jusqu'à 1 (les octets sont répartis également entre chaque valeur possible d'un octet).


ne explication de l'utilisation de la base de journaux 256

Il est vrai que cet algorithme est généralement appliqué en utilisant la base de journal 2. Cela donne la réponse résultante en bits. Dans un tel cas, vous avez un maximum de 8 bits d'entropie pour un fichier donné. Essayez-le vous-même: maximisez l'entropie de l'entrée en faisant byte_counts une liste de tous 1 ou 2 ou 100. Lorsque les octets d'un fichier sont répartis uniformément, vous constaterez qu'il existe une entropie de 8 bits.

Il est possible d'utiliser d'autres bases de logarithmes. L'utilisation de b = 2 permet d'obtenir un résultat en bits, car chaque bit peut avoir 2 valeurs. L'utilisation de b = 10 place le résultat en dits , ou bits décimaux, car il y a 10 valeurs possibles pour chaque dit. L'utilisation de b = 256 donnera le résultat en octets, car chaque octet peut avoir l'une des 256 valeurs discrètes.

Fait intéressant, en utilisant les identités de journal, vous pouvez déterminer comment convertir l'entropie résultante entre les unités. Tout résultat obtenu en unités de bits peut être converti en unités d'octets en divisant par 8. En tant qu'effet secondaire intentionnel intéressant, cela donne l'entropie comme une valeur comprise entre 0 et 1.

En résumé:

  • Vous pouvez utiliser différentes unités pour exprimer l'entropie
  • La plupart des gens expriment l'entropie en bits ( b = 2)
    • Pour une collection d'octets, cela donne une entropie maximale de 8 bits
    • Puisque le demandeur veut un résultat entre 0 et 1, divisez ce résultat par 8 pour une valeur significative
  • L'algorithme ci-dessus calcule l'entropie en octets ( b = 256)
    • Cela équivaut à (entropie en bits)/8
    • Cela donne déjà une valeur entre 0 et 1
30
Wesley

Pour ce que ça vaut, voici le calcul traditionnel (bits d'entropie) représenté en c #

/// <summary>
/// returns bits of entropy represented in a given string, per 
/// http://en.wikipedia.org/wiki/Entropy_(information_theory) 
/// </summary>
public static double ShannonEntropy(string s)
{
    var map = new Dictionary<char, int>();
    foreach (char c in s)
    {
        if (!map.ContainsKey(c))
            map.Add(c, 1);
        else
            map[c] += 1;
    }

    double result = 0.0;
    int len = s.Length;
    foreach (var item in map)
    {
        var frequency = (double)item.Value / len;
        result -= frequency * (Math.Log(frequency) / Math.Log(2));
    }

    return result;
}
17
Jeff Atwood

Est-ce quelque chose que ent pourrait gérer? (Ou peut-être que ce n'est pas disponible sur votre plate-forme.)

$ dd if=/dev/urandom of=file bs=1024 count=10
$ ent file
Entropy = 7.983185 bits per byte.
...

Comme contre-exemple, voici un fichier sans entropie.

$ dd if=/dev/zero of=file bs=1024 count=10
$ ent file
Entropy = 0.000000 bits per byte.
...
14
Peter Kovacs

J'ai deux ans de retard dans la réponse, alors veuillez considérer cela malgré seulement quelques votes positifs.

Réponse courte: utilisez mes 1ère et 3ème équations en gras ci-dessous pour obtenir ce que la plupart des gens pensent quand ils disent "entropie" d'un fichier en bits. Utilisez juste la 1ère équation si vous voulez l'entropie H de Shannon qui est en fait entropie/symbole comme il l'a dit 13 fois dans son article dont la plupart des gens ne sont pas conscients. Certains calculateurs d'entropie en ligne utilisent celui-ci, mais le H de Shannon est "l'entropie spécifique", et non "l'entropie totale", ce qui a causé tant de confusion. Utilisez la 1ère et la 2ème équation si vous voulez la réponse entre 0 et 1 qui est l'entropie/symbole normalisé (ce n'est pas des bits/symbole, mais une véritable mesure statistique de la "nature entropique" des données en laissant les données choisir leur propre base de log au lieu d'attribuer arbitrairement 2, e ou 10).

Il 4 types d'entropie de fichiers (données) de N symboles longs avec n types uniques de symboles. Mais gardez à l'esprit qu'en connaissant le contenu d'un fichier, vous connaissez son état et donc S = 0. Pour être précis, si vous avez une source qui génère beaucoup de données auxquelles vous avez accès, vous pouvez alors calculer l'entropie/caractère futur attendu de cette source. Si vous utilisez ce qui suit sur un fichier, il est plus exact de dire qu'il estime l'entropie attendue d'autres fichiers à partir de cette source.

  • Entropie de Shannon (spécifique) H = -1 * somme (count_i/N * log (count_i/N))
    où count_i est le nombre d'occurrences du symbole i dans N.
    Les unités sont des bits/symbole si le journal est en base 2, nats/symbole si le journal naturel.
  • Entropie spécifique normalisée: H/log (n)
    Les unités sont entropiées/symbole. Les plages vont de 0 à 1. 1 signifie que chaque symbole s'est produit de manière égale et près de 0 est l'endroit où tous les symboles sauf 1 ne se sont produits qu'une seule fois, et le reste d'un fichier très long était l'autre symbole. Le journal est dans la même base que le H.
  • Entropie absolue S = N * H
    Les unités sont des bits si log est en base 2, nats si ln ()).
  • Entropie absolue normalisée S = N * H/log (n)
    L'unité est "entropique", varie de 0 à N. Le log est dans la même base que le H.

Bien que le dernier soit la "entropie" la plus vraie, le premier (l'entropie Shannon H) est ce que tous les livres appellent "l'entropie" sans la qualification (à mon humble avis). La plupart ne précisent pas (comme Shannon l'a fait) qu'il s'agit de bits/symbole ou d'entropie par symbole. Appeler H "entropie", c'est parler de façon trop vague.

Pour les fichiers à fréquence égale de chaque symbole: S = N * H = N. C'est le cas pour la plupart des gros fichiers de bits. L'entropie n'effectue aucune compression sur les données et est donc complètement ignorante de tous les modèles, donc 000000111111 a les mêmes H et S que 010111101000 (6 1 et 6 0 dans les deux cas).

Comme d'autres l'ont dit, l'utilisation d'une routine de compression standard comme gzip et la division avant et après donneront une meilleure mesure de la quantité d '"ordre" préexistant dans le fichier, mais cela est biaisé par rapport aux données qui correspondent mieux au schéma de compression. Il n'y a pas de compresseur parfaitement optimisé à usage général que nous pouvons utiliser pour définir un "ordre" absolu.

Une autre chose à considérer: H change si vous changez la façon dont vous exprimez les données. H sera différent si vous sélectionnez différents regroupements de bits (bits, quartets, octets ou hex). Donc, vous divisez par log (n) où n est le nombre de symboles uniques dans les données (2 pour le binaire, 256 pour les octets) et H sera compris entre 0 et 1 (il s'agit de l'entropie de Shannon intensive normalisée en unités d'entropie par symbole). Mais techniquement, si seulement 100 des 256 types d'octets se produisent, alors n = 100, pas 256.

H est une entropie "intensive", c'est-à-dire que c'est par symbole qui est analogue à entropie spécifique en physique qui est entropie par kg ou par mole. L'entropie "extensive" régulière d'un fichier analogue au S de la physique est S = N * H où N est le nombre de symboles dans le fichier. H serait exactement analogue à une partie d'un volume de gaz idéal. L'entropie de l'information ne peut pas simplement être rendue exactement égale à l'entropie physique dans un sens plus profond parce que l'entropie physique permet des arrangements "ordonnés" aussi bien désordonnés: l'entropie physique sort plus qu'une entropie complètement aléatoire (comme un fichier compressé). Un aspect des différents Pour un gaz idéal, il y a un facteur 5/2 supplémentaire pour expliquer cela: S = k * N * (H + 5/2) où H = états quantiques possibles par molécule = (xp) ^ 3/hbar * 2 * sigma ^ 2 où x = largeur de la boîte, p = momentum non directionnel total dans le système (calculé à partir de l'énergie cinétique et de la masse par molécule), et sigma = 0,341 conformément au principe d'incertitude ne donnant que le nombre de états possibles dans 1 std dev.

Un peu de mathématiques donne une forme plus courte d'entropie étendue normalisée pour un fichier:

S = N * H/log (n) = somme (count_i * log (N/count_i))/log (n)

Les unités de ceci sont "l'entropie" (qui n'est pas vraiment une unité). Elle est normalisée pour être une meilleure mesure universelle que les unités "entropiques" de N * H. Mais elle ne devrait pas non plus être appelée "entropie" sans clarification parce que la convention historique normale est d'appeler à tort H "entropie" (ce qui est contraire à les clarifications apportées dans le texte de Shannon).

12
zawy

L'entropie d'un fichier n'existe pas. En théorie de l'information, l'entropie est fonction d'un variable aléatoire, pas d'un ensemble de données fixe (enfin, techniquement un ensemble de données fixe a une entropie, mais cette entropie serait 0 - nous pouvons considérer les données comme une distribution aléatoire qui n'a qu'un seul résultat possible avec la probabilité 1).

Pour calculer l'entropie, vous avez besoin d'une variable aléatoire avec laquelle modéliser votre fichier. L'entropie sera alors l'entropie de la distribution de cette variable aléatoire. Cette entropie sera égale au nombre de bits d'informations contenus dans cette variable aléatoire.

10
Adam Rosenfield

Si vous utilisez l'entropie de la théorie de l'information, sachez qu'il peut être judicieux de ne pas l'utiliser sur des octets. Par exemple, si vos données sont constituées de flottants, vous devez plutôt ajuster une distribution de probabilité à ces flotteurs et calculer l'entropie de cette distribution.

Ou, si le contenu du fichier est constitué de caractères unicode, vous devez les utiliser, etc.

5
bayer

Re: J'ai besoin de tout pour faire des hypothèses sur le contenu du fichier: (texte en clair, balisage, compressé ou binaire, ...)

Comme d'autres l'ont souligné (ou ont été confondus/distraits par), je pense que vous parlez en fait de entropie métrique (entropie divisée par la longueur du message). Voir plus sur Entropie (théorie de l'information) - Wikipedia .

le commentaire de la gigue lié à Analyse des données pour les anomalies d'entropie est très pertinent pour votre objectif sous-jacent. Cela lie finalement à libdisorder (bibliothèque C pour mesurer l'entropie d'octets) . Cette approche semble vous donner beaucoup plus d'informations, car elle montre comment l'entropie métrique varie dans différentes parties du fichier. Voir par exemple ce graphique de la façon dont l'entropie d'un bloc de 256 octets consécutifs à partir d'une image jpg de 4 Mo (axe y) change pour différents décalages (axe x). Au début et à la fin, l'entropie est plus faible, à mi-chemin, mais elle est d'environ 7 bits par octet pour la majeure partie du fichier.

enter image description here Source: https://github.com/cyphunk/entropy_examples . [ Notez que ce graphique et d'autres graphiques sont disponibles via le roman http://nonwhiteheterosexualmalelicense.org licence ....]

Plus intéressant est l'analyse et les graphiques similaires à Analyse de l'entropie d'octets d'un disque au format FAT | GL.IB.LY

Des statistiques telles que le max, le min, le mode et l'écart-type de l'entropie métrique pour l'ensemble du fichier et/ou les premier et dernier blocs de celui-ci peuvent être très utiles comme signature.

Ce livre semble également pertinent: Détection et reconnaissance du masquage de fichiers pour la messagerie électronique et la sécurité des données - Springer

2
nealmcb

Calcule l'entropie de toute chaîne de caractères non signés de taille "longueur". Il s'agit essentiellement d'une refactorisation du code trouvé à http://rosettacode.org/wiki/Entropy . Je l'utilise pour un générateur IV 64 bits qui crée un conteneur de 100000000 IV sans dupes et une entropie moyenne de 3,9. http://www.quantifiedtechnologies.com/Programming.html

#include <string>
#include <map>
#include <algorithm>
#include <cmath>
typedef unsigned char uint8;

double Calculate(uint8 * input, int  length)
  {
  std::map<char, int> frequencies;
  for (int i = 0; i < length; ++i)
    frequencies[input[i]] ++;

  double infocontent = 0;
  for (std::pair<char, int> p : frequencies)
  {
    double freq = static_cast<double>(p.second) / length;
    infocontent += freq * log2(freq);
  }
  infocontent *= -1;
  return infocontent;
 }
2
iggy_pop