【问题标题】:Generating a non-repeating list of alpha-numeric codes生成不重复的字母数字代码列表
【发布时间】:2019-04-25 18:25:49
【问题描述】:

我正在尝试生成不重复的字母数字代码列表。它们将批量生成,因此无法明确查看之前生成的内容 - 即需要以某种方式保证唯一性,而无需求助于当前批次之外的先前代码。

代码的长度应为 8 个字符,并限制某些字符不能出现在代码中(例如 l 和 L),因为用户将在以后重新输入这些字符。

我可能会在 Java 中实现它,但我会很感激任何人能想到的任何算法或技巧来解决这个问题......

问候,

【问题讨论】:

  • 只有有限数量的 8 字符组合 -- 很明显,它们必须在一段时间后重复。
  • 你能给我们完整的允许字母列表吗?我假设 'o' 和 'O' 也是不允许的。
  • @casablance 使用 10 个十进制数字加上 24 个字母给出 1.8e12 长度为 8 的唯一组合。确实会一段时间 :-)

标签: java algorithm


【解决方案1】:

只需使用 System.currentTimeMillis 并通过将每个数字映射到一个字母来对其进行字母数字编码。跟踪最后一个发布(以防止在同一毫秒内发生多代)并进行相应处理。

【讨论】:

    【解决方案2】:

    您可以只编码一个原子计数器,例如

    AtomicInteger counter = new AtomicInteger();
    
    public String generateId() {
       return Integer.toHexString(counter.getAndIncrement());
    }
    

    这将为您提供 40 亿个唯一 ID。

    如果您需要超过 40 亿个,您可以使用 AtomicLong 并根据您要允许的字符使用您自己的编码。

    【讨论】:

      【解决方案3】:

      上述问题有一个明显的解决方案,即从零开始顺序生成代码。将每个代码视为 base-34 中的数字(数字为 0-9A-ZIL 除外)。如果这不是您想要的,您可能想澄清这个问题(例如,您想要随机性吗?)

      编辑:这当然需要你记住最后生成的代码,并跨批次携带这条信息。

      【讨论】:

        【解决方案4】:

        8 个嵌套循环可以轻松解决您的问题。 此外,如果您愿意,您可以使用 Random 生成下一个令牌并将所有令牌存储在 Set 中。每次获得新令牌时,请检查它是否已设置。

        【讨论】:

        • 我认为Random 不认为需要以某种方式保证唯一性,而不求助于当前批次之外的先前代码
        • 给定一个编码字符有 34 个符号,随机生成编码时重复编码的概率约为 10^-13,- 非常小。
        【解决方案5】:

        太糟糕了,你被限制为 8 个字符。否则,您可以使用 MD5 类来生成唯一代码。

        无论如何,如果你想确保你的代码是唯一的,你可以在你的一些代码字符中编码生成日期,以确保它不会与以前的代码冲突。

        例如,您的代码将采用YMDXXXXX 形式,其中:

        • Y 是自 2010 年以来的年份(从 0 开始,在 2020 年用完数字时开始使用字母)
        • M 是月份(相同标准)
        • D 是天(不会大于 31,所以字符 0-9A-Z 应该足够了)
        • X 是您当前批次生成的代码。

        【讨论】:

          【解决方案6】:

          你能像这样向前迭代吗?

          000000a1 000000a2 000000a3 ... 000000ay 000000az 000000b0

          那么只要记住最后一个数字,所有未来的数字都会大于最后一个

          你可能会发现这很有用

          long l = 20492;
          String s = "wogjz";
          s = Long.toString(l, 26+10-2).replace('I','Y').replace('L','Z') // convert long number to string (with letters)
          l = Long.parseLong(s.replace('Y','I').replace('Z','L'), 26+10-2) + 1) // Convert string to number
          

          数字 26+10-2 是字母的数量加上数字的数量减去禁用字母的数量(I 和 L)。 I/Y 和 Z/L 转换是与 Java 库配合使用字母表的最后一个字母。

          您需要确保用户不会自己输入 I 或 L,否则我的代码将无法正常工作。

          您需要在字符串中添加前导零,直到达到 8 个字符

          我的程序也不知道大小写的区别。如果您需要,那么应用程序必须更复杂,因为我们需要一个数组而不是一个长数字。

          【讨论】:

            【解决方案7】:

            检查这个逻辑。您可以在循环中排除任何字母或数字。对于您的“L”问题,您可以排除如下

                    if(brokenCode[i] == 'K') brokenCode[i] = 'L'; 
                    brokenCode[i] = (char)(((int)brokenCode[i]) + 1);
            

            示例代码

            class Rextester
            {  
                public static void main(String args[])
                {
                    String currCode = "00000000";
                    for(int i=0; i<2000; i++)
                    {
                        System.out.println(currCode);
                        currCode = getNextCode(currCode);
                    }
                }
            
                private static String getNextCode(String currCode)
                {
                    char [] brokenCode;
                    brokenCode = currCode.toCharArray();
                    for(int i=brokenCode.length-1; i>= 0; i--)
                    {
                        if(brokenCode[i] == '9')
                        {
                            brokenCode[i] = 'A';
                            break;
                        }
                        if(brokenCode[i] == 'Z'){
                            brokenCode[i] = '0';
                            continue;
                        }
                        brokenCode[i] = (char)(((int)brokenCode[i]) + 1);
                        break;
                    }
                    currCode = new String(brokenCode);
                    return currCode;
                }
            
            }
            

            【讨论】:

              猜你喜欢
              • 2012-11-14
              • 1970-01-01
              • 1970-01-01
              • 2019-04-16
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多