Лучший способ генерировать номера заказов для интернет-магазина?

каждый заказ в моем интернет-магазине есть пользователь номер заказа. Мне интересно, как их лучше всего генерировать. Критерии включают:

  • короче
  • легко сказать по телефону (например, "m" и "n" неоднозначны)
  • уникальный
  • контрольная сумма (перебор? Полезно?)
  • Edit: не показывает, сколько всего заказов было (клиент может найти его нервирующим, чтобы сделать ваш 3rd порядок)

прямо сейчас я использую следующий метод (без контрольной суммы):

def generate_number                
    possible_values = 'abfhijlqrstuxy'.upcase.split('') | '123456789'.split('')

    record = true
    while record
        random = Array.new(5){possible_values[rand(possible_values.size)]}.join
        record = Order.find(:first, :conditions => ["number = ?", random])
    end          
    self.number = random
end

13 ответов


Как клиент, я был бы счастлив с:

year-month-day/short_uid

например:

2009-07-27/KT1E

это дает место для порядка 33^4 ~ 1mln заказов в день.


вот реализация для системы I предложено в предыдущем вопросе:

MAGIC = [];
29.downto(0) {|i| MAGIC << 839712541[i]}

def convert(num)
  order = 0
  0.upto(MAGIC.length - 1)  {|i| order = order << 1 | (num[i] ^ MAGIC[i]) }
  order
end

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

вот результаты convert(x) С 1 по 10:

1:  302841629
2:  571277085
3:   34406173
4:  973930269
5:  437059357
6:  705494813
7:  168623901
8:  906821405
9:  369950493
10: 638385949

на моем старом месте было следующее:

идентификатор клиента (который начинался со 1001), последовательность заказа, который они сделали, затем уникальный идентификатор из таблицы заказов. Это дало нам хорошее длинное число по крайней мере 6 цифр, и оно было уникальным из-за двух первичных ключей.

Я полагаю, если вы поместите тире или пробелы, вы могли бы даже получить нам небольшое представление о покупательских привычках клиента. Это не уму непостижимо безопасно, и я думаю, что идентификатор заказа будет угадываемым но я не уверен, есть ли в этом риск для безопасности или нет.


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


Я бы предпочел отправить номер 347 и получить отличное обслуживание клиентов на меньшем представительном веб-сайте, чем: G-84e38wRD-45OM на мега-сайте и быть проигнорированным в течение недели.

вы не хотели бы, чтобы это было системным идентификатором или частью ссылки, но как удобный номер он работает.


что-то вроде этого:

  1. получи порядковый номер. Или, может быть, временная метка UNIX плюс две или три случайные цифры (когда два ордера размещаются в один и тот же момент) тоже хороша.
  2. побитовое-XOR с некоторым полусекретным значением, чтобы число выглядело "псевдослучайным". Это примитивно и не остановит тех, кто действительно хочет исследовать, сколько у вас заказов, но для правда "случайность" вам нужно сохранить (большую) таблицу перестановок. Или вам нужно будет иметь большой случайные числа, так что вы не будете поражены парадоксом дня рождения.
  3. добавить checkdigit с помощью алгоритм Верхоеф (Я не уверен, что у него будут такие хорошие свойства для base33, но это не должно быть плохо).
  4. преобразовать число в - например-base 33 ("0-9A-Z", за исключением" O"," Q "и" L", которые могут быть ошибочно приняты за" 0 "и" 1") или что-то в этом роде. Легкость pronouncation означает, кроме более буквы.
  5. группируйте результат в некотором визуально читаемом шаблоне, например XXX-XXX-XX, поэтому пользователям не придется отслеживать положение пальцами или указателями мыши.

кодировка Base32 Дугласа Крокфорда отлично работает для этого.

http://www.crockford.com/wrmg/base32.html

сохраните сам идентификатор в своей базе данных как автоматически увеличивающееся целое число, начиная с чего-то подходящего большого, как 100000, и просто выставьте закодированное значение клиенту/интерфейсу.

5 символов увидят вас через ваши первые ~32 миллиона заказов, при этом выполняя очень хорошо и удовлетворяя большинство из них требования. Это не позволяет исключить аналогичные звучащие символы, хотя.


хорошо, как насчет этого?

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

число всегда увеличивается (пока вы не превысите емкость целочисленного типа, но к тому времени вам, вероятно, все равно, так как вы будете невероятно успешны и будете потягивать Маргариту в каком-то далеком райском острове). Это достаточно просто реализовать, и он смешивает вещи достаточно, чтобы сбросить любые угадайте, сколько у вас заказов.


последовательно, начиная с 1? Что в этом плохого?

(Примечание: этот ответ был дан до того, как OP отредактировал вопрос.)


только одна идея в стиле Руби Голдберга:

вы можете создать таблицу со случайным набором чисел, привязанную к случайному периоду времени:

Time Period          Interleaver
next 2 weeks:        442
following 8 days:    142
following 3 weeks:   580

и так далее... это дает вам неограниченное количество Interleavers и не позволяет никому знать вашу скорость заказов, потому что ваши периоды времени могут быть в порядке дней, и ваш interleaver делает много низкотехнологичных "затираний" для вас.

вы можете сгенерировать эту таблицу один раз и просто убедиться, что все Interleavers уникальны. Вы можете убедиться, что у вас не закончились Интерливеры, просто добавив больше символов в набор или определив более длинные Интерливеры.

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

пример:

Today I have a sequential number 1, so I will generate the order ID:  4412
The next order will be 4422
The next order will be 4432
The 10th order will be 41402

In two weeks my interleaver will change to 142, 
The 200th order will be 210402
The 201th order will be 210412

Eight days later, my interleaver changes to 580:
The 292th order will be 259820

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

Я не сказал, что это лучший способ - просто пятничная идея.


вы можете сделать это как почтовый индекс: 2Б2 В2В

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



Как насчет получения текущего времени в миллисекундах и используя в качестве идентификатора заказа?