我的一位客户想要为其商品使用唯一的代码(长话说吧),他要求我提供解决方案。该代码将分为4部分,其中第一部分是寄出商品的邮政编码,第二部分是供应商注册号,第三部分是寄出商品的年份,最后一部分是三部分部门字母数字唯一字符。

如您所见,前三部分是静态字段,对于同一年的同一发送者而言,它永远不会改变。因此,可以说最后一部分是该年的标识符部分。这部分是3分区字母数字,表示从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,就应该从选择池中丢弃该可能性。

我正在寻找一种有效的方法来做到这一点。


如果我只记录选定的可能性并对照它们检查一个新创建的可能性,则总是存在最坏的情况,那就是不断产生已经选定的可能性,尤其是在接近尾声时。
如果我立即创建所有可能性并将其记录在表或文件中,则每次创建项后可能要花费一些时间,因为它将查找未选择的记录。顺便说一下,26个字母+ 10个数字表示46.656个可能的组合,并且有可能会增加第4个格,这意味着1.679.616个可能的组合。


您可以提出更有效的建议吗?我将使用C#进行编码,并使用MS SQL进行数据库编辑。

最佳答案

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

然后,每次需要新的序列号时,都将此固定号添加到以前的序列号中。当然,这是对46656(或1679616)取模。

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

作为附加,您可以使用const int addend = 26075,因为它是56的模。

08-24 18:08