如果hashString是纳米时间,Hashing.crc32会生成一个唯一的字符串吗?

Gio*_*oft 2 java algorithm uniqueidentifier unique-key url-shortener

我正在开发一个url shortener,我必须在java中生成一个像这个" 3d0d1fb8 " 的唯一字符串,有一个这样的短网址:shrt.it/3d0d1fb8

我正在使用此代码:

String nanotime = String.valueOf(System.nanoTime());    
String uniqueId = Hashing.crc32().hashString(nanotime, StandardCharsets.UTF_8).toString();
Run Code Online (Sandbox Code Playgroud)

这个" uniqueId "是一个非常独特的字符串吗?

Pet*_*rey 7

不,在大约60K值之后,任何32位散列都将获得重复.任何两个字符串都可以具有相同的散列.

如果你想看看随机32位值重复的速度有多快,你可以运行它,这会在几秒钟内产生数千个结果.

public static void main(String[] args) {
    Random rand = new Random();
    int range = 1 << 30;
    BitSet bs = new BitSet(range);
    while (true) {
        int value = rand.nextInt();
        if (value >= 0 && value < range)
            if (bs.get(value))
                System.out.println("Duplicate " + value);
            else
                bs.set(value);
    }
}
Run Code Online (Sandbox Code Playgroud)

获取唯一ID的一种更简单的方法是使用System.currentTimeMillis()转换为base 36 的时间戳,但您只能确保它对于单个JVM是唯一的.

例如

import java.util.concurrent.atomic.AtomicLong;

// unique for a JVM, and ok on restart provided less than 1000 ids/sec
public enum UniqueTimestamp {
    INSTANCE;
    final AtomicLong time = new AtomicLong();

    public long uniqueTime() {
        long now = System.currentTimeMillis();
        long value = time.get();
        long next = Math.max(now, value) + 1;
        if (time.compareAndSet(value, next))
            return next;
        return time.incrementAndGet();
    }

    public String uniqueId() {
        return Long.toString(uniqueTime(), Character.MAX_RADIX /*36*/);
    }
}
Run Code Online (Sandbox Code Playgroud)

哪里

    for (int i = 0; i < 5; i++)
        System.out.println(UniqueTimestamp.INSTANCE.uniqueId());
Run Code Online (Sandbox Code Playgroud)

版画

jae4gmp2
jae4gmp3
jae4gmp4
jae4gmp5
jae4gmp6
Run Code Online (Sandbox Code Playgroud)

如果你有多个JVM,你会怎么做?

您可以在分配给JVM的每个id的开头添加一个唯一的字符.例如一个添加a,另一个添加b等.