Я не понимаю, почему вы хотели бы использовать здесь генератор случайных чисел ... однако я могу помочь вам ускорить процесс.
Фильтр Блума - это, по сути, битовый вектор, в котором вы устанавливаете биты. Если вы хотите выяснить, существует ли элемент, фильтр цветения выдаст вам истину, если элемент возможно существует, и ложь, если элемент наверняка не существует .
(Я делаю это в простом текстовом редакторе, поэтому в коде могут быть ошибки)
Я предполагаю, что ваше хеш-пространство может использовать 32-битные целочисленные вычисления; если у вас очень большая таблица цветения, вы, вероятно, захотите использовать 64-битное целое число.
Самая простая (и, вероятно, самая быстрая) реализация фильтра Блума:
byte[] bloomFilter = new byte[MyBloomFilterSize];
foreach (var item in myItems)
{
int hash = Hash(item) & 0x7FFFFFFF;
int bit = 1 << (hash & 7); // you have 8 bits
int index = (hash >> 3) % MyBloomFilterSize;
bloomFilter[hash % MyBloomFilterSize] |= bit;
}
Вы можете поэкспериментировать с изменением byte[]
на uint[]
или ulong[]
; Я не уверен, что это имеет значение.
Если затем вы хотите проверить, может ли элемент существовать, вы вычисляете тот же индекс и бит и получаете результат.
public bool PossiblyExists(MyItem item)
{
int hash = Hash(item) & 0x7FFFFFFF;
int bit = 1 << (hash & 7); // you have 8 bits
int index = (hash >> 3) % MyBloomFilterSize;
return (bloomFilter[hash % MyBloomFilterSize] & bit) != 0;
}
Единственное, что здесь остается, - это скорость, с которой вы можете вычислить хеш. Если вы используете целое число, я бы просто умножил его на большое простое число; если вы используете байт [] фиксированной длины SHA256 (что вы, кажется, делаете), вам нужно сделать его целым (или длинным).
Я использую небольшой трюк с Buffer.BlockCopy для преобразования типов. В целях безопасности я предпочитаю использовать несколько байтов из данных, но поскольку SHA256 уже должен быть случайным, простой BitConverter.ToInt32(data, [0..28])
также должен помочь.
public int CalculateHash(byte[] data)
{
// Data = >128 bits = >16 bytes -- which is the same as >4 integers
int[] tmp = new int[4];
Buffer.BlockCopy(data, 0, tmp, 0, data.Length);
return tmp[0] ^ tmp[1] ^ tmp[2] ^ tmp[3];
}
Это должно сработать.
person
atlaste
schedule
30.04.2014
random.Next
в некоторой степени противоречит цели наличия_numberOfHashes
в первую очередь ... Потому что хеши перестают быть действительно независимыми. Вы можете просто использовать несколько легких хешей (например, Fletcher, xxhash, Murmur). Или, поскольку ключ всего 128 бит ... возможно, сохранить весь ключ. (На случай, если я не совсем понял: я бы подумал о том, чтобы полностью потерять случайный шаг и напрямую использовать комбинацию независимых хешей) - person sehe   schedule 01.09.2013