我的一位客户想要为其商品使用唯一的代码(长话说吧),他要求我提供解决方案。该代码将分为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²
而言是素数。这意味着,只需选择一个固定的加数,该固定的加数不能被2
或3
整除。
然后,每次需要新的序列号时,都将此固定号添加到以前的序列号中。当然,这是对46656
(或1679616
)取模。
数学保证您不会两次得到相同的数字(在此之前不再剩下“免费”数字)。
作为附加,您可以使用const int addend = 26075
,因为它是5
模6
的模。