我正在开发一个必须生成诸如 Google课堂之类的代码的应用程序。当用户创建课程时,我会使用以下功能生成代码
private String codeGenerator(){
StringBuilder stringBuilder=new StringBuilder();
String chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
int characterLength=chars.length();
for(int i=0;i<5;i++){
stringBuilder.append(chars.charAt((int)Math.floor(Math.random()*characterLength)));
}
return stringBuilder.toString();
}
我有62个不同的字符。我可以生成总计很大的 5 ^ 62 代码。我可以在服务器或用户设备中生成此代码。所以我的问题是哪种方法更好?生成的代码与其他代码冲突的可能性有多大?
答案 0 :(得分:2)
从评论看来,您似乎正在为自己的应用程序生成组代码。
对于您的应用程序的用途和规模,可能需要5个字符的代码。但是,您应该知道几点:
Math.random()
很不适合(java.util.Random
也是如此),尤其是因为组代码太短了。请改用安全的随机生成器,例如java.security.SecureRandom
(对于您来说,很幸运,其安全性问题已在Android 4.4中得到解决,正如我从您的评论中看到的那样,它是您的应用程序支持的最低Android版本;请参阅还有this question)。另外,如果可能,请增加组代码的长度,例如8或12个字符。有关更多信息,请参见Unique Random Identifiers。
还有另一个问题。如果5个字符的组代码是唯一授予该组访问权限的东西,则存在严重的安全问题。理想情况下,应该有其他形式的授权,例如仅允许登录用户或某些登录用户—
PERMISSION_DENIED
错误代码)。答案 1 :(得分:1)
避免方案中重复的唯一方法是保留已生成的副本的副本,并避免“生成”任何会导致重复的内容。由于5 ^ 62很大,因此,如果使用数据库,则可以将它们存储在表上;或在哈希集上(如果所有内容都在内存中并且只有一个应用程序实例)(记住,每次创建新ID时都会将生成的ID列表保存到磁盘,并在启动时重新读取它)。
发生碰撞的可能性很低:您需要生成大约5^(62/2) = 5^31 ~= 4.6E21
个真正随机的标识符,以使碰撞更有可能发生(请参阅birthday paradox)-这会花费很多时间存储空间并检查所有这些标识符是否重复,以检测是否存在这种情况。但这就是安全的代价。
答案 2 :(得分:0)
队列:一个麻袋包含一个蓝色的球和一个红色的球。我从麻袋里抽出一个球。红球有什么机会?
答案: 1/2
队列:我收集了5 ^ 62个唯一代码。我从集合中选择一个代码。它是“ ABCDE”的机会是什么?
答案: 1 /(5 ^ 62)
注意::随机数生成器不是actually random。
答案 3 :(得分:0)
好吧,如果您需要一个唯一的生成器,那么接下来呢?这绝对不是随机的,但对于一个实例绝对是唯一的。
public final class UniqueCodeGenerator implements Supplier<String> {
private int code;
@Override
public synchronized String get() {
return String.format("%05d", code++);
}
public static void main(String... args) {
Supplier<String> generator = new UniqueCodeGenerator();
for (int i = 0; i < 10; i++)
System.out.println(generator.get());
}
}