非重复随机字母数字代码

时间:2012-12-30 21:44:01

标签: c# random

我的一个客户希望为他的项目使用唯一的代码(长篇故事......),他问我解决方案。代码将包含4个部分,其中第一个是发送项目的邮政编码,第二个是供应商注册号,第三个是发送项目的年份,最后一个是三个分裂字母数字独特的字符。

正如您所看到的,前三个部分是静态字段,在同一年中对于同一发件人永远不会更改。所以我们可以说最后一部分是该年的标识符部分。这部分是3分区的alpahnumeric,意思是从000开始到ZZZ结束。

问题是我的客户出于某些合理的原因希望这部分不是顺序的。例如,这不是他想要的:

  

06450-05-2012-000

     

06450-05-2012-001

     

06450-05-2012-002

     

...

     

06450-05-2012-ZZY

     

06450-05-2012-ZZZ

最后一部分应随机产生:

  

06450-05-2012-A17

     

06450-05-2012-0BF

     

06450-05-2012-002

     

...

     

06450-05-2012-T7W

     

06450-05-2012-22C

但它也应该是非重复性的。因此,一旦生成了可能的id,就应该从选择池中丢弃该可能性。

我正在寻找一种有效的方法。

  1. 如果我只记录选定的可能性并检查新创建的可能性,那么总是存在最坏的情况,即它会继续生成已经选择的可能性,特别是在结束时。
  2. 如果我一次创建所有可能性并将它们记录在表格或文件中,则每个项目创建后可能需要一段时间,因为它将查找未选择的记录。顺便说一句26个字母+10个数字意味着46.656种可能的组合,并且有可能增加第4个分区,这意味着1.679.616种可能的组合。
  3. 你能提出更有效的建议吗?我将使用C#进行编码,将MS SQL用于数据库..

3 个答案:

答案 0 :(得分:4)

如果您希望为每个zip-supplier-year元组创建远小于36^3个条目,您应该只为最后一个字段选择一个随机值,然后检查它是否存在,如果它存在则重复确实

即使您创建了最大可能条目数的一半,新条目仍然只有一个失败的预期值。假设您的数据库是根据整体标识符编制索引的,那么这个代价就不算太高了。

也就是说,如果您希望使用除了几个可能的标识符之外的所有标识符,那么您应该提前创建所有可能的记录。这可能听起来像是一个高成本,但内存中存储未使用记录的每个空间最终都会存储真实记录。

我希望第一种情况更有可能,但如果没有,或者如果还有其他两种组合,请添加评论以及更多信息,我会修改我的答案。

答案 1 :(得分:4)

我认为选项取决于将要使用的代码量:

  1. 如果您希望在一年内使用其中大部分,那么最好预先生成。如果做得好,查找应该非常快。无论如何,你的数据库每年将有1.679.616项,所以你必须做正确的事情。

    另一方面,你期望使用其中大部分是否好?如果突然有多于预期的项目,它可能会让你没有代码。

  2. 如果您希望只使用少量,那么随机+存在检查可能是一种方法,但不清楚它应该是多少才能做到最好(我很确定它是可能的虽然计算了这一点。

答案 2 :(得分:4)

如果它不一定是随机的,你可以简单地选择一个固定但“不可预测”的加数,这对于26 + 10 == 36 == 2²·3²是相对优先的。这意味着,只需选择一个既不能被2也可以3整除的固定加数。

每次需要新的序列号时,请继续将此固定号码添加到以前的序列号中。当然,这要以模46656(或1679616}为模。

数学保证你不会两次得到相同的数字(在没有剩下“免费”数字之前)。

作为加数,您可以使用const int addend = 26075,因为它是56