1. p.elagin

    17.02.2010

    0 ↑
    1 ↓
    Делаю инет Магазин(Ы )) ), встала задача генерации номера заявки ( заказа, партнумбера товара ) - на входе есть уникальный идентификатор , нужно на основе него получить другой уникальный.

    Вот пример
    Есть номер заказа 2000 , через 10 минут есть еще один заказ 2001, мне нужно получить что-то вроже такого:

    2000 - 983484
    2001 - 547883

    1. основная идея спрятать идентификаторы
    2. вторая идея, чтоб нельзя было понять сколько идет товара за какое-то время( утром сделал заказ фиктивный, и вечером, на основе разницы идентификаторов получаем количество заказов в день).

    что в голове сейчас:

    1. сдвиг побитовый
    2. добавление к 2000 рнд слева и справа, типа 32200031
    3. тупой метод : берем последовательность случайный чисел из 100000, и находим первый не используемый номер



    Есть идеи что еще можно. хочется какого-нибудь изящества.
  2. Иван Сагалаев

    17.02.2010

    0 ↑
    0 ↓

    Для этого придумали хеш-функции. Можно взять любую, применить, и отрезать от результата столько символов, сколько влезает в поле:

    import hashlib
    hidden_id = hasshlib.md5(str(id)).hexdigest()[:7]
    

    Если обязательно-обязательно надо сделать из этого десятичное представление, то:

    hidden_id = int(hidden_id, 16)
    
  3. Олег Селиванов

    17.02.2010

    0 ↑
    0 ↓
    Пункт 2 в первом списке не понятен.

    hash(str(2000))
    hash(str(2001))
    оно?
  4. Иван Сагалаев

    17.02.2010

    0 ↑
    0 ↓

    Олег, hash не даёт случайности. Попробуйте сделать map(hash, map(str, range(2000, 2010))), по разбросу результатов вполне можно прикинуть порядок количества заказов.

  5. Олег Селиванов

    17.02.2010

    0 ↑
    0 ↓
    Сравнил, действительно, там более простое и эффективное по скорости хеширование
    http://effbot.org/zone/python-hash.htm
  6. p.elagin

    17.02.2010

    0 ↑
    1 ↓
    2Иван Сагалаев - уникальностьи не будет так мы отрезаем символы

    2000 - md5 - 08f90c1a417155361a5c4b8d297e0d78 - получаем 08f90c1, следовательно любая последовательно мд5 типа 08f90c13322242343234324432, даст нам тот же идентификкатор, поэтому я мд5 то и исключил. есть еще идея взять epoc и его в шестнацетиричное представление, но тогда номер заказа будет не очень приятным. так как по телефону его будет говорить сложно.
  7. Иван Сагалаев

    17.02.2010

    1 ↑
    0 ↓

    уникальностьи не будет так мы отрезаем символы

    Вы зря делаете такое предположение, оно неверно. И md5, и sha-функции как раз специально разработаны таким образом, что вероятность изменчивости битов по всей из длине равномерна. То есть свойством уникальности (до некоторой вероятности) обладает любой произвольный кусок хеша. Разница только в количестве комбинаций. 5 символов шестнадцатеричного дайджеста — это 20 бит, соответственно вероятность коллизии — примерно одна миллионная. Возьмите 7 символов — будет примерно 1/260 млн. Поверьте, этого хватает.

    по телефону его будет говорить сложно

    Это в любом случае так будет. К сожалению, бизнес обычно свою мнительность ставит выше и здравого смысла, и удобства клиентов.

  8. Иван Сагалаев

    17.02.2010

    0 ↑
    0 ↓

    Собственно, чтобы не теоретизировать, вот:

    >>> 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, чтобы удобнее читать.

  9. Иван Сагалаев

    17.02.2010

    0 ↑
    0 ↓

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

  10. alxrem

    17.02.2010

    0 ↑
    0 ↓
    В порядке бреда. :)

    Возьмите ряд простых чисел, допустим, в интервале 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 знаков длиной. И с непросто определяемой закономерностью. Можно хвост зашумить случайной цифрой, чтобы не бросалось в глаза, что все числа нечётные.

    Понадобится хранить массив чисел, лучше, наверное, в памяти и два счётчика в базе: для позиции и длины шага.
  11. lizzard

    19.02.2010

    0 ↑
    2 ↓
    А шифрование не катит? Либо стеганография :).
  12. andrian

    24.02.2010

    1 ↑
    0 ↓
    А через бд не катит? Простая табличка: [номер заказа, идентификатор]
  13. Grigory Fateyev

    16.03.2010

    3 ↑
    0 ↓
    Есть утилита uuid, генерит любые случайные идентификаторы. Например:
    In [2]: uuid.uuid4()
    Out[2]: UUID('9384ffd8-e2d6-4f0b-af29-e325229a044a')

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.