为在线商店生成订单号的最佳方法?

发布于 2024-07-27 18:35:32 字数 616 浏览 6 评论 0原文

我的在线商店中的每个订单都有一个面向用户的订单号。 我想知道生成它们的最佳方法。 标准包括:

  • 简短
  • 易于通过电话说出(例如,“m”和“n”不明确)
  • 唯一
  • 校验和(过度?有用吗?)
  • 编辑: 不透露订单总数(客户可能会觉得下第三个订单令人不安)

现在我正在使用以下方法(无校验和):

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

Every order in my online store has a user-facing order number. I'm wondering the best way to generate them. Criteria include:

  • Short
  • Easy to say over the phone (e.g., "m" and "n" are ambiguous)
  • Unique
  • Checksum (overkill? Useful?)
  • Edit: Doesn't reveal how many total orders there have been (a customer might find it unnerving to make your 3rd order)

Right now I'm using the following method (no checksum):

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

不奢求什么 2024-08-03 18:35:32

作为客户我会很高兴:

year-month-day/short_uid

例如:

2009-07-27/KT1E

它每天可以容纳大约 33^4 ~ 100 万个订单。

As a customer I would be happy with:

year-month-day/short_uid

for example:

2009-07-27/KT1E

It gives room for about 33^4 ~ 1mln orders a day.

梦中的蝴蝶 2024-08-03 18:35:32

在我原来的地方,内容如下:

客户 ID(从 1001 开始)、他们下的订单的序列,然后是订单表中的唯一 ID。 这给了我们一个至少 6 位数字的长数字,并且由于有两个主键,它是唯一的。

我想如果你在其中添加破折号或空格,你甚至可以让我们深入了解客户的购买习惯。 这并不是令人难以置信的安全,我猜订单 ID 是可以猜测的,但我不确定这是否存在安全风险。

At my old place it was the following:

The customer ID (which started at 1001), the sequence of the order they made then the unique ID from the Orders table. That gave us a nice long number of at least 6 digits and it was unique because of the two primary keys.

I suppose if you put dashes or spaces in you could even get us a little insight into the customer's purchasing habits. It isn't mind boggling secure and I guess a order ID would be guessable but I am not sure if there is security risk in that or not.

卸妝后依然美 2024-08-03 18:35:32

这是系统的实现 在之前的问题中提出

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 个订单(您不会很快完成这些订单)之前,它的空间不会用完。

以下是 1 到 10 的 convert(x) 结果:

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

Here is an implementation for a system I proposed in an earlier question:

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

It's just a cheap hash function, but it makes it difficult for an average user to determine how many orders have been processed, or a number for another order. It won't run out of space until you've done 230 orders, which you won't hit any time soon.

Here are the results of convert(x) for 1 through 10:

1:  302841629
2:  571277085
3:   34406173
4:  973930269
5:  437059357
6:  705494813
7:  168623901
8:  906821405
9:  369950493
10: 638385949
葬シ愛 2024-08-03 18:35:32

好吧,这个怎么样?

按顺序,从某个数字 (2468) 开始,并向其中添加一些其他数字,例如下订单的月份中的哪一天。

这个数字总是在增加(直到你超过了整数类型的容量,但到那时你可能不在乎,因为你将取得令人难以置信的成功,并且将在一些遥远的天堂岛屿上喝着玛格丽塔酒)。 它实现起来很简单,而且它把事情混合在一起,足以消除对你有多少订单的猜测。

Ok, how about this one?

Sequentially, starting at some number (2468) and add some other number to it, say the day of the month that the order was placed.

The number always increases (until you exceed the capacity of the integer type, but by then you probably don't care, as you will be incredibly successful and will be sipping margaritas in some far-off island paradise). It's simple enough to implement, and it mixes things up enough to throw off any guessing as to how many orders you have.

雪花飘飘的天空 2024-08-03 18:35:32

我宁愿提交号码 347 并在一个较小的风度翩翩的网站上获得优质的客户服务,也不愿在大型网站上提交 G-84e38wRD-45OM 并被忽视一周。

您不希望将此作为系统 ID 或链接的一部分,但作为用户友好的数字,它可以工作。

I'd rather submit the number 347 and get great customer service at a smaller personable website than: G-84e38wRD-45OM at the mega-site and be ignored for a week.

You would not want this as a system id or part of a link, but as a user-friendly number it works.

屌丝范 2024-08-03 18:35:32

Douglas Crockford 的 Base32 编码对此非常有效。

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

存储 ID 本身在数据库中作为自动递增整数,从适当大的值(例如 100000)开始,然后将编码值简单地公开给客户/界面。

5 个角色将帮助您完成前约 3200 万个订单,同时表现出色并满足大部分要求。 但它不允许排除发音相似的字符。

Douglas Crockford's Base32 Encoding works superbly well for this.

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

Store the ID itself in your database as an auto-incrementing integer, starting at something suitably large like 100000, and simply expose the encoded value to the customer/interface.

5 characters will see you through your first ~32 million orders, whilst performing very well and satisfying most of these requirements. It doesn't allow for the exclusion of similar sounding characters though.

山有枢 2024-08-03 18:35:32

您可以尝试创建一个不会泄露系统中订单数量的加密版本,而不是生成和存储数字。 这里是一篇关于这一点的文章

Rather than generating and storing a number, you might try creating an encrypted version that would not reveal the number of orders in the system. Here's an article on exactly that.

糖粟与秋泊 2024-08-03 18:35:32

像这样的事情:

  1. 获取连续的订单号。 或者,也许 UNIX 时间戳加上两个或三个随机数字(当同时下了两个订单时)也可以。
  2. 将其与一些半秘密值进行按位异或以使数字显示为“伪随机”。 这是原始的,不会阻止那些真正想调查你有多少订单的人,但为了真正“随机性”,你需要保留一个(大)排列表。 或者您需要有随机数,这样您就不会受到生日悖论的困扰。
  3. 使用 Verhoeff 算法 添加校验位(我不确定它对于 base33 是否具有如此好的属性) ,但应该不会太差)。
  4. 将数字转换为 - 例如 - 基数 33(“0-9A-Z”,“O”、“Q”和“L”除外,它们可能会与“0”和“1”混淆)或类似的值。 易于发音意味着排除更多字母。
  5. 将结果分组为某种视觉上可读的模式,例如 XXX-XXX-XX,这样用户就不必用手指或鼠标指针来跟踪位置。

Something like this:

  1. Get sequential order number. Or, maybe, an UNIX timestamp plus two or three random digits (when two orders are placed at the same moment) is fine too.
  2. Bitwise-XOR it with some semi-secret value to make number appear "pseudo-random". This is primitive and won't stop those who really want to investigate how many orders you have, but for true "randomness" you need to keep a (large) permutation table. Or you'll need to have large random numbers, so you won't be hit by the birthday paradox.
  3. Add checkdigit using Verhoeff algorithm (I'm not sure it will have such a good properties for base33, but it shouldn't be bad).
  4. Convert the number to - for example - base 33 ("0-9A-Z", except for "O", "Q" and "L" which can be mistaken with "0" and "1") or something like that. Ease of pronouncation means excluding more letters.
  5. Group the result in some visually readable pattern, like XXX-XXX-XX, so users won't have to track the position with their fingers or mouse pointers.
隱形的亼 2024-08-03 18:35:32

依次从 1 开始? 这有什么问题吗?

(注意:这个答案是在OP编辑问题之前给出的。)

Sequentially, starting at 1? What's wrong with that?

(Note: This answer was given before the OP edited the question.)

扮仙女 2024-08-03 18:35:32

只是一个鲁布·戈德堡式的想法:

你可以生成一个包含一组随机数字的表,这些数字与随机时间段相关联:

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

依此类推......这为你提供了无限数量的交织器,并且不允许任何人了解您的订单率,因为您的时间段可能是几天,而您的交错器正在为您做大量低技术的“混搭”。

您可以生成该表一次,并且只需确保所有交织器都是唯一的。
您可以通过简单地将更多字符添加到集合中来确保不会用完交织器,或者首先定义更长的交织器。

因此,您可以通过获取序列号来生成订单 ID,并使用当前的 Interleaver 值,将其数字(因此,名称)交错在每个序列号的数字之间。 保证独特-保证令人困惑。

示例

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 开始的所有其他数字。 (除非您的订单 ID 仅比交织器长一位数)

我并没有说这是最好的方法 - 只是周五的想法。

Just one Rube Goldberg-style idea:

You could generate a table with a random set of numbers that is tied to a random period of time:

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

and so on... this gives you an unlimited number of Interleavers, and doesn't let anyone know your rate of orders because your time periods could be on the order of days and your interleaver is doing a lot of low-tech "mashing" for you.

You can generate this table once, and simply ensure that all Interleavers are unique.
You can ensure you don't run out of Interleavers by simply adding more characters into the set, or start by defining longer Interleavers.

So you generate an order ID by getting a sequential number, and using today's Interleaver value, interleave its digits (hence, the name) in between each sequential number's digits. Guaranteed unique - guaranteed confusing.

Example:

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

This will be completely confusing but completely deterministic. You can just remove every other digit starting at the 1's place. (except when your order id is only one digit longer than your interleaver)

I didn't say this was the best way - just a Friday idea.

野の 2024-08-03 18:35:32

您可以像邮政编码一样这样做:
2b2 b2b

这样它就有某种校验和(不是真的,但至少你知道如果有 2 个连续的数字或字母是错误的)。 通过电话很容易读出,并且它没有表明系统中有多少订单。

You could do it like a postal code:
2b2 b2b

That way it has some kind of checksum (not really, but at least you know it's wrong if there are 2 consecutive numbers or letters). It's easy to read out over the phone, and it doesn't give an indication of how many orders are in the system.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文