Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在JAVA中生成UUID字符串的有效方法(UUID.randomUUID().toString(),不带破折号)_Java_Random_Uuid - Fatal编程技术网

在JAVA中生成UUID字符串的有效方法(UUID.randomUUID().toString(),不带破折号)

在JAVA中生成UUID字符串的有效方法(UUID.randomUUID().toString(),不带破折号),java,random,uuid,Java,Random,Uuid,我想要一个高效的实用程序来生成唯一的字节序列。UUID是一个很好的候选者,但是UUID.randomUUID().toString()生成类似44e128a5-ac7a-4c9a-be4c-224b6bf81b20的东西,这很好,但我更喜欢短划线字符串 我正在寻找一种有效的方法来生成随机字符串,仅从字母数字字符(无破折号或任何其他特殊符号)生成 public static void main(String[] args) { final String uuid = UUID.random

我想要一个高效的实用程序来生成唯一的字节序列。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);
}

破折号不需要从HTTP请求中删除,正如您在该线程的URL中看到的那个样。 但是,如果您想准备格式良好的URL而不依赖于数据,您应该使用URLEncoder.encode(字符串数据,字符串编码),而不是更改数据的标准格式。 对于UUID字符串表示,破折号是正常的。

我使用JAG(Java UUID生成器)生成唯一的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();
}

您可以从以下位置下载该库:

最后基于UUID.java实现编写了我自己的东西。请注意,我不是在生成UUID,而是以我所能想到的最有效的方式生成一个随机的32字节十六进制字符串

实施 用法 测验 我测试了一些输入,以确保其正常工作:

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));
}

我使用org.apache.commons.codec.binary.Base64将UUID转换为url安全的唯一字符串,该字符串的长度为22个字符,并且具有与UUID相同的唯一性


我将我的代码发布在

上,看到如此多的字符串取代了UUID的想法,我感到惊讶。这个怎么样:

UUID temp = UUID.randomUUID();
String uuidString = Long.toHexString(temp.getMostSignificantBits())
     + Long.toHexString(temp.getLeastSignificantBits());
这是最快的方法,因为UUID的整个toString()已经很昂贵了,更不用说必须解析和执行的正则表达式或替换为空字符串了。

一个简单的解决方案是

UUID.randomUUID().toString().replace("-", "")
(与现有解决方案一样,只是避免了调用。此处不需要正则表达式替换,因此感觉更自然,尽管从技术上讲,它仍然是用正则表达式实现的。由于UUID的生成比替换成本更高,因此在运行时应该没有显著差异。)

对于大多数情况,使用UUID类可能足够快,尽管我希望一些不需要后处理的专门手写变体速度更快。无论如何,总体计算的瓶颈通常是随机数生成器。对于UUID类,它使用


使用哪种随机数生成器也是一种权衡,取决于应用程序。如果它是安全敏感的,通常建议使用SecureRandom。否则,它是一种替代方法(比SecureRandom或旧方法快,但不是加密安全的)。

我刚刚复制了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);
}

我刚刚实现了这个实用程序类,它将UUID创建为带破折号或不带破折号的字符串。可以自由使用和共享。我希望这会有帮助

打包您的.package.name;
导入java.security.SecureRandom;
导入java.util.Random;
/**
*创建基于随机UUID的实用程序类。
* 
*/
公共抽象类RandomUuidStringCreator{
私有静态最终int随机_版本=4;
/**
*以字符串形式返回基于随机的UUID。
* 
*它使用线程本地{@link SecureRandom}。
* 
*@返回基于随机的UUID字符串
*/
公共静态字符串getRandomUuid(){
返回getRandomUuid(SecureRandomLazyHolder.SECURE\u RANDOM);
}
/**
*以带破折号的字符串形式返回基于随机的UUID。
* 
*它使用线程本地{@link SecureRandom}。
* 
*@返回基于随机的UUID字符串
*/
公共静态字符串getRandomUuidWithDashes(){
返回格式(getRandomUuid());
}
/**
*返回基于随机的UUID字符串。
* 
*它使用{@link Random}的任何实例。
* 
*@返回基于随机的UUID字符串
*/
公共静态字符串getRandomUuid(随机){
长msb=0;
长lsb=0;
//(3)随机设置所有位
if(SecureRandom的随机实例){
//SecureRandom实例的速度更快
最终字节[]字节=新字节[16];
随机。下一个字节(字节);
msb=toNumber(字节,0,8);//msb的前8个字节
lsb=toNumber(字节,8,16);//lsb的最后8个字节
}否则{
msb=random.nextLong();//msb的前8个字节
lsb=random.nextLong();//lsb的最后8个字节
}
//应用版本和变量位(符合RFC-4122要求)

msb=(msb&0xFFFFFFFF0FFFL)|(RANDOM_VERSION&0x0f)好吧,因为UUID被添加到字符串上的连字符(破折号)(),我们可以从Java自己的实现中窃取实现,将字节数组缩短到32并调整偏移量

        public static String special() {
            UUID uuid = UUID.randomUUID();
            return fastUUID(uuid.getLeastSignificantBits(), uuid.getMostSignificantBits());
        }

        private static String fastUUID(long lsb, long msb) {
            byte[] buf = new byte[32];
            formatUnsignedLong0(lsb,        4, buf, 20, 12);
            formatUnsignedLong0(lsb >>> 48, 4, buf, 16, 4);

            formatUnsignedLong0(msb,        4, buf, 12, 4);
            formatUnsignedLong0(msb >>> 16, 4, buf, 8,  4);
            formatUnsignedLong0(msb >>> 32, 4, buf, 0,  8);

            return new String(buf, 0);
        }

        private static final char[] digits = {
                '0' , '1' , '2' , '3' , '4' , '5' ,
                '6' , '7' , '8' , '9' , 'a' , 'b' ,
                'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
                'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
                'o' , 'p' , 'q' , 'r' , 's' , 't' ,
                'u' , 'v' , 'w' , 'x' , 'y' , 'z'
        };
        private static void formatUnsignedLong0(long val, int shift, byte[] buf, int offset, int len) {
            int charPos = offset + len;
            int radix = 1 << shift;
            int mask = radix - 1;
            do {
                buf[--charPos] = (byte)digits[((int) val) & mask];
                val >>>= shift;
            } while (charPos > offset);
        }
生成:

23f57da8a2784bb5acca553030f82e61
a14427efd8d147fdae315c1cf20fc53c
ee972aa1cf85414ca364bef5c74a7e57
6877ef35eab94b9485c5dd7c8c5a8a56
578721476629422381c0f625e22564a8
dbf60f068b5443d7bc6e5280696fed9f
dd611e870700480d81d394dd2125316c
04d71b9379ef4db49c28e113485ea76d
fd4e8cf3f85a45ae8c1b9bfe3e489a4a
858c4e8297f849b784b65b6096dec4d4
b30a8ca318a349b486b5693814422555
351c2fab9bc1426fa3bb512484628f12
9ce59e01db38405aab82d46f2a236880
5ffb5acb547a4f15a4621b406391bc0d
541b5fba8ddb4f1ebbd59cdcd5f59f7c
77f9460c4baa43a7bbaaf7f2aff205bd
85fa5254305b4c72b1b7c0103aaee269
062d45aa86694b06aad841236b839341
7a265293560f4223ab8248fda502c89b
b748c13ac45747b99aead4b0a2d7d179
cbcbf623c75d407fa3c88cfc89a90ed4
da263eed8771496faebb6290527f77fa
22231088dec04cffa40fb79ff56c6453
594a66de4b874b3491649c5d033917f6
4f6802ebd0cc4a39b25a67191c3af09d
8878b7ab8aa445cdadbef0f7c70d3deb
2c3ed0154f0c4ddbad498b7ae928b9bc
cac1dcaa80e54e2db3248987d2dbda4a
f9a3567e6dd54bf5900444c8b1c03815
f0d25d7b615a4495b51c01ab15093a88
243e45926311437c8b26cede2dc7de25
e4738c50e4cd448fbac252571c0907df
261d3593cc054569bcd645885d22c2ee
64a4796356a04cc4a09506aeb6f5b8fd
9aeebcbdde074ed69738589ca9bde0f1
ec040c956861466b84ed7f7cec601be0
18bd233781e44e7cb152800db4c4edc7
1b7b251df1244e8db46a45c186aada2b
3e32f644c9074cb3bbb15c5be1d9b95e
625309e3ffd14a90bfbd6d48142ac60e
664f0cf347ce4767add576da584526e7
fe3893fd376849fe9fed00e328e61470
254ce1441bbf4a7eae1cdf8d288e61e8
90896c6b309a49f48cc3b7a1570e1846
5f47acd1319245648098c1aec9b95f23
f798033052614b9eae8da7eba4ba3475
3471c4320e4e431eb1fa9f5eb5cb21e0
855f473fed034b1fa17f4f65b850e03b
1245de826d0d4373bdd4cf2157792954
543a8b16efca4fa2b5263315e8b21660
2dc186d699274257922853d783c0ec13
a92e6b1783db4b49a4aaa424b9e1b03f
16773feb48054cf0942a2a27204b3572
1e58da2107ac4ee39e28a93b32e1df1d
67622c19498d4178a1bab6b19087f2c2
412b6b4474fc43ccbeb1e7707b6420ee
7d0fd632913c425eb5f087600ccea870
439687baddb44852a43048b04d38427c
8b2dcc4e50464429a18b11e4aacf51a2
2fccb1c832894fe6b0b61bbdf175cd39
6d224b3d6e8747319fcf01b0309d8a0f
b4982e3b4b594cb4b334c95c2c96355e
c47fbaf90d1d4e9caf211f93b742631f
9440271e8ba6447d9a008e89a93016a6
8d24274b6a3f436a88362438aa6a221d
60452bd3f71747ed8c3706abb2235bd5
6fa93f2ee30740b89496439dd7227a4f
cc17504cf80641f882c8665ae166ba44
743efe8eac6e47a789928da4fb5b6f70
4c4d2df3461448c4a3e934cf4a7ea74f
b231eb3fb46240d38157764e8906aa7b
a234ae65f7ed48f6b1887644eed36cc2
c9cd5ed3df3f4a27957b45498f0c48ef
3eb2fbbb0a714bb7986aef3ee34f0254
d15968e605f0440c9e740e3f4e498a9f
63a8d50e8db24b91a13d4ac2fb6f7d5b
5377df9296154c57926672ca8b3c9478
a4db4a3a9d5148648a23aa7f4f77f1e0
d0aee355a2ba42de89d659385514b0fa
e92e7702481a4575a66d59c061459c5b
1b6c542d8f994d85a1312ab2cf4545ce
88e347a515474ec59013673e5402b97f
2187d9b2dc2b4d96baceade5ae99db44
4d641e69ca5b4acf90f8afe238d8a940
9c0f4c101c434831b928114c5fc0c401
140e16f6cf134785a98ae9baee5b9e7b
4dac5910f4d047e1b213c058e2230bf3
fb50a7e6333f49e4b469234426d5002f
c96c5f2fa167458eaa6d01997d90a980
1e79721e587c4a92aa55cdf8195c8c55
0da27fc5d8384ce299197b4e06cda1d4
a5e32d9cf5834e86b3fe02bc0e3104d6
2dc1826647594b1fb728de67d3df363c
0276371815254198bd22cc76f901b332
bf9d77b7b4a64e7a97ade2a62af1f8e0
268cce3249f64895b6b47e86cf296e5b
d523201fc950435f803bf89d5f042c45
607a4306b90b467f8b19c2c943bc92ef
adfa9fb63a874ca1ad746ff573f03f28
fe88132c70d141e8839ce9e7f0308750

应该同样有效(更有效)实际上,它比Java更重要。

为什么需要删除破折号才能通过HTTP传输这样一个UUID?我不认为通常需要在HTTP中删除破折号…哪一位会给您带来麻烦?也许在移动环境中,如果您仍然为传输的每个字节付费,并且使用低带宽和高延迟网络,节省4个字节就是sti在某些情况下,我希望删除破折号,因为我们稍后使用UUID字符串作为唯一的请求标识符,使用十六进制小数比[a-f0-9-]容易得多。我删除了HTTP部分,因为它不相关(正如Maxim所解释的),只会混淆读者(在注释和答案中都可以看到).对于您的情况,UUID.randomUUID().toString()有什么问题?还要注意,您(理论上)减少了
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));

}
// 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'
        public static String special() {
            UUID uuid = UUID.randomUUID();
            return fastUUID(uuid.getLeastSignificantBits(), uuid.getMostSignificantBits());
        }

        private static String fastUUID(long lsb, long msb) {
            byte[] buf = new byte[32];
            formatUnsignedLong0(lsb,        4, buf, 20, 12);
            formatUnsignedLong0(lsb >>> 48, 4, buf, 16, 4);

            formatUnsignedLong0(msb,        4, buf, 12, 4);
            formatUnsignedLong0(msb >>> 16, 4, buf, 8,  4);
            formatUnsignedLong0(msb >>> 32, 4, buf, 0,  8);

            return new String(buf, 0);
        }

        private static final char[] digits = {
                '0' , '1' , '2' , '3' , '4' , '5' ,
                '6' , '7' , '8' , '9' , 'a' , 'b' ,
                'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
                'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
                'o' , 'p' , 'q' , 'r' , 's' , 't' ,
                'u' , 'v' , 'w' , 'x' , 'y' , 'z'
        };
        private static void formatUnsignedLong0(long val, int shift, byte[] buf, int offset, int len) {
            int charPos = offset + len;
            int radix = 1 << shift;
            int mask = radix - 1;
            do {
                buf[--charPos] = (byte)digits[((int) val) & mask];
                val >>>= shift;
            } while (charPos > offset);
        }
        public static void main(String[] args) {
            IntStream.range(0, 100).forEach(i-> {
                System.out.println(special());
            });
        }
23f57da8a2784bb5acca553030f82e61
a14427efd8d147fdae315c1cf20fc53c
ee972aa1cf85414ca364bef5c74a7e57
6877ef35eab94b9485c5dd7c8c5a8a56
578721476629422381c0f625e22564a8
dbf60f068b5443d7bc6e5280696fed9f
dd611e870700480d81d394dd2125316c
04d71b9379ef4db49c28e113485ea76d
fd4e8cf3f85a45ae8c1b9bfe3e489a4a
858c4e8297f849b784b65b6096dec4d4
b30a8ca318a349b486b5693814422555
351c2fab9bc1426fa3bb512484628f12
9ce59e01db38405aab82d46f2a236880
5ffb5acb547a4f15a4621b406391bc0d
541b5fba8ddb4f1ebbd59cdcd5f59f7c
77f9460c4baa43a7bbaaf7f2aff205bd
85fa5254305b4c72b1b7c0103aaee269
062d45aa86694b06aad841236b839341
7a265293560f4223ab8248fda502c89b
b748c13ac45747b99aead4b0a2d7d179
cbcbf623c75d407fa3c88cfc89a90ed4
da263eed8771496faebb6290527f77fa
22231088dec04cffa40fb79ff56c6453
594a66de4b874b3491649c5d033917f6
4f6802ebd0cc4a39b25a67191c3af09d
8878b7ab8aa445cdadbef0f7c70d3deb
2c3ed0154f0c4ddbad498b7ae928b9bc
cac1dcaa80e54e2db3248987d2dbda4a
f9a3567e6dd54bf5900444c8b1c03815
f0d25d7b615a4495b51c01ab15093a88
243e45926311437c8b26cede2dc7de25
e4738c50e4cd448fbac252571c0907df
261d3593cc054569bcd645885d22c2ee
64a4796356a04cc4a09506aeb6f5b8fd
9aeebcbdde074ed69738589ca9bde0f1
ec040c956861466b84ed7f7cec601be0
18bd233781e44e7cb152800db4c4edc7
1b7b251df1244e8db46a45c186aada2b
3e32f644c9074cb3bbb15c5be1d9b95e
625309e3ffd14a90bfbd6d48142ac60e
664f0cf347ce4767add576da584526e7
fe3893fd376849fe9fed00e328e61470
254ce1441bbf4a7eae1cdf8d288e61e8
90896c6b309a49f48cc3b7a1570e1846
5f47acd1319245648098c1aec9b95f23
f798033052614b9eae8da7eba4ba3475
3471c4320e4e431eb1fa9f5eb5cb21e0
855f473fed034b1fa17f4f65b850e03b
1245de826d0d4373bdd4cf2157792954
543a8b16efca4fa2b5263315e8b21660
2dc186d699274257922853d783c0ec13
a92e6b1783db4b49a4aaa424b9e1b03f
16773feb48054cf0942a2a27204b3572
1e58da2107ac4ee39e28a93b32e1df1d
67622c19498d4178a1bab6b19087f2c2
412b6b4474fc43ccbeb1e7707b6420ee
7d0fd632913c425eb5f087600ccea870
439687baddb44852a43048b04d38427c
8b2dcc4e50464429a18b11e4aacf51a2
2fccb1c832894fe6b0b61bbdf175cd39
6d224b3d6e8747319fcf01b0309d8a0f
b4982e3b4b594cb4b334c95c2c96355e
c47fbaf90d1d4e9caf211f93b742631f
9440271e8ba6447d9a008e89a93016a6
8d24274b6a3f436a88362438aa6a221d
60452bd3f71747ed8c3706abb2235bd5
6fa93f2ee30740b89496439dd7227a4f
cc17504cf80641f882c8665ae166ba44
743efe8eac6e47a789928da4fb5b6f70
4c4d2df3461448c4a3e934cf4a7ea74f
b231eb3fb46240d38157764e8906aa7b
a234ae65f7ed48f6b1887644eed36cc2
c9cd5ed3df3f4a27957b45498f0c48ef
3eb2fbbb0a714bb7986aef3ee34f0254
d15968e605f0440c9e740e3f4e498a9f
63a8d50e8db24b91a13d4ac2fb6f7d5b
5377df9296154c57926672ca8b3c9478
a4db4a3a9d5148648a23aa7f4f77f1e0
d0aee355a2ba42de89d659385514b0fa
e92e7702481a4575a66d59c061459c5b
1b6c542d8f994d85a1312ab2cf4545ce
88e347a515474ec59013673e5402b97f
2187d9b2dc2b4d96baceade5ae99db44
4d641e69ca5b4acf90f8afe238d8a940
9c0f4c101c434831b928114c5fc0c401
140e16f6cf134785a98ae9baee5b9e7b
4dac5910f4d047e1b213c058e2230bf3
fb50a7e6333f49e4b469234426d5002f
c96c5f2fa167458eaa6d01997d90a980
1e79721e587c4a92aa55cdf8195c8c55
0da27fc5d8384ce299197b4e06cda1d4
a5e32d9cf5834e86b3fe02bc0e3104d6
2dc1826647594b1fb728de67d3df363c
0276371815254198bd22cc76f901b332
bf9d77b7b4a64e7a97ade2a62af1f8e0
268cce3249f64895b6b47e86cf296e5b
d523201fc950435f803bf89d5f042c45
607a4306b90b467f8b19c2c943bc92ef
adfa9fb63a874ca1ad746ff573f03f28
fe88132c70d141e8839ce9e7f0308750