-
Делаю инет Магазин(Ы )) ), встала задача генерации номера заявки ( заказа, партнумбера товара ) - на входе есть уникальный идентификатор , нужно на основе него получить другой уникальный.
Вот пример
Есть номер заказа 2000 , через 10 минут есть еще один заказ 2001, мне нужно получить что-то вроже такого:
2000 - 983484
2001 - 547883
1. основная идея спрятать идентификаторы
2. вторая идея, чтоб нельзя было понять сколько идет товара за какое-то время( утром сделал заказ фиктивный, и вечером, на основе разницы идентификаторов получаем количество заказов в день).
что в голове сейчас:
1. сдвиг побитовый
2. добавление к 2000 рнд слева и справа, типа 32200031
3. тупой метод : берем последовательность случайный чисел из 100000, и находим первый не используемый номер
Есть идеи что еще можно. хочется какого-нибудь изящества. -
Для этого придумали хеш-функции. Можно взять любую, применить, и отрезать от результата столько символов, сколько влезает в поле:
import hashlib hidden_id = hasshlib.md5(str(id)).hexdigest()[:7]Если обязательно-обязательно надо сделать из этого десятичное представление, то:
hidden_id = int(hidden_id, 16) -
Пункт 2 в первом списке не понятен.
hash(str(2000))
hash(str(2001))
оно? -
Олег, hash не даёт случайности. Попробуйте сделать
map(hash, map(str, range(2000, 2010))), по разбросу результатов вполне можно прикинуть порядок количества заказов. -
Сравнил, действительно, там более простое и эффективное по скорости хеширование
http://effbot.org/zone/python-hash.htm -
2Иван Сагалаев - уникальностьи не будет так мы отрезаем символы
2000 - md5 - 08f90c1a417155361a5c4b8d297e0d78 - получаем 08f90c1, следовательно любая последовательно мд5 типа 08f90c13322242343234324432, даст нам тот же идентификкатор, поэтому я мд5 то и исключил. есть еще идея взять epoc и его в шестнацетиричное представление, но тогда номер заказа будет не очень приятным. так как по телефону его будет говорить сложно. -
уникальностьи не будет так мы отрезаем символы
Вы зря делаете такое предположение, оно неверно. И md5, и sha-функции как раз специально разработаны таким образом, что вероятность изменчивости битов по всей из длине равномерна. То есть свойством уникальности (до некоторой вероятности) обладает любой произвольный кусок хеша. Разница только в количестве комбинаций. 5 символов шестнадцатеричного дайджеста — это 20 бит, соответственно вероятность коллизии — примерно одна миллионная. Возьмите 7 символов — будет примерно 1/260 млн. Поверьте, этого хватает.
по телефону его будет говорить сложно
Это в любом случае так будет. К сожалению, бизнес обычно свою мнительность ставит выше и здравого смысла, и удобства клиентов.
-
Собственно, чтобы не теоретизировать, вот:
>>> len(set([md5(str(i)).hexdigest()[:6] for i in range(10000)])) 10000 >>> len(set([md5(str(i)).hexdigest()[:8] for i in range(50000)])) 50000 >>> len(set([md5(str(i)).hexdigest()[:9] for i in range(100000)])) 100000Первые 10000 заказов производят уникальные 6-символьные md5. На 100000 заказов надо уже взять 9 символов. 9 символов в десятичном представлении — 11 цифр. Их вполне можно разбить на группы типа 1234-5678-912, чтобы удобнее читать.
-
Ну и напоследок, можно просто нагенерить, например, 7-циферных номеров, размешать их в случайном порядке, сохранить эту последовательность в базе, и брать из этого пула номер для нового заказа.
-
В порядке бреда. :)
Возьмите ряд простых чисел, допустим, в интервале 1000 - 10000. Их там 1061 штука. И выбирайте сочетания по 2. Например, в порядке N1*N2, N2*N3... N(k-1)*N(k), N1*N3, N2*N4... N(k-2)*N(k)... N(1)*N(K).
Получите последовательность длиной 562330 из уникальных чисел 7-8 знаков длиной. И с непросто определяемой закономерностью. Можно хвост зашумить случайной цифрой, чтобы не бросалось в глаза, что все числа нечётные.
Понадобится хранить массив чисел, лучше, наверное, в памяти и два счётчика в базе: для позиции и длины шага. -
А шифрование не катит? Либо стеганография :).
-
А через бд не катит? Простая табличка: [номер заказа, идентификатор]
-
Есть утилита uuid, генерит любые случайные идентификаторы. Например:
In [2]: uuid.uuid4()
Out[2]: UUID('9384ffd8-e2d6-4f0b-af29-e325229a044a')
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.



