Поиск функции хеширования/заказанных Int/to/Shuffled Int/

Я ищу алгоритм постоянного времени, который может изменить значение упорядоченного целочисленного индекса в случайный хэш-индекс. Было бы неплохо, если бы оно было обратимым. Мне нужен, чтобы хэш-ключ был уникальным для каждого индекса. Я знаю, что это можно сделать, если таблица просмотрит большой файл. И.Е. создайте упорядоченный набор всех int и затем произвольно перемешайте их и напишите в файл в случайной последовательности. Затем вы могли бы прочитать их, когда они вам понадобятся. Но это потребует поиска в большом файле. Интересно, есть ли простой способ использовать псевдослучайный генератор для создания последовательности по мере необходимости?

Генерация перетасованного диапазона с использованием PRNG, а не перетасовка erikkallen Линейные регистры сдвига обратной связи выглядят как правильные вещи. Я просто попробовал, но он производит повторы и дыры.

Отношения Дэвид Аллан Финч

Ответ 1

Вопрос теперь, если вам нужно действительно случайное сопоставление или просто "слабая" перестановка. Предполагая последнее, если вы работаете с 32-битными целыми числами без знака (скажем) на 2-арифметической арифметике, умножение на любое нечетное число является биективным и обратимым отображением. Конечно, то же самое относится и к XOR, поэтому простой шаблон, который вы можете попробовать использовать, например,

unsigned int hash(int x) {
   return (((x ^ 0xf7f7f7f7) * 0x8364abf7) ^ 0xf00bf00b) * 0xf81bc437;
}

В числах нет ничего волшебного. Таким образом, вы можете изменить их, и они могут быть даже рандомизированы. Единственное, что мультипликаторы должны быть нечетными. И вы должны рассчитывать с помощью rollaround (игнорируя переполнения). Это может быть инвертировано. Чтобы сделать инверсию, вы должны иметь возможность вычислить правильные дополнительные мультипликаторы A и B, после чего инверсия

unsigned int rhash(int h) {
    return (((x * B) ^ 0xf00bf00b) * A) ^ 0xf7f7f7f7;
}

Вы можете вычислить A и B математически, но для вас проще всего запустить цикл и выполнить поиск (например, в автономном режиме).

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

Ответ 2

Вы могли бы попытаться создать подходящую сеть Feistel. Обычно они используются для криптографии (например, DES), но с по меньшей мере 64 битами, поэтому вам, возможно, придется самостоятельно построить их, который соответствует вашим потребностям. Они обратимы по конструкции.

Ответ 3

Предполагая, что ваша цель состоит в распределении группированных значений по всему диапазону,
похоже, что перетасовка битов в некотором предопределенном порядке может сделать трюк.
то есть с учетом 8 бит ABCDEFGH, упорядочить их, как EGDBHCFA, или некоторую такую ​​структуру.

Код просто будет простой последовательностью масок, сдвигов и добавлений.

Ответ 4

Mmm... в зависимости, если у вас много чисел, вы можете использовать обычный список stl и заказать его по "случайным" критериям

bool
nonsort(int i, int j)
{
    return  random() & 31 >16 ? true : false;
}

std::list<int> li;
// insert elements
li.sort(nonsort);

Затем вы можете получить все целые числа с обычным итератором. Не забудьте инициализировать случайное значение с помощью srand() со временем или любым другим псевдослучайным значением.

Ответ 5

Для набора ограничений действительно нет решения. Попытка хэша 32-битного без знака в 32-битное без знака даст вам столкновений, если вы не сделаете что-то простое, например, от 1 до 1 отображения. Каждое число - это собственный хеш.