web-dev-qa-db-fra.com

Comment calculer l'entropie approximative d'une chaîne de bits?

Existe-t-il un moyen standard de procéder?

Googler - bits "entropie approximative" - découvre plusieurs articles académiques mais je voudrais juste trouver un morceau de pseudocode définissant l'entropie approximative pour une chaîne de bits donnée de longueur arbitraire.

(Dans le cas où cela est plus facile à dire qu'à faire et cela dépend de l'application, mon application implique 16 320 bits de données chiffrées (chiffrement). Mais chiffrées comme un puzzle et pas censées être impossibles à résoudre. l'entropie mais n'a pas pu facilement trouver une bonne définition de cela. Donc, cela semblait être une question qui devrait être sur StackOverflow! Des idées pour commencer par décrypter des bits de 16k au hasard sont également les bienvenus ...)

Voir aussi cette question connexe:
Quelle est la définition informatique de l'entropie?

43
dreeves

Je crois que la réponse est le Kolmogorov Complexity de la chaîne. Non seulement cela ne répond pas avec un morceau de pseudocode, la complexité de Kolmogorov n'est pas un fonction calculable !

Une chose que vous pouvez faire en pratique est de compresser la chaîne de bits avec le meilleur algorithme compression de données disponible. Plus il se comprime, plus l'entropie est faible.

12
dreeves

L'entropie n'est pas une propriété de la chaîne que vous avez obtenue, mais des chaînes que vous auriez pu obtenir à la place. En d'autres termes, il qualifie le processus par lequel la chaîne a été générée.

Dans le cas simple, vous obtenez une chaîne parmi un ensemble de N chaînes possibles, où chaque chaîne a la même probabilité d'être choisie que toutes les autres, c'est-à-dire - 1/N. Dans ce cas, la chaîne aurait une entropie de N . L'entropie est souvent exprimée en bits, ce qui est une échelle logarithmique: une entropie de "n bits" est une entropie égale à 2n.

Par exemple: j'aime générer mes mots de passe sous la forme de deux lettres minuscules, puis de deux chiffres, puis de deux lettres minuscules et enfin de deux chiffres (par exemple va85mw24). Les lettres et les chiffres sont choisis au hasard, uniformément et indépendamment les uns des autres. Ce processus peut produire 26 * 26 * 10 * 10 * 26 * 26 * 10 * 10 = 4569760000 mots de passe distincts, et tous ces mots de passe ont des chances égales d'être sélectionnés. L'entropie d'un tel mot de passe est alors 4569760000, ce qui signifie environ 32,1 bits.

31
Thomas Pornin

équation d'entropie de Shannon est la méthode de calcul standard. Voici une implémentation simple en Python, copiée sans vergogne à partir de la base de code Revelation , et donc sous licence GPL:

import math


def entropy(string):
        "Calculates the Shannon entropy of a string"

        # get probability of chars in string
        prob = [ float(string.count(c)) / len(string) for c in dict.fromkeys(list(string)) ]

        # calculate the entropy
        entropy = - sum([ p * math.log(p) / math.log(2.0) for p in prob ])

        return entropy


def entropy_ideal(length):
        "Calculates the ideal Shannon entropy of a string with given length"

        prob = 1.0 / length

        return -1.0 * length * prob * math.log(prob) / math.log(2.0)

Notez que cette implémentation suppose que votre flux binaire d'entrée est mieux représenté sous forme d'octets. Cela peut ou non être le cas pour votre domaine problématique. Ce que vous voulez vraiment, c'est que votre train de bits soit converti en une chaîne de chiffres. La façon dont vous décidez quels sont ces numéros dépend du domaine. Si vos nombres ne sont vraiment qu'un et des zéros, alors convertissez votre train de bits en un tableau de uns et de zéros. Cependant, la méthode de conversion que vous choisissez affectera les résultats que vous obtenez.

20
fmark

Il n'y a pas de réponse unique. L'entropie est toujours relative à un modèle. Quand quelqu'un parle d'un mot de passe ayant une entropie limitée, cela signifie "par rapport à la capacité d'un attaquant intelligent de prédire", et c'est toujours une limite supérieure.

Votre problème est que vous essayez de mesurer l'entropie afin de vous aider à trouver un modèle, et c'est impossible; ce qu'une mesure d'entropie peut vous dire, c'est la qualité d'un modèle.

Cela dit, il existe des modèles assez génériques que vous pouvez essayer; on les appelle des algorithmes de compression. Si gzip peut bien compresser vos données, vous avez trouvé au moins un modèle qui peut bien le prévoir. Et gzip est, par exemple, insensible à la substitution simple. Il peut gérer "wkh" fréquemment dans le texte aussi facilement qu'il peut gérer "the".

8
Cypherpunks

Désolé de répondre si longtemps à cette question.

Jetez un œil à mon récent article:

"BiEntropy - L'entropie approximative d'une chaîne binaire finie"

http://arxiv.org/abs/1305.0954

"Nous concevons, implémentons et testons un algorithme simple qui calcule l'entropie approximative d'une chaîne binaire finie de longueur arbitraire. L'algorithme utilise une moyenne pondérée des entropies Shannon de la chaîne et tout sauf le dernier dérivé binaire de la chaîne. Nous avons réussi tester l'algorithme dans les domaines de la théorie des nombres premiers (où nous prouvons explicitement que la séquence des nombres premiers n'est pas périodique), la vision humaine, la cryptographie, la génération de nombres aléatoires et la finance quantitative "

7
Grenville Croll

La boîte à outils d'évaluation du générateur de nombres aléatoires du NIST permet de calculer "l'entropie approximative". Voici la courte description:

Description approximative du test d'entropie: l'objectif de ce test est la fréquence de chaque motif de m bits qui se chevauchent. Le but du test est de comparer la fréquence des blocs qui se chevauchent de deux longueurs consécutives/adjacentes (m et m + 1) avec le résultat attendu pour une séquence aléatoire.

Et une explication plus approfondie est disponible à partir du PDF sur cette page:

http://csrc.nist.gov/groups/ST/toolkit/rng/documentation_software.html

4
rob

Voici une implémentation en Python (je l'ai également ajoutée à la page Wiki):

import numpy as np

def ApEn(U, m, r):

    def _maxdist(x_i, x_j):
        return max([abs(ua - va) for ua, va in Zip(x_i, x_j)])

    def _phi(m):
        x = [[U[j] for j in range(i, i + m - 1 + 1)] for i in range(N - m + 1)]
        C = [len([1 for x_j in x if _maxdist(x_i, x_j) <= r]) / (N - m + 1.0) for x_i in x]
        return -(N - m + 1.0)**(-1) * sum(np.log(C))

    N = len(U)

    return _phi(m) - _phi(m + 1)

Exemple:

>>> U = np.array([85, 80, 89] * 17)
>>> ApEn(U, 2, 3)
-1.0996541105257052e-05

L'exemple ci-dessus est cohérent avec l'exemple donné sur Wikipedia .

1
Ulf Aslak

En utilisant l'entropie de Shannon d'un mot avec cette formule: http://imgur.com/a/DpcIH

Voici un algorithme O(n) qui le calcule:

import math
from collections import Counter


def entropy(s):
    l = float(len(s))
    return -sum(map(lambda a: (a/l)*math.log2(a/l), Counter(s).values()))
0
Thomas Dussaut