고유 한 바이트 시퀀스를 생성하는 효율적인 유틸리티를 원합니다. UUID는 좋은 후보이지만 좋은 것을 UUID.randomUUID().toString()
생성 44e128a5-ac7a-4c9a-be4c-224b6bf81b20
하지만 대시가없는 문자열을 선호합니다.
영숫자 문자 (대시 또는 다른 특수 기호 없음)에서만 무작위 문자열을 생성하는 효율적인 방법을 찾고 있습니다.
고유 한 바이트 시퀀스를 생성하는 효율적인 유틸리티를 원합니다. UUID는 좋은 후보이지만 좋은 것을 UUID.randomUUID().toString()
생성 44e128a5-ac7a-4c9a-be4c-224b6bf81b20
하지만 대시가없는 문자열을 선호합니다.
영숫자 문자 (대시 또는 다른 특수 기호 없음)에서만 무작위 문자열을 생성하는 효율적인 방법을 찾고 있습니다.
답변:
이것은 그것을한다 :
public static void main(String[] args) {
final String uuid = UUID.randomUUID().toString().replace("-", "");
System.out.println("uuid = " + uuid);
}
이 스레드의 URL에서 볼 수 있듯이 대시는 HTTP 요청에서 제거 할 필요가 없습니다. 그러나 데이터에 의존하지 않고 올바른 형식의 URL을 준비하려면 표준 데이터 형식을 변경하는 대신 URLEncoder.encode (String data, String encoding)를 사용해야합니다. UUID 문자열 표현의 경우 대시는 정상입니다.
http://stackoverflow.com/questions/3804591/efficient-method-to-generate-uuid-string-in-java-uuid-randomuuid-tostring-w?rq=1
UUID.java 구현을 기반으로 내 자신의 무언가를 작성하게되었습니다. 내가있어주의 UUID를 생성하지 않음 , 대신 임의의 (32)는 내가 생각할 수있는 가장 효율적인 방법으로 16 진수 문자열을 바이트.
import java.security.SecureRandom;
import java.util.UUID;
public class RandomUtil {
// Maxim: Copied from UUID implementation :)
private static volatile SecureRandom numberGenerator = null;
private static final long MSB = 0x8000000000000000L;
public static String unique() {
SecureRandom ng = numberGenerator;
if (ng == null) {
numberGenerator = ng = new SecureRandom();
}
return Long.toHexString(MSB | ng.nextLong()) + Long.toHexString(MSB | ng.nextLong());
}
}
RandomUtil.unique()
테스트를 거친 입력 중 일부가 작동하는지 확인했습니다.
public static void main(String[] args) {
System.out.println(UUID.randomUUID().toString());
System.out.println(RandomUtil.unique());
System.out.println();
System.out.println(Long.toHexString(0x8000000000000000L |21));
System.out.println(Long.toBinaryString(0x8000000000000000L |21));
System.out.println(Long.toHexString(Long.MAX_VALUE + 1));
}
JUG (Java UUID Generator)를 사용하여 고유 ID를 생성했습니다. JVM에서 고유합니다. 사용하기에 좋습니다. 다음은 참조 용 코드입니다.
private static final SecureRandom secureRandom = new SecureRandom();
private static final UUIDGenerator generator = UUIDGenerator.getInstance();
public synchronized static String generateUniqueId() {
UUID uuid = generator.generateRandomBasedUUID(secureRandom);
return uuid.toString().replaceAll("-", "").toUpperCase();
}
https://github.com/cowtowncoder/java-uuid-generator 에서 라이브러리를 다운로드 할 수 있습니다.
java.util.UUID
대안 이 있음을 아는 것이 좋습니다 .
간단한 해결책은
UUID.randomUUID().toString().replace("-", "")
(기존의 솔루션과 마찬가지로 String # replaceAll 호출을 피할 수 있습니다. 여기에서는 정규식 대체가 필요하지 않으므로 기술적으로 여전히 정규식으로 구현되지만 String # replace 는 더 자연스럽게 느껴집니다. UUID 생성은 다음과 같습니다. 교체보다 비용이 많이 들지만 런타임에 큰 차이가 없어야합니다.)
UUID 클래스를 사용하는 것은 아마도 대부분의 시나리오에서 충분히 빠르지 만 후 처리가 필요없는 특수한 손으로 쓰는 변형이 더 빠를 것으로 기대합니다. 어쨌든 전체 계산의 병목 현상은 일반적으로 난수 생성기입니다. UUID 클래스의 경우 SecureRandom 을 사용합니다 .
어떤 난수 생성기를 사용할 것인지는 응용 프로그램에 따라 달라집니다. 보안에 민감한 경우 SecureRandom은 일반적으로 권장 사항입니다. 그렇지 않으면 ThreadLocalRandom 이 대안이 될 수 있습니다 (SecureRandom 또는 이전 Random 보다 빠르지 만 암호로 안전하지는 않음).
나는 많은 문자열이 UUID의 아이디어를 대체하는 것을보고 놀랐습니다. 이건 어때요:
UUID temp = UUID.randomUUID();
String uuidString = Long.toHexString(temp.getMostSignificantBits())
+ Long.toHexString(temp.getLeastSignificantBits());
UUID의 전체 toString ()이 구문 분석 및 실행되거나 빈 문자열로 교체 해야하는 정규 표현식을 언급하지 않는 것이 더 비싸기 때문에 이것은 빠른 방법입니다.
String.format("0x%016x%016x", f.getMostSignificantBits(), f.getLeastSignificantBits())
replace
.
방금 UUID toString () 메서드를 복사하고 "-"를 제거하도록 업데이트했습니다. 다른 솔루션보다 훨씬 빠르고 간단합니다.
public String generateUUIDString(UUID uuid) {
return (digits(uuid.getMostSignificantBits() >> 32, 8) +
digits(uuid.getMostSignificantBits() >> 16, 4) +
digits(uuid.getMostSignificantBits(), 4) +
digits(uuid.getLeastSignificantBits() >> 48, 4) +
digits(uuid.getLeastSignificantBits(), 12));
}
/** Returns val represented by the specified number of hex digits. */
private String digits(long val, int digits) {
long hi = 1L << (digits * 4);
return Long.toHexString(hi | (val & (hi - 1))).substring(1);
}
용법:
generateUUIDString(UUID.randomUUID())
리플렉션을 사용한 또 다른 구현
public String generateString(UUID uuid) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
if (uuid == null) {
return "";
}
Method digits = UUID.class.getDeclaredMethod("digits", long.class, int.class);
digits.setAccessible(true);
return ( (String) digits.invoke(uuid, uuid.getMostSignificantBits() >> 32, 8) +
digits.invoke(uuid, uuid.getMostSignificantBits() >> 16, 4) +
digits.invoke(uuid, uuid.getMostSignificantBits(), 4) +
digits.invoke(uuid, uuid.getLeastSignificantBits() >> 48, 4) +
digits.invoke(uuid, uuid.getLeastSignificantBits(), 12));
}
org.apache.commons.codec.binary.Base64를 사용하여 UUID를 길이가 22 자이고 UUID와 동일한 고유성을 갖는 URL 안전 고유 문자열로 변환합니다.
UUID 저장에 코드를 base64 문자열로 게시했습니다.
방금 대시가 있거나없는 UUID를 String으로 만드는이 유틸리티 클래스를 구현했습니다 . 자유롭게 사용하고 공유하십시오. 도움이 되길 바랍니다.
package your.package.name;
import java.security.SecureRandom;
import java.util.Random;
/**
* Utility class that creates random-based UUIDs.
*
*/
public abstract class RandomUuidStringCreator {
private static final int RANDOM_VERSION = 4;
/**
* Returns a random-based UUID as String.
*
* It uses a thread local {@link SecureRandom}.
*
* @return a random-based UUID string
*/
public static String getRandomUuid() {
return getRandomUuid(SecureRandomLazyHolder.SECURE_RANDOM);
}
/**
* Returns a random-based UUID as String WITH dashes.
*
* It uses a thread local {@link SecureRandom}.
*
* @return a random-based UUID string
*/
public static String getRandomUuidWithDashes() {
return format(getRandomUuid());
}
/**
* Returns a random-based UUID String.
*
* It uses any instance of {@link Random}.
*
* @return a random-based UUID string
*/
public static String getRandomUuid(Random random) {
long msb = 0;
long lsb = 0;
// (3) set all bit randomly
if (random instanceof SecureRandom) {
// Faster for instances of SecureRandom
final byte[] bytes = new byte[16];
random.nextBytes(bytes);
msb = toNumber(bytes, 0, 8); // first 8 bytes for MSB
lsb = toNumber(bytes, 8, 16); // last 8 bytes for LSB
} else {
msb = random.nextLong(); // first 8 bytes for MSB
lsb = random.nextLong(); // last 8 bytes for LSB
}
// Apply version and variant bits (required for RFC-4122 compliance)
msb = (msb & 0xffffffffffff0fffL) | (RANDOM_VERSION & 0x0f) << 12; // apply version bits
lsb = (lsb & 0x3fffffffffffffffL) | 0x8000000000000000L; // apply variant bits
// Convert MSB and LSB to hexadecimal
String msbHex = zerofill(Long.toHexString(msb), 16);
String lsbHex = zerofill(Long.toHexString(lsb), 16);
// Return the UUID
return msbHex + lsbHex;
}
/**
* Returns a random-based UUID as String WITH dashes.
*
* It uses a thread local {@link SecureRandom}.
*
* @return a random-based UUID string
*/
public static String getRandomUuidWithDashes(Random random) {
return format(getRandomUuid(random));
}
private static long toNumber(final byte[] bytes, final int start, final int length) {
long result = 0;
for (int i = start; i < length; i++) {
result = (result << 8) | (bytes[i] & 0xff);
}
return result;
}
private static String zerofill(String string, int length) {
return new String(lpad(string.toCharArray(), length, '0'));
}
private static char[] lpad(char[] chars, int length, char fill) {
int delta = 0;
int limit = 0;
if (length > chars.length) {
delta = length - chars.length;
limit = length;
} else {
delta = 0;
limit = chars.length;
}
char[] output = new char[chars.length + delta];
for (int i = 0; i < limit; i++) {
if (i < delta) {
output[i] = fill;
} else {
output[i] = chars[i - delta];
}
}
return output;
}
private static String format(String string) {
char[] input = string.toCharArray();
char[] output = new char[36];
System.arraycopy(input, 0, output, 0, 8);
System.arraycopy(input, 8, output, 9, 4);
System.arraycopy(input, 12, output, 14, 4);
System.arraycopy(input, 16, output, 19, 4);
System.arraycopy(input, 20, output, 24, 12);
output[8] = '-';
output[13] = '-';
output[18] = '-';
output[23] = '-';
return new String(output);
}
// Holds lazy secure random
private static class SecureRandomLazyHolder {
static final Random SECURE_RANDOM = new SecureRandom();
}
/**
* For tests!
*/
public static void main(String[] args) {
System.out.println("// Using `java.security.SecureRandom` (DEFAULT)");
System.out.println("RandomUuidCreator.getRandomUuid()");
System.out.println();
for (int i = 0; i < 5; i++) {
System.out.println(RandomUuidStringCreator.getRandomUuid());
}
System.out.println();
System.out.println("// Using `java.util.Random` (FASTER)");
System.out.println("RandomUuidCreator.getRandomUuid(new Random())");
System.out.println();
Random random = new Random();
for (int i = 0; i < 5; i++) {
System.out.println(RandomUuidStringCreator.getRandomUuid(random));
}
}
}
이것은 출력입니다.
// Using `java.security.SecureRandom` (DEFAULT)
RandomUuidStringCreator.getRandomUuid()
'f553ca75657b4b5d85bedf1082785a0b'
'525ecc389e934f209b97d0f0db09d9c6'
'93ec6425bb04499ab47b790fd013ab0d'
'c2d438c620ea4cd5baafd448f9fe945b'
'fb4bc5734931415e94e78da62cb5fe0d'
// Using `java.util.Random` (FASTER)
RandomUuidStringCreator.getRandomUuid(new Random())
'051360b5c92d40fbbb89b40842adbacc'
'a993896538aa43faacbcfd83f913f38b'
'720684d22c584d5299cb03cdbc1912d2'
'82cf94ea296a4a138a92825a0068d4a1'
'a7eda46a215c4e55be3aa957ba74ca9c'