English 中文(简体)
唯一数字生成算法
原标题:Unique Number Generation Algorithm

我需要为我的爪哇申请 提供独特的号码 满足以下要求

  1. 9 digit hexadecimal
  2. About 600,000 numbers to be generated everyday
  3. The numbers must remain unique for a minimum period of 7 days; not a problem if they repeat beyond 7 days period.
  4. During peak loads, about 800 unique numbers need to be generated every second for about 15 seconds.

不成功的解决办法

    public static String getUniqueId() {
        String uniqueTime = Long.toHexString(System.nanoTime());
        String uniqueId = uniqueTime.substring(uniqueTime.length() - 9);

        return uniqueId;
    }

使用纳米时间生成了 12 位数的十六进制数。 我截读了 3 个左字符 。 纳米时间帮助正在处理峰值负载 。

我认为这不正确,可能导致重复。

有人能提供快速算法吗?

问题回答

如果只用一条线来生成数字:

long nextId = counter % MAX_VALUE;
counter++;
return convertToHex(nextId);

如果有多个线索 :

long nextId = atomicLongCounter.getAndIncrement() % MAX_VALUE;
return convertToHex(nextId);

注意: 给@ Gumbo s 计算, 它需要 313 年才能达到最高值, 这样您甚至可以降低 modulo 。

http://en.wikipedia.org/wiki/Universally_unique_identer#Defrimine" rel=“no follow” >UUID ?在这样的情况下,它们非常有用。Java的落实工作有

简短回答: 加密。 由于加密是可逆的, 您可以保证如果输入是独一无二的, 而不是输出是独一无二的 。 使用36 位块密钥( 36 位元 = 9 Xx 位数) 并加密数字 0, 1, 2, 3, 4...

您可以在闲暇期间提前预发多少份,然后储存多少份。

大多数常见的区块密码器不是36位(DES是64位),但Hasty Putding Cypher 有一个36位变体,或者你可以使用快速流密码器,如RC4或一个 < a href=>”http://www.ecrypt.eu.org/strem/"rel=“no follow”>eSTREAM cepers。

ETA: 串流密码器将需要对每个数字重新加密, 因此对于您的目的来说可能太慢 。 串流密码器也会影响独特性, 因为仅在使用同一密钥时才保证独一性 。

- 另一种同时产生数字的可能性

您最多可以拥有10个独立的线条/处理/机器生成号码,保证不会发生冲突。

只需使用顺序对数来生成整数

start one of them at 0, use increments of 10
start the next at 1, increments of 10
start the next at 2, increments of 10

即便上面的一位最终承担了全部载荷,它也可以持续7天,而不会溢出9位数,因为您在9位数不足之前就有大约1亿个序列,而您每天只能产生1百万个数字。

这里的线条/处理程序/机器是

btw - 你可以直接在16号基地这样做 - 只要使用16号加薪而不是10号 或者5号加薪...

如果你不需要数字来“看随机”,那么你可以像其他人建议的那样使用一个柜台。

我猜你之所以要找复杂的东西 是因为你想让数字“看随机”。在这种情况下,你可以做以下工作:

  • use an instance of SecureRandom to allocate your numbers
  • keep in memory a map of "currently allocated" numbers mapped to their time of allocation (I think 600K numbers with this data stored in a ConcurrentHashMap will be in the order of a few tens of megabytes of data, so not a big deal by today s standards)
  • each time you need to allocate a new number, just generate 9 random hex digits via your instance of SecureRandom (asking it to fill an array with 5 random bytes then discarding 4 of the bits will give you 9 hex digits worth of random data)
  • check if your new number is already in the map of allocated numbers. If so, just loop round and generate a new number until you get a unique one-- in reality, this will only happen 100 or so times per week for the volume you mention, so will have no performance impact though you do need to account for it;
  • periodically, scan through your map of allocated numbers and purge ones that have been allocated for more than 7 days so that they can be re-used.

对于现实生活应用程序,您也需要考虑持久性:每次分配一个数字时,您需要将其持续到数据库中,然后才能将其归还给客户,这样如果服务器崩溃,国家就可以恢复。 同样,在从记忆地图中移除之前,您的清洗操作会从数据库中移除分配款。

部分是为了娱乐,请允许我从您给出的规格中建议另一种可能性。您还可以找到一种假随机数字生成算法,它从已知种子开始,实际上不会产生每周生成数量所需的重复数据。

例如,根据XORShift 生成器 ,根据XORShift 生成器 ,将产生600,000*7 随机的9位数数字,无重复:

        long seed = 1;
        for (long i = 1; i <= 600000*7; i++) {
            long x = seed++;
            for (int n = 0; n < 3; n++) {
                x ^= (x << 21);
                x ^= (x >>> 35);
                x ^= (x << 4);
            }
          x &= 0xfffffffffL;

          // "x" is now the next unique, random-looking number in the sequence
        }

这种方法的优点是,除了柜台之外,不需要存储来决定迄今为止生成了哪些数字。

当然,如果你突然需要增加分配数字的数量,那么你可能需要另找一个序列。

总之,我想我把它扔进混合体里 以防有用

AtomicLong. incrowementandGet () 应该做这个把戏 。

如果您需要在 JVM 实例之间坚持, 您可能需要在数据库或其他交易仓库中分配一个区域, 存储该区域的最大值, 并确保在 < code> AtomicLong 中接近最大值时请求新的区域( 加上适当的锁定, 以确保您不会超过该范围 ) 。

但如果在一次运行中只需要一个独有的号码, AtomicLong. incrowement and Get 很简单,并且保证是独一无二的,直到它包到 -1, higcch 1 (higch 1) 在你的一生中不会发生, 2) 很容易检查。





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签