|
|
@ -1,5 +1,7 @@ |
|
|
|
package com.storeroom.utils; |
|
|
|
|
|
|
|
import cn.hutool.core.lang.id.NanoId; |
|
|
|
|
|
|
|
import java.security.SecureRandom; |
|
|
|
import java.util.Random; |
|
|
|
|
|
|
@ -19,52 +21,52 @@ public final class NanoIdUtils { |
|
|
|
public static final int DEFAULT_SIZE = 21; |
|
|
|
|
|
|
|
public static String randomNanoId() { |
|
|
|
return randomNanoId(DEFAULT_NUMBER_GENERATOR, DEFAULT_ALPHABET, DEFAULT_SIZE); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 生成随机ID |
|
|
|
* @param random 随机字符串 |
|
|
|
* @param alphabet 字母 |
|
|
|
* @param size 长度 |
|
|
|
* @return 随机id |
|
|
|
*/ |
|
|
|
public static String randomNanoId(final Random random, final char[] alphabet, final int size) { |
|
|
|
if (random == null) { |
|
|
|
/*随机数不能为空*/ |
|
|
|
throw new IllegalArgumentException("random cannot be null"); |
|
|
|
} |
|
|
|
if (alphabet == null) { |
|
|
|
/*字母不能为空*/ |
|
|
|
throw new IllegalArgumentException("alphabet cannot be null."); |
|
|
|
return NanoId.randomNanoId(DEFAULT_NUMBER_GENERATOR, DEFAULT_ALPHABET, DEFAULT_SIZE); |
|
|
|
} |
|
|
|
|
|
|
|
if (alphabet.length == 0 || alphabet.length >= 256) { |
|
|
|
/* 字母必须保护1-255个字符*/ |
|
|
|
throw new IllegalArgumentException("alphabet must contain between 1 and 255 symbols."); |
|
|
|
} |
|
|
|
|
|
|
|
if (size <= 0) { |
|
|
|
/*长度必须大于0*/ |
|
|
|
throw new IllegalArgumentException("size must be greater than zero."); |
|
|
|
} |
|
|
|
final int mask = (2 << (int) Math.floor(Math.log(alphabet.length - 1) / Math.log(2))) - 1; |
|
|
|
final int step = (int) Math.ceil(1.6 * mask * size / alphabet.length); |
|
|
|
|
|
|
|
final StringBuilder idBuilder = new StringBuilder(); |
|
|
|
while (true) { |
|
|
|
final byte[] bytes = new byte[step]; |
|
|
|
random.nextBytes(bytes); |
|
|
|
for (int i = 0; i < step; i++) { |
|
|
|
final int alphabetIndex = bytes[i] & mask; |
|
|
|
if (alphabetIndex < alphabet.length) { |
|
|
|
idBuilder.append(alphabet[alphabetIndex]); |
|
|
|
if (idBuilder.length() == size) { |
|
|
|
return idBuilder.toString(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// /** |
|
|
|
// * 生成随机ID |
|
|
|
// * @param random 随机字符串 |
|
|
|
// * @param alphabet 字母 |
|
|
|
// * @param size 长度 |
|
|
|
// * @return 随机id |
|
|
|
// */ |
|
|
|
// public static String randomNanoId(final Random random, final char[] alphabet, final int size) { |
|
|
|
// if (random == null) { |
|
|
|
// /*随机数不能为空*/ |
|
|
|
// throw new IllegalArgumentException("random cannot be null"); |
|
|
|
// } |
|
|
|
// if (alphabet == null) { |
|
|
|
// /*字母不能为空*/ |
|
|
|
// throw new IllegalArgumentException("alphabet cannot be null."); |
|
|
|
// } |
|
|
|
// |
|
|
|
// if (alphabet.length == 0 || alphabet.length >= 256) { |
|
|
|
// /* 字母必须保护1-255个字符*/ |
|
|
|
// throw new IllegalArgumentException("alphabet must contain between 1 and 255 symbols."); |
|
|
|
// } |
|
|
|
// |
|
|
|
// if (size <= 0) { |
|
|
|
// /*长度必须大于0*/ |
|
|
|
// throw new IllegalArgumentException("size must be greater than zero."); |
|
|
|
// } |
|
|
|
// final int mask = (2 << (int) Math.floor(Math.log(alphabet.length - 1) / Math.log(2))) - 1; |
|
|
|
// final int step = (int) Math.ceil(1.6 * mask * size / alphabet.length); |
|
|
|
// |
|
|
|
// final StringBuilder idBuilder = new StringBuilder(); |
|
|
|
// while (true) { |
|
|
|
// final byte[] bytes = new byte[step]; |
|
|
|
// random.nextBytes(bytes); |
|
|
|
// for (int i = 0; i < step; i++) { |
|
|
|
// final int alphabetIndex = bytes[i] & mask; |
|
|
|
// if (alphabetIndex < alphabet.length) { |
|
|
|
// idBuilder.append(alphabet[alphabetIndex]); |
|
|
|
// if (idBuilder.length() == size) { |
|
|
|
// return idBuilder.toString(); |
|
|
|
// } |
|
|
|
// } |
|
|
|
// } |
|
|
|
// } |
|
|
|
// } |
|
|
|
} |