如何在Java中创建用户友好的唯一ID、UUID或其他唯一标识符
我通常使用UUID类来生成唯一的ID。如果这些ID仅由技术系统使用,则可以正常工作,它们不关心它们的长度:如何在Java中创建用户友好的唯一ID、UUID或其他唯一标识符,java,random,uuid,Java,Random,Uuid,我通常使用UUID类来生成唯一的ID。如果这些ID仅由技术系统使用,则可以正常工作,它们不关心它们的长度: System.out.println(UUID.randomUUID().toString()); > 67849f28-c0af-46c7-8421-94f0642e5d4d 有没有一种很好的方法来创建比UUID短一点的用户友好的唯一ID(比如tinyurl中的ID)?用例:您希望通过邮件将ID发送给您的客户,这些客户反过来访问您的站点,并在表单中输入该号码,如凭证ID 我假设
System.out.println(UUID.randomUUID().toString());
> 67849f28-c0af-46c7-8421-94f0642e5d4d
有没有一种很好的方法来创建比UUID短一点的用户友好的唯一ID(比如tinyurl中的ID)?用例:您希望通过邮件将ID发送给您的客户,这些客户反过来访问您的站点,并在表单中输入该号码,如凭证ID
我假设UUID在UUID的128位范围内的整个范围内都是平等生成的。那么,仅使用较低的64位是否明智呢
System.out.println(UUID.randomUUID().getLeastSignificantBits());
欢迎任何反馈。仅适用于您:):
private final static char[]idchars=“abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyz012456789”。tocharray();
私有静态字符串createId(int len){
char[]id=新字符[len];
Random r=新的Random(System.currentTimeMillis());
对于(int i=0;i
我假设uuid是生成的
在整个过程中都是一样的
UUID的128位范围
首先,根据UUID类型(1、2、3或4),您的假设可能不正确。发件人:
存在着不同的语言变体
这些是全局标识符。方法
这个类的
Leach Salz变体,尽管
构造函数允许创建任何
UUID的变体(如下所述)
变体2(Leach Salz)的布局
UUID如下所示:最
重要的长代码包括
以下未签名字段:
最不重要的长代码包括
以下未签名字段:
变量字段包含一个值
它标识了
乌伊德。上面描述的位布局
仅对具有
变量值2,表示
Leach-Salz变体
version字段包含一个
描述此UUID的类型。那里
有四种不同的基本类型
UUID:基于时间的DCE安全性,
基于名称,随机生成
UUIDs。这些类型有一个版本
值分别为1、2、3和4
最好的方法是生成一个随机字符串,代码如下():
公共类随机字符串{
公共静态字符串随机字符串(int-lo,int-hi){
int n=兰特(低,高);
字节b[]=新字节[n];
对于(int i=0;i
如果您非常担心冲突或其他问题,我建议您base64
对UUID进行编码,这样可以减少UUID的大小
故事的寓意:不要依赖UUID的各个部分,因为它们是整体设计的。如果确实需要依赖UUID的各个部分,请确保熟悉特定的UUID类型和实现。以下是生成用户友好ID的另一种方法:
(但您应该使用坏字过滤器)任何UUID/Guid都只有16字节的数据。这16个字节可以使用BASE64(或BASE64url)轻松编码,然后去掉字符串末尾的所有“=”字符
这提供了一个很好的短字符串,它仍然保存与UUID/Guid相同的数据。换句话说,如果有必要,可以从该数据重新创建UUID/Guid。这个如何?实际上,这段代码最多返回13个字符(数字和小写字母)
下面是一种生成URL友好的22个字符UUID的方法
public static String generateShortUuid() {
UUID uuid = UUID.randomUUID();
long lsb = uuid.getLeastSignificantBits();
long msb = uuid.getMostSignificantBits();
byte[] uuidBytes = ByteBuffer.allocate(16).putLong(msb).putLong(lsb).array();
// Strip down the '==' at the end and make it url friendly
return Base64.encode(uuidBytes)
.substring(0, 22)
.replace("/", "_")
.replace("+", "-");
}
对于您的用例,最好跟踪已注册用户的运行计数,并为每个值生成如下所示的字符串标记:
public static String longToReverseBase62(long value /* must be positive! */) {
final char[] LETTERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
StringBuilder result = new StringBuilder(9);
do {
result.append(LETTERS[(int)(value % 62)]);
value /= 62l;
}
while (value != 0);
return result.toString();
}
出于安全原因,如果您将这些值设置为非顺序的,那就更好了,因此每次用户注册时,您都可以将该值增加1024(比如说,为2^64/2^10=2^54用户生成UUID会很好,这肯定比您需要的要多:)在撰写本文时,这个问题的标题是: 如何在Java中创建用户友好的唯一ID、UUID或其他唯一标识符 生成用户友好的ID是一个主观问题。如果您有一个唯一的值,有许多方法可以将其格式化为“用户友好”的值,它们都可以归结为将唯一值与“用户友好”ID一一映射-如果输入值是唯一的,“用户友好”ID也同样是唯一的 此外,通常不可能创建一个同样唯一的随机值,至少如果每个随机值是独立于任何其他值生成的。此外,如果要生成唯一标识符(来自my),您应该问自己很多问题:
0xC000000000000000 variant
0x3FFF000000000000 clock_seq
0x0000FFFFFFFFFFFF node
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());
}
}
import java.nio.ByteBuffer;
import java.util.UUID;
/**
* Generate short UUID (13 characters)
*
* @return short UUID
*/
public static String shortUUID() {
UUID uuid = UUID.randomUUID();
long l = ByteBuffer.wrap(uuid.toString().getBytes()).getLong();
return Long.toString(l, Character.MAX_RADIX);
}
public static String generateShortUuid() {
UUID uuid = UUID.randomUUID();
long lsb = uuid.getLeastSignificantBits();
long msb = uuid.getMostSignificantBits();
byte[] uuidBytes = ByteBuffer.allocate(16).putLong(msb).putLong(lsb).array();
// Strip down the '==' at the end and make it url friendly
return Base64.encode(uuidBytes)
.substring(0, 22)
.replace("/", "_")
.replace("+", "-");
}
public static String longToReverseBase62(long value /* must be positive! */) {
final char[] LETTERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
StringBuilder result = new StringBuilder(9);
do {
result.append(LETTERS[(int)(value % 62)]);
value /= 62l;
}
while (value != 0);
return result.toString();
}