为客户端生成唯一的字母数字代码,减少冲突

问题描述 投票:0回答:1

我需要使用一个简单的代码来识别每个预订,该代码可以提供给客户并由他们使用(例如,当联系我们的客户服务或将他们的预订详细信息连接/链接到他们的移动应用程序时)。

因此,我们不使用 13 个字符长的随机序列,而是使用 6 个字符长的数字 + 大写字母字符串。

例如:

3RATW2

我目前的解决方案是:

  1. 采用可能/允许的字符的字符集。
  2. 每个输出字符(6次,因为输出应该是6个字符长):
    1. 使用 Fisher-Yates 算法打乱字符集
    2. 从结果中选择一个随机字符。

使用 Kotlin 代码:

val charset = "ABCDEFGHIJKLMNOPQRSTUVWXTZ0123456789"
return (1..6)
    .map { // for each iteration :
         charset.toCharArray().shuffle() // shuffle (Fisher-Yates)
         .toString().random() // then take a random char
    }
    .joinToString("")

但是由于 6 的数量相对较少,我不确定这是否是一个足够好的解决方案,以避免可能的冲突,因为预订数量将会不断增加。有没有办法改进它(例如多次打乱字符集等)?

或者是始终从我们的数据库(Postgres)获取现有预订代码列表的唯一真正解决方案,然后代码生成器必须确保生成的代码不包含在该列表中(如果包含,请再次运行代码直到找到唯一的代码)?

postgresql algorithm kotlin random probability
1个回答
0
投票

创建新订单时避免冲突的方法是:

  1. 为新订单生成代码
  2. 检查数据库中是否已经有具有相同代码的订单(类似
    SELECT 1 FROM orders WHERE code = "3RATW2"
  3. 重复直到生成尚未使用的代码

我强烈建议在包含这些代码的列上添加唯一索引,这样绝对不可能在数据库中创建冲突。

如果使用 36 个字符的字符集生成 6 个字符代码,则有 36^6 个可能的代码(约 20 亿),您可以通过生成更长的代码和/或包含更多可能的字符来增加此数字。

请注意,当您创建更多订单时,生成新代码时更有可能发生冲突,并且您必须重试生成(可能多次)

已经处理的订单还需要有code吗?如果没有,您可以从旧的/已取消的订单中删除该代码,以便您可以在新订单中重新使用相同的代码。

© www.soinside.com 2019 - 2024. All rights reserved.