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

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

  • 通过电话很容易说(例如,“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 

作为客户,我很满意:

 year-month-day/short_uid 

例如:

 2009-07-27/KT1E 

它每天可以提供约33 ^ 4~1ml的订单。

以下是我在之前的问题中提出的系统的实现:

 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 

它只是一个廉价的哈希函数,但它使普通用户难以确定已处理的订单数量,或另一个订单的数量。 在您完成2 30个订单之前,它不会用完空间,您很快就不会打到它。

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

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

在我的旧地方,它是以下:

客户ID(从1001开始),它们所订单的顺序,然后是Orders表中的唯一ID。 这给了我们一个很好的长数至少6位数,由于两个主键,它是独一无二的。

我想如果你把破折号或空格放进去,甚至可以让我们对客户的购买习惯有所了解。 它不是令人难以置信的安全,我想订单ID是可以猜到的,但我不确定是否存在安全风险。

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

我宁愿提交数字347并在一个较小的个性化网站上获得优质的客户服务:G-84e38wRD-45OM在大型网站上被忽略一周。

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

像这样的东西:

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

Douglas Crockford的Base32编码非常适合这种情况。

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

将ID本身作为自动递增的整数存储在数据库中,从大约100000的大小开始,然后将编码值公开给客户/接口。

5个字符将通过您的第一个~3200万个订单看到您,同时表现非常好并满足大多数这些要求。 但它不允许排除类似的声音字符。

好的,这个怎么样?

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

数字总是增加(直到你超过整数类型的容量,但到那时你可能不在乎,因为你会非常成功,并将在一些遥远的岛屿天堂啜饮玛格丽塔酒)。 它实现起来非常简单,并且它可以将事情混合起来,以避免猜测你有多少订单。

顺便说一下,从1开始? 这有什么问题?

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

只有一个Rube Goldberg风格的想法:

您可以生成一个包含随机时间段的随机数字表的表:

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

等等…这给你一个无限数量的Interleavers,并且不会让任何人知道你的订单率,因为你的时间段可能是几天,而你的交织器正在做很多低技术的“糖化” “ 为了你。

您可以生成此表一次,并确保所有Interleavers都是唯一的。 您可以通过简单地在集合中添加更多字符来确保不会耗尽Interleavers,或者通过定义更长的Interleavers来开始。

因此,您通过获取序列号生成订单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比交织器长一位数)

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

你可以像邮政编码那样做:2b2 b2b

这样它有一些校验和(不是真的,但至少你知道如果有2个连续的数字或字母则错了)。 通过电话轻松读出,并不能说明系统中有多少订单。

如何以毫秒为单位获取当前时间并将其用作订单ID?