如何在Java中创建用户友好的唯一ID,UUID或其他唯一标识符

2022-09-03 06:54:46

我通常使用 UUID 类来生成唯一的 ID。如果这些ID仅由技术系统使用,则此方法可以正常工作,它们不关心它们的长度:

System.out.println(UUID.randomUUID().toString());

> 67849f28-c0af-46c7-8421-94f0642e5d4d

有没有一种很好的方法可以创建用户友好的唯一ID(如来自tinyurl的ID),这些ID比UUID短一些?用例:您希望通过邮件向您的客户发送ID,然后客户访问您的网站并将该号码输入到表单中,例如凭证ID。

我假设UUID在UUID的128位范围的整个范围内均匀生成。那么,例如,只使用较低的64位会是明智的吗?

System.out.println(UUID.randomUUID().getLeastSignificantBits());

欢迎任何反馈。


答案 1

我假设UUID在UUID的128位范围的整个范围内均匀生成。

首先,您的假设可能不正确,具体取决于 UUID 类型(1、2、3 或 4)。来自 Java UUID 文档

这些全局标识符存在不同的变体。此类的方法用于操作 Leach-Salz 变体,尽管构造函数允许创建 UUID 的任何变体(如下所述)。

变体 2 (Leach-Salz) UUID 的布局如下:最重要的长整型由以下无符号字段组成:

0xFFFFFFFF00000000 time_low 
0x00000000FFFF0000 time_mid 
0x000000000000F000 version 
0x0000000000000FFF time_hi  

最低有效长整型由以下无符号字段组成:

0xC000000000000000 variant 
0x3FFF000000000000 clock_seq 
0x0000FFFFFFFFFFFF node  

变体字段包含一个值,该值标识 UUID 的布局。上述位布局仅对变体值为 2 的 UUID 有效,这表示 Leach-Salz 变体。

版本字段包含描述此 UUID 类型的值。有四种不同的基本类型的 UUID:基于时间的 UUID、DCE 安全性、基于名称的 UUID 和随机生成的 UUID。这些类型的版本值分别为 1、2、3 和 4。

执行您正在执行的操作的最佳方法是生成一个随机字符串,其中包含如下所示的代码():

public class RandomString {

          public static String randomstring(int lo, int hi){
                  int n = rand(lo, hi);
                  byte b[] = new byte[n];
                  for (int i = 0; i < n; i++)
                          b[i] = (byte)rand('a', 'z');
                  return new String(b, 0);
          }

          private static int rand(int lo, int hi){
                      java.util.Random rn = new java.util.Random();
                  int n = hi - lo + 1;
                  int i = rn.nextInt(n);
                  if (i < 0)
                          i = -i;
                  return lo + i;
          }

          public static String randomstring(){
                  return randomstring(5, 25);
          }

        /**
         * @param args
         */
        public static void main(String[] args) {
                System.out.println(randomstring());

        }

}

如果您非常担心碰撞或其他事情,我建议您对UUID进行编码,这应该可以减小其大小。base64

故事的寓意是:不要依赖UUID的各个部分,因为它们是整体设计的。如果您确实需要依赖 UUID 的各个部分,请确保您熟悉特定的 UUID 类型和实现。


答案 2

以下是生成用户友好 ID 的另一种方法:
http://thedailywtf.com/Articles/The-Automated-Curse-Generator.aspx

(但你应该去坏词过滤器)