Как вычислить приблизительную энтропию битовой строки?
Есть ли стандартный способ сделать это?
Поиск в Google - "примерные биты энтропии" - раскрывает несколько научных статей, но я хотел бы просто найти кусок псевдокода, определяющего приблизительную энтропию для данной строки битов произвольной длины.
(Если это легче сказать, чем сделать, и это зависит от приложения, мое приложение содержит 16 320 бит зашифрованных данных (зашифрованный текст). Но зашифровано как головоломка и не должно быть невозможно взломать. Я подумал, что сначала проверим энтропия, но не может легко найти хорошее определение такого. Так что это похоже на вопрос, который должен быть на Stackru! Идеи для того, с чего начать с дешифрования 16K случайных битов, также приветствуются...)
Смотрите также этот связанный вопрос:
Какое компьютерное определение энтропии?
8 ответов
Я считаю, что ответ Колмогорова Сложность строки. Мало того, что это не отвечает с порцией псевдокода, сложность Колмогорова не вычислима!
Одна вещь, которую вы можете сделать на практике, - это сжатие битовой строки наилучшим доступным алгоритмом сжатия данных. Чем больше он сжимает, тем ниже энтропия.
Энтропия - это не свойство строки, которую вы получили, а строки, которые вы могли бы получить вместо этого. Другими словами, он определяет процесс, с помощью которого была сгенерирована строка.
В простом случае вы получаете одну строку среди набора из N возможных строк, где каждая строка имеет одинаковую вероятность выбора, чем все остальные, т.е. 1 / N. В этой ситуации говорят, что строка имеет энтропию N. Энтропия часто выражается в битах, что является логарифмической шкалой: энтропия "n битов" - это энтропия, равная 2n.
Например: мне нравится генерировать мои пароли в виде двух строчных букв, затем двух цифр, затем двух строчных букв и, наконец, двух цифр (например, va85mw24
). Буквы и цифры выбираются случайным образом, равномерно и независимо друг от друга. Этот процесс может создать 26*26*10*10*26*26*10*10 = 4569760000 различных паролей, и все эти пароли имеют равные шансы на выбор. Тогда энтропия такого пароля составляет 4569760000, что означает около 32,1 бит.
Уравнение Шеннона для энтропии является стандартным методом расчета. Вот простая реализация в Python, бесстыдно скопированная из кодовой базы Revelation и, следовательно, лицензированная по лицензии 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)
Обратите внимание, что эта реализация предполагает, что ваш входной поток битов лучше всего представлен в байтах. Это может или не может иметь место в вашей проблемной области. То, что вы действительно хотите, это ваш битовый поток, преобразованный в строку чисел. То, как вы решите, что это за цифры, зависит от домена. Если ваши числа на самом деле только один и нули, то преобразуйте поток битов в массив единиц и нулей. Однако выбранный вами метод конвертации повлияет на результаты, которые вы получите.
В инструменте оценки генератора случайных чисел NIST есть способ вычисления "Приблизительной энтропии". Вот краткое описание:
Примерный тест энтропии Описание: в центре внимания этого теста - частота каждого перекрывающегося m-битового шаблона. Цель теста - сравнить частоту перекрывающихся блоков двух последовательных / смежных длин (m и m+1) с ожидаемым результатом для случайной последовательности.
Более подробное объяснение доступно в PDF на этой странице:
http://csrc.nist.gov/groups/ST/toolkit/rng/documentation_software.html
Там нет однозначного ответа. Энтропия всегда относительно некоторой модели. Когда кто-то говорит о пароле с ограниченной энтропией, он имеет в виду "относительно способности интеллектуального злоумышленника предсказывать", и это всегда верхняя граница.
Ваша проблема в том, что вы пытаетесь измерить энтропию, чтобы помочь вам найти модель, а это невозможно; что измерение энтропии может сказать вам, насколько хороша модель.
Сказав это, есть несколько довольно общих моделей, которые вы можете попробовать; они называются алгоритмами сжатия. Если gzip может хорошо сжимать ваши данные, вы нашли по крайней мере одну модель, которая может хорошо ее прогнозировать. А gzip, например, в основном нечувствителен к простой замене. Он может обрабатывать "wkh" часто в тексте так же легко, как и "".
Извините, что так долго отвечал на этот вопрос.
Взгляните на мою недавнюю статью:
"BiEntropy - приближенная энтропия конечной двоичной строки"
http://arxiv.org/abs/1305.0954
"Мы проектируем, реализуем и тестируем простой алгоритм, который вычисляет приблизительную энтропию конечной двоичной строки произвольной длины. Алгоритм использует средневзвешенное значение энтропий Шеннона строки и всех, кроме последней двоичной производной строки. Мы успешно проверить алгоритм в областях теории простых чисел (где мы явно докажем, что последовательность простых чисел не является периодической), человеческого зрения, криптографии, генерации случайных чисел и количественного финансирования "
Используя больцмановскую энтропию слова с этой формулой: https://imgur.com/a/DpcIH
Вот алгоритм O(n), который его вычисляет:
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()))
Вот реализация в Python (я также добавил ее на вики-страницу):
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)
Пример:
>>> U = np.array([85, 80, 89] * 17)
>>> ApEn(U, 2, 3)
-1.0996541105257052e-05
Приведенный выше пример согласуется с примером, приведенным в Википедии.