Фильтр Блума на основе символов

Я новичок в Bloom Filter. Я понимаю, как реализовать фильтр Блума с битовым массивом, в котором мы хэшируем значение x с помощью k хэш-функций и устанавливаем каждый индекс битового массива равным 1.

Но мне интересно, как мы собираемся реализовать фильтр Блума с массивом символов? Особенно, если ввод - это строка. Один из способов, который я могу придумать, - это добавить значение ASCII каждого символа строки и хеша этого значения, а затем установить индекс массива символов на какое-то значение (я также не уверен, какое значение установить в массиве символов, если я использую этот метод, потому что он может 'не будет просто 0 или 1, поскольку мы не используем битовый массив), но вероятность ложного срабатывания будет очень высокой. Может кто-нибудь дать мне несколько идей для начала? (Мне не нужен фактический код, но я очень признателен, если вы дадите мне некоторое представление о том, какую хеш-функцию использовать и как сопоставить их с массивом символов)


person PassingBy    schedule 31.10.2017    source источник
comment
Я собираюсь использовать C ++   -  person PassingBy    schedule 02.11.2017


Ответы (1)


Вы можете использовать некоторый алгоритм хеширования, который преобразует его в целочисленный хэш, а затем рассматривает каждый его бит как часть массива бит или массива символов.

hash(S)=sum(S[i]*(p^i))_i=0 to n-1.

Вы можете использовать этот хеш 2 раза, чтобы уменьшить вероятность ложных срабатываний. Это даст вам разумное поведение.

Также выбор p должен быть ограничен простым числом, и он должен быть больше, чем количество символов в наборе алфавита.

  • Это даст вам лучший результат, чем простое добавление значений ascii.

Также странно то, что используемые хеш-функции должны быть независимыми и равномерно распределенными.

Еще одним критерием является скорость, поэтому стандартные криптографические хеши - не лучший выбор. (как sha1)

Я слышал об одном стандартном методе хеширования murmurhash, который вы можете попробовать использовать и сравнить с ожидаемым результатом.

Чтобы понять, как вы собираетесь его реализовать: -

Вы можете рассмотреть несколько хэш-функций, таких как murmur, fnv1a или даже простую, которую я представил, и тогда вы получите 3 значения из каждого хеша. Поместите их в соответствующие места. И тогда он будет работать как ваш фильтр цветения.

Здесь, поскольку вы реализуете разные хеш-функции, вероятность ложного срабатывания будет зависеть от нескольких хеш-функций, что приведет к лучшему результату.

Например:

Вы хотите хешировать stackoverflow. Теперь вы используете 3 хэш-функции, которые дают вам числа 11, 45 и 17. Вы бы сохранили карту, где вы поместите это значение.

{
   11: 1,
   45: 1,
   17: 1
}

Снова вы выполняете хеширование таким образом и получаете значения 11, 15 и 97.

Затем вы измените его на

{
  11: 1,
  15: 1,
  17: 1,
  45: 1,
  97: 1
}

Примечание: я упомянул здесь карту ... это может быть что-то вроде массива битов, в котором вы также устанавливаете биты. Например .. в случае stackoverflow 11,17 и 45 биты будут установлены в 1.

Обратите внимание, что эта карта поможет вам ответить на вопрос, есть ли элемент там или нет.

Теперь в случае запроса вы сделаете то же самое, получите хеш-значения и проверите, существуют ли эти значения. Если да, высока вероятность, что он есть (не совсем так, как это может быть ложное срабатывание), если нет, то это не совсем точно.

Предположим, теперь вы проверите, есть ли там строка «abcd». Вы применяете 3 хэш-функции, которые использовались ранее. Результаты 11,99,55. Вы проверите, все ли они существуют. Вы можете видеть, что 55 там нет. Так что строки «abcd» там нет.

person user2736738    schedule 31.10.2017
comment
Означает ли это, что я должен установить определенный индекс массива char как это хеш-значение? Если да, то как мне определить, какой индекс поставить? (С битовым массивом B это будет просто B (h1 (x)) = 1, B (h2 (x)) = 1 для каждой хеш-функции, но я не знаю, что делать с массивом char) - person PassingBy; 31.10.2017
comment
Look char array - это в основном коллекция char. Теперь весь массив символов представляет собой строку. Итак, вы конвертируете все это в int, используя упомянутый мною метод хеширования. Затем отключите фильтрацию Блума по этому целому числу. @ZhiyuanRuan - person user2736738; 31.10.2017
comment
@ZhiyuanRuan: Проверьте мой ответ .. Я обновил - person user2736738; 31.10.2017
comment
Я только что видел ваш измененный ответ. Я получил ваши баллы, но все еще не уверен, как выбрать подходящее место для размещения. Можете ли вы подробнее остановиться на этом? - person PassingBy; 31.10.2017
comment
@ZhiyuanRuan .: Я попробую..подождите - person user2736738; 31.10.2017
comment
@ZhiyuanRuan: Проверьте мой ответ ... он прост, но объяснит суть - person user2736738; 31.10.2017
comment
Спасибо. Если я правильно понимаю ваш ответ, значит ли это, что нам понадобится дополнительное пространство, например карта, для хранения хеш-значения? Если это так, мне кажется, что мы на самом деле не используем массив char, поскольку у нас есть что-то вроде карты для отслеживания хеш-значения и их позиций. - person PassingBy; 31.10.2017
comment
Но не сделает ли это дополнительное пространство бессмысленным наш исходный массив символов, поскольку мы ни для чего не используем этот массив символов? - person PassingBy; 31.10.2017
comment
@ZhiyuanRuan .: В противном случае вы ничего не сможете сделать с фильтром цветения ... эти массивы символов - это просто стремления..вычисления ... ничего больше ... вы можете распределить их двойным образом, а затем удалить их после того, как это будет сделано - person user2736738; 31.10.2017
comment
Большое Вам спасибо. И последний вопрос: как нам решить, в какую позицию поместить хеш-значения? Он не может быть случайным, поскольку при наличии определенных значений будет сложно выполнить поиск. В вашем примере вы помещаете все значения в ячейку 1, поскольку они из одной строки. Но когда мы проверяем, существует ли строка, как мы решаем, какое место проверять (например, как мы узнаем, что нам нужно проверять местоположение 1 для stackoverflow) Мне кажется, нам нужна другая функция, чтобы решить, какое место поместить. - person PassingBy; 31.10.2017
comment
@ZhiyuanRuan .: Предположим, вы хотите проверить, существует ли stackoverflow .... или нет? Он получит его хеш-значения, .. 11,45,17 ... а затем вы проверите, есть ли они на карте ... и все. Теперь вы знаете, что существует высокая вероятность того, что stackoverflow есть - person user2736738; 31.10.2017
comment
Мне интересно, используем ли мы дополнительное пространство, разве это не теряет смысл использования фильтра цветения, поскольку значение, которое мы добавляем, будет расти в отличие от типичного фильтра цветения, который использует фиксированное пространство? - person PassingBy; 31.10.2017
comment
Мы можем использовать дополнительное пространство, но время для ответа на запрос будет быстрее. - person user2736738; 31.10.2017
comment
Можно ли не использовать дополнительное пространство, а только с фильтром цветения m символов? - person PassingBy; 31.10.2017
comment
@ZhiyuanRuan .: Я не понимаю, как вы можете использовать его с m символами ... вы хешируете строки, а не символы ... - person user2736738; 31.10.2017
comment
@ZhiyuanRuan .: Похоже, вы сказали в своем вопросе ... вместо карты вы также можете использовать битовое поле ... где вы получаете доступ к каждому из бит ... таким образом это также можно сделать - person user2736738; 31.10.2017
comment
@ZhiyuanRuan .: Проверьте ответ .. Я добавил кое-что по поводу реализации - person user2736738; 31.10.2017
comment
Спасибо. Я вижу ваши точки с битовым массивом. Я спрашиваю, как это сделать с массивом символов и без карты (или любого другого дополнительного пространства) - person PassingBy; 31.10.2017
comment
Просто скажите мне, что вы думаете? - person user2736738; 31.10.2017
comment
Мой ввод - строка, такая как aab - person PassingBy; 31.10.2017
comment
Теперь посмотрим ... после того, как вы получите aab ... вы будете хешировать его, используя различные хеш-функции, а затем сохраните их в каком-то месте. Где их разместить? Каким-то образом вы установите бит в серии бит ... и это будет то, что вам понадобится ... как только вы закончите, вы можете прекратить использовать этот массив символов и удалить его ... это не имеет значения. - person user2736738; 31.10.2017