"Случайные" идентификаторы
От: malphunction  
Дата: 19.09.10 10:26
Оценка:
Пишу библиотеку, в которой создаются объекты с уникальными идентификаторами. Сейчас это обычный инкремент,
поэтому объекты получают идентификаторы 0, 1, 2, ..., n, n+1, ...

Подскажите какую-нибудь простую функцию, которая по-случайнее "разбрасывает" идентификаторы по некоторому диапазону
(например, [0..UINT_MAX)), но так, чтобы генерируемые идентификаторы оставались уникальными. Например, чтобы
получалась последовательность 54231, 3, 9547, 4431, 1, 8877, ...

Сложность алгоритма должна быть O(1) и без дополнительных огромных массивов и т.п.

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

Было бы идеально получить обратную функцию, ну да это уже не так важно.

Это нужно вот для чего: после генерации с этими идентификаторами производятся некие манипуляции,
поэтому хочется проверить поведение библиотеки на разных значениях этих идентификаторов (и её независимость от
прямого следования). Кроме того, пользователи могут подумать, что идентификаторы последовательны и использовать
это в своих корыстных целях -- например, они могут полагать, что первый объект всегда имеет идентификатор 0, и явно забивать
этот 0 в свои программы (а не использовать getNextId() из моей библиотеки). Да и внутри библиотеки это не
помешает.
Re: "Случайные" идентификаторы
От: _DAle_ Беларусь  
Дата: 19.09.10 10:33
Оценка: 37 (3) +1
Здравствуйте, malphunction, Вы писали:

http://en.wikipedia.org/wiki/Linear_congruential_generator не подойдет? Он в общем-то обычно используется в стандартном rand.
Re: "Случайные" идентификаторы
От: andy1618 Россия  
Дата: 19.09.10 10:54
Оценка:
Здравствуйте, malphunction, Вы писали:

M>Подскажите какую-нибудь простую функцию, которая по-случайнее "разбрасывает" идентификаторы по некоторому диапазону

M>(например, [0..UINT_MAX)), но так, чтобы генерируемые идентификаторы оставались уникальными. Например, чтобы
M>получалась последовательность 54231, 3, 9547, 4431, 1, 8877, ...

M>Сложность алгоритма должна быть O(1) и без дополнительных огромных массивов и т.п.


Задачка известная, вот пара ссылок на обсуждение: здесь
Автор:
Дата: 05.05.08
, здесь
Автор: a18
Дата: 23.08.07
Re: "Случайные" идентификаторы
От: dilmah США  
Дата: 19.09.10 12:08
Оценка:
берешь симметричный блочный шифр с размером блока, равным размеру идентификатора. Для 64-битного блока таких шифров полно. Для 32 бит придется специально затачивать. Берешь случайный ключ и последовательно (в режиме ECB) шифруешь им блоки содержащие 0, 1, 2, 3, и т.д.
Re: "Случайные" идентификаторы
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 19.09.10 12:45
Оценка:
Здравствуйте, malphunction, Вы писали:

M>Пишу библиотеку, в которой создаются объекты с уникальными идентификаторами. Сейчас это обычный инкремент,

M>поэтому объекты получают идентификаторы 0, 1, 2, ..., n, n+1, ...

M>Подскажите какую-нибудь простую функцию, которая по-случайнее "разбрасывает" идентификаторы по некоторому диапазону

M>(например, [0..UINT_MAX)), но так, чтобы генерируемые идентификаторы оставались уникальными. Например, чтобы
M>получалась последовательность 54231, 3, 9547, 4431, 1, 8877, ...

M>Сложность алгоритма должна быть O(1) и без дополнительных огромных массивов и т.п.


M>Получается, это должна быть какая-то негладкая биективная функция...


Вот этот вывод уже поспешен. Например, если сильно расширить объём идентификатора, то можно обойтись просто случайной его генерацией. 128 бит для этого хватит с головой. Можно воспользоваться системным генератором UUID'ов, если они не MAC-based.

Ещё можно использовать симметричный шифр (см. ответ dilmah'а), но я бы делал чуть не так: шифруется не номер по порядку, а адрес структуры объекта в памяти библиотеки. Дополнительная польза — можно расшифровать и сравнить с адресом.
The God is real, unless declared integer.
Re[2]: "Случайные" идентификаторы
От: dilmah США  
Дата: 19.09.10 14:03
Оценка:
N>но я бы делал чуть не так: шифруется не номер по порядку, а адрес структуры объекта в памяти библиотеки. Дополнительная польза — можно расшифровать и сравнить с адресом.

тут вопрос для чего эти идентификаторы используются. Если у объектов есть время жизни, то старый и новый объекты могут иметь одинаковый адрес.
Собственно, в последний раз когда я использлвал такие идентификаторы в своей практике они использовались как раз с целью отличать новый объект от привидений из прошлого которые размещались по этому же адресу.
Re[3]: "Случайные" идентификаторы
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 20.09.10 05:26
Оценка:
Здравствуйте, dilmah, Вы писали:


N>>но я бы делал чуть не так: шифруется не номер по порядку, а адрес структуры объекта в памяти библиотеки. Дополнительная польза — можно расшифровать и сравнить с адресом.


D>тут вопрос для чего эти идентификаторы используются. Если у объектов есть время жизни, то старый и новый объекты могут иметь одинаковый адрес.

D>Собственно, в последний раз когда я использлвал такие идентификаторы в своей практике они использовались как раз с целью отличать новый объект от привидений из прошлого которые размещались по этому же адресу.

Да, в таком случае действительно нужна своя нумерация.
The God is real, unless declared integer.
Re[2]: "Случайные" идентификаторы
От: malphunction  
Дата: 21.09.10 00:41
Оценка:
Здравствуйте, _DAle_, Вы писали:

_DA>http://en.wikipedia.org/wiki/Linear_congruential_generator не подойдет? Он в общем-то обычно используется в стандартном rand.


Спасибо, самое то: дешево и сердито.

Не знал, что rand() периодичен, да ещё и с регулируемым периодом.
Re[3]: "Случайные" идентификаторы
От: malphunction  
Дата: 21.09.10 00:43
Оценка:
Здравствуйте, dilmah, Вы писали:


N>>но я бы делал чуть не так: шифруется не номер по порядку, а адрес структуры объекта в памяти библиотеки. Дополнительная польза — можно расшифровать и сравнить с адресом.


D>тут вопрос для чего эти идентификаторы используются. Если у объектов есть время жизни, то старый и новый объекты могут иметь одинаковый адрес.

D>Собственно, в последний раз когда я использлвал такие идентификаторы в своей практике они использовались как раз с целью отличать новый объект от привидений из прошлого которые размещались по этому же адресу.

Интересно, что это за проект был, в котором потребовалось такое решение? Есть информация в инете?
Re[4]: "Случайные" идентификаторы
От: dilmah США  
Дата: 21.09.10 09:23
Оценка:
D>>тут вопрос для чего эти идентификаторы используются. Если у объектов есть время жизни, то старый и новый объекты могут иметь одинаковый адрес.
D>>Собственно, в последний раз когда я использлвал такие идентификаторы в своей практике они использовались как раз с целью отличать новый объект от привидений из прошлого которые размещались по этому же адресу.

M>Интересно, что это за проект был, в котором потребовалось такое решение? Есть информация в инете?


допустим есть некая асинхронная система, может быть многопоточная, или использующая libevent. На каждый объект могут быть ссылки в других частях системы, и в будущем может прийти коллбэк или сообщение для него.
Часто может быть нужно удалить объект. Но при этом удалять все связанные с ним задачи может быть и дорого (в многопоточных системах на это потребуется синхронизация) или это может требовать кучи говнокода, или в моем случае это было просто невозможно, потому что интерфейс libevent/evdns не предоставляет возможность отменить DNS коллбэк.
Не уничтожать объект пока все задачи не отработают также неуместно.
Поэтому просто объектам присваиваются уникальные идентификаторы, для живых идентификаторов хранится соответствие идентификатора адресу объекта; когда объект уничтожается, он удаляется, удаляется все связанное с ним что можно легко удалить, на удаление остальных следов забивается, и его идентификатор удаляется из множества живых.
Когда приходит коллбэк или сообщение для неживого идентификатора оно просто игнорируется.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.