我一直在寻找一种简单的Java算法来生成伪随机字母数字字符串。在我的情况下,它将被用作唯一的会话/密钥标识符,“很可能”在超过50万代的时间内是唯一的(我的需求实际上不需要更复杂的东西)。
理想情况下,我可以根据我的独特性需求指定长度。例如,生成的长度为12的字符串可能看起来像“AEYGF7K0DM1X”。
我一直在寻找一种简单的Java算法来生成伪随机字母数字字符串。在我的情况下,它将被用作唯一的会话/密钥标识符,“很可能”在超过50万代的时间内是唯一的(我的需求实际上不需要更复杂的东西)。
理想情况下,我可以根据我的独特性需求指定长度。例如,生成的长度为12的字符串可能看起来像“AEYGF7K0DM1X”。
当前回答
public static String randomSeriesForThreeCharacter() {
Random r = new Random();
String value = "";
char random_Char ;
for(int i=0; i<10; i++)
{
random_Char = (char) (48 + r.nextInt(74));
value = value + random_char;
}
return value;
}
其他回答
我找到了生成随机十六进制编码字符串的解决方案。所提供的单元测试似乎符合我的主要用例。虽然,它比提供的一些其他答案稍微复杂一些。
/**
* Generate a random hex encoded string token of the specified length
*
* @param length
* @return random hex string
*/
public static synchronized String generateUniqueToken(Integer length){
byte random[] = new byte[length];
Random randomGenerator = new Random();
StringBuffer buffer = new StringBuffer();
randomGenerator.nextBytes(random);
for (int j = 0; j < random.length; j++) {
byte b1 = (byte) ((random[j] & 0xf0) >> 4);
byte b2 = (byte) (random[j] & 0x0f);
if (b1 < 10)
buffer.append((char) ('0' + b1));
else
buffer.append((char) ('A' + (b1 - 10)));
if (b2 < 10)
buffer.append((char) ('0' + b2));
else
buffer.append((char) ('A' + (b2 - 10)));
}
return (buffer.toString());
}
@Test
public void testGenerateUniqueToken(){
Set set = new HashSet();
String token = null;
int size = 16;
/* Seems like we should be able to generate 500K tokens
* without a duplicate
*/
for (int i=0; i<500000; i++){
token = Utility.generateUniqueToken(size);
if (token.length() != size * 2){
fail("Incorrect length");
} else if (set.contains(token)) {
fail("Duplicate token generated");
} else{
set.add(token);
}
}
}
这是算盘常用的一行:
String.valueOf(CharStream.random('0', 'z').filter(c -> N.isLetterOrDigit(c)).limit(12).toArray())
随机并不意味着它必须是唯一的。要获取唯一字符串,请使用:
N.uuid() // E.g.: "e812e749-cf4c-4959-8ee1-57829a69a80f". length is 36.
N.guid() // E.g.: "0678ce04e18945559ba82ddeccaabfcd". length is 32 without '-'
Java提供了一种直接实现这一点的方法。如果你不想要破折号,它们很容易去掉。只需使用uuid.replace(“-”,“”)
import java.util.UUID;
public class randomStringGenerator {
public static void main(String[] args) {
System.out.println(generateString());
}
public static String generateString() {
String uuid = UUID.randomUUID().toString();
return "uuid = " + uuid;
}
}
输出
uuid = 2d7428a6-b58c-4008-8575-f05549f16316
令人惊讶的是,这里没有人建议,但:
import java.util.UUID
UUID.randomUUID().toString();
容易的
这样做的好处是UUID很好、很长,并且保证几乎不可能发生冲突。
维基百科对此有很好的解释:
“……只有在未来100年内每秒生成10亿个UUID之后,仅创建一个重复的概率才会达到50%。”
前四位是版本类型,两位是变体,因此您可以得到122位随机数。因此,如果需要,可以从末尾截断以减小UUID的大小。这是不推荐的,但你仍然有大量的随机性,足以让你的500k记录变得容易。
高效而简短。
/**
* Utility class for generating random Strings.
*/
public interface RandomUtil {
int DEF_COUNT = 20;
Random RANDOM = new SecureRandom();
/**
* Generate a password.
*
* @return the generated password
*/
static String generatePassword() {
return generate(true, true);
}
/**
* Generate an activation key.
*
* @return the generated activation key
*/
static String generateActivationKey() {
return generate(false, true);
}
/**
* Generate a reset key.
*
* @return the generated reset key
*/
static String generateResetKey() {
return generate(false, true);
}
static String generate(boolean letters, boolean numbers) {
int
start = ' ',
end = 'z' + 1,
count = DEF_COUNT,
gap = end - start;
StringBuilder builder = new StringBuilder(count);
while (count-- != 0) {
int codePoint = RANDOM.nextInt(gap) + start;
switch (getType(codePoint)) {
case UNASSIGNED:
case PRIVATE_USE:
case SURROGATE:
count++;
continue;
}
int numberOfChars = charCount(codePoint);
if (count == 0 && numberOfChars > 1) {
count++;
continue;
}
if (letters && isLetter(codePoint)
|| numbers && isDigit(codePoint)
|| !letters && !numbers) {
builder.appendCodePoint(codePoint);
if (numberOfChars == 2)
count--;
}
else
count++;
}
return builder.toString();
}
}