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

bas*_*ero 12 java random uuid

我通常使用UUID类生成唯一ID.如果这些ID仅由技术系统使用,它们可以正常工作,它们不关心它们有多长:

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

> 67849f28-c0af-46c7-8421-94f0642e5d4d
Run Code Online (Sandbox Code Playgroud)

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

我假设UUID在UUID的128位范围的整个范围内均等地生成.那么仅仅使用较低的64位是圣人吗?

System.out.println(UUID.randomUUID().getLeastSignificantBits());
Run Code Online (Sandbox Code Playgroud)

欢迎任何反馈.

Dav*_*nco 9

我假设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  
Run Code Online (Sandbox Code Playgroud)

最不重要的长整数由以下无符号字段组成:

0xC000000000000000 variant 
0x3FFF000000000000 clock_seq 
0x0000FFFFFFFFFFFF node  
Run Code Online (Sandbox Code Playgroud)

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

version字段包含一个描述此UUID类型的值.UUID有四种不同的基本类型:基于时间,DCE安全性,基于名称和随机生成的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());

        }

}
Run Code Online (Sandbox Code Playgroud)

如果你非常担心碰撞或其他什么,我建议你base64编码你的UUID,它应该减少它的大小.

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

  • 基础64编码版本的'67849f28-c0af-46c7-8421-94f0642e5d4d`是'Njc4NDlmMjgtYzBhZi00NmM3LTg0MjEtOTRmMDY0MmU1ZDRk`.所以这种后备方法实际上并没有削减尺寸. (3认同)
  • 取128位数字形式的UUID(不是字符串),然后base-64版本确实更短:22个字符. (3认同)
  • 附注:对于加密应用程序,您可能不希望使用"随机".还有"SecureRandom"应该更难预测(可能是也可能不是问题,但会话密钥之类的东西是你不想要一个天真的LCG的应用程序).OP对凭证ID的描述也可能是您不希望随机的人声称其他人的情况. (2认同)