YouTube上的每个视频都有一个唯一的识别字符串,例如1cru2fzUlEc。
是否有任何Java方法可以生成接近它的东西?关闭我的意思是字符串是唯一的,短的,并使用数字和字母(区分大小写)。
我需要像YouTube使用的那样使用这样的字符串:在后端系统中识别记录。我正在做一个Java Web应用程序。我不想使用http://example.com?id=123的方法。
我知道Java的UUID实现可以产生类似的结果,但与YouTube相比,它太长了。
谢谢!
非常感谢大家的回复。您的所有输入都是有用的!似乎没有完美的解决方案。任何完美的(如果不是UUID)必须生成并检查(以避免重复)。我是对的吗?
我可以肯定地说,在制作自己的12个字符的视频字符串时,YouTube会遇到与我们Java用户相同的问题吗?
干杯!
我想使用全范围的字母数字字符而不仅仅是十六进制数字。我将使用Marcus Junius Brutus的解决方案。我觉得它足够直观和安全。从理论上讲,我将不得不检查每个生成的字符串,但我不会这样做,因为每次检查都是另一个数据库调用。我将为生成的字符串ID向表字段添加唯一约束。我可能会在第一次生成记录时让那个不幸的用户失败。他需要做的是回到表单再次填充并保存(希望不会因为重复的字符串值而第二次失败)。最初我将使用12-char字符串,我可以在需要时轻松增加长度。
我将使用此解决方案用于与同一后端数据库通信的分布式Web应用程序,这意味着同一应用程序的多个JVM。
这是我的解决方案,我希望它能奏效。
String sampleAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
char[] buf = new char[12];
for (int i = 0 ; i < 12 ; i++)
buf[i] = sampleAlphabet.charAt(random.nextInt(sampleAlphabet.length()));
return new String(buf);
谢谢大家的回复。它们都是可以接受的解决方案。我真的很感激。
祝你们好!
答案 0 :(得分:3)
我认为最好的方法是使用数字和字母生成随机字符串,并在使用之前确保它在您的数据库中不存在。如果确实如此,只需生成另一个并再次检查,等等......
最不可能两次生成相同的字符串(但可能)。
或者正如你所说的那样你可以使用Java的UUID实现,但我想它有点长。
答案 1 :(得分:3)
你为什么不尝试这个?它满足您的所有需求。
答案 2 :(得分:2)
您可以使用Base64编码自纪元以来的当前时间:
byte[] bytes = String.valueOf(System.currentTimeMillis()).getBytes();
String s = new sun.misc.BASE64Encoder().encode(bytes);
请参阅https://ideone.com/f4cFy1了解演示。
答案 3 :(得分:2)
UUID是128位值的十六进制表示(插入“ - ”作为标点符号,就像逗号或空格用作十进制表示中的千位分隔符一样)。您可以像往常一样生成UUID,然后将128位值转换为更紧凑的表示形式,例如Base64或Ascii85(a.k.a. Base85),从而保留UUID的优点并缩短标识符。这将使它减少到20个字符(使用Ascii85);不像YouTube的ID那么紧凑,但是UUID的36个字符可以节省相当多的费用。
如果仍然太长,则生成较少数量的随机字节(使用良好的PRNG)并转换为Ascii85。每四个字节的数据在Ascii85中生成5个字符。
编辑:在之前的评论中,我建议使用UUID的哈希值。这是它的工作方式。
答案 4 :(得分:1)
如果您想生成任意字符(例如全部字母数字而不仅仅是十六进制数字)或甚至篡改其频率,请创建一个包含所需示例字符的数组,然后:
String sampleAlphabet = "whatever";
Random random = new Random();
char[] bf = new char[length];
for (int i = 0 ; i < length ; i++)
buf[i] = sampleAlphabet.charAt(random.nextInt(sampleAlphabet.length());
return new String(bf);
如果您愿意,请使用SecureRandom以提高安全性。
答案 5 :(得分:1)
UUID通常是以十六进制格式格式化的128位数字。
最大的128位数是2^128-12
。如果以十六进制表示,则将变为32位字符长度log(2^128)/log(16) = 32
您可以定义一个自定义基数(例如包含0-9,a-z和A-Z),它将成为基数(62)10 + 26 + 26(在此基数位中区分大小写!)。
最大的128位数字将变为ceil(log(2^128)/log(62)) = 22
位数。
如果它仍然很大,那么你应该使用较小的数字(不是128位)。
答案 6 :(得分:1)
生成随机字符使用此功能
public static String generateKey(int length) {
String alphabet
= new String("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); //9
int n = alphabet.length();
String result = new String();
Random r = new Random();
for (int i = 0; i < length; i++) {
result = result + alphabet.charAt(r.nextInt(n));
}
return result;
}
答案 7 :(得分:0)
这是一个很好的方法来做你想做的事。 length
是您想要的UUID的长度。重要的是要注意,当你缩短UUID的长度时,碰撞的几率会增加(感谢assylias在评论中提到这一点)。在使用之前,您一定要检查以确保它在数据库中不存在。如果确实如此,则只生成另一个。
public String getUUID(int length)
{
return UUID.randomUUID().toString().replaceAll("-", "").substring(0, length);
}