Foolproof way of differentiating String and UUID
Asked Answered
S

7

18

If I have a string "key:<String || UUID>" is there a way where I can extract the string and differentiate of the part after : is a string or a UUID?

Example: in this key:863864947148451183L and key:1234 May be by using the size of a UUID or the number of bytes?

Springspringboard answered 10/9, 2013 at 16:53 Comment(3)
The toString() value of a UUID is 36 characters long, but what if you're String is also randomly 32 characters long?Veda
Is there such a thing as a UUID that isn't a string? (And why do you need to differentiate?)Victory
You can have the compiler differentiate for you right? A UUID is-not-a StringEntresol
V
17

The only foolproof way is to use

UUID.fromString(yourString);

It will return an

java.lang.IllegalArgumentException: Invalid UUID string: "someString"

Handle the exception.

The javadoc explains the UUID format.

Veda answered 10/9, 2013 at 16:55 Comment(5)
The test for this exception is just for trivial cases and it should not be used for validation. Not just because it is an exception, but also because the JVM might use simpler tests than you might expect. My for instance uses this test to throw the exception: String[] var1 = var0.split("-"); if (var1.length != 5) { throw new IllegalArgumentException("Invalid UUID string: " + var0); } The only foolproof way is to match against the RFC specification.Crocoite
@Crocoite The factory method proceeds to parse each component of the string. Long.decode also throws IllegalArgumentException if the component passed to it isn't parseable.Veda
Interesting, but even if it was the case, this is exception as logic. Let's try "1-1-1-1-1"Crocoite
Because fromString does not take a desired UUID version you should also verify the desired version of the UUID using the .version() method, usually you want version 4.Mocha
It also can throw NumberFormatException thoughFoilsman
C
12

Using exceptions to replace logic is never a good option. In this case the use of the exception is also erroneous, logically speaking.

First one must consider why the exception is thrown and if it is a case where the act of throwing the exception is JVM dependent.

My JDK for instance points to the following logic when evaluating if the exception is thrown

    String[] var1 = var0.split("-"); 
    if (var1.length != 5) { 
        throw new IllegalArgumentException("Invalid UUID string: " + var0);
    }

As one can see, it is a simple and fast check.

Long.decode, as mentioned also throws one exception a NumberFormatException, which might be a big stretch to understand this as a validation mechanism.

Even when those start getting ugly, one might still use the rational that leads to UUID is invalid if any of those is invalid.

But the matter of the fact is that the real test one could get from this exceptions, if one chooses to use this exception to build logic, is that it is enough to say that the String is an UUID if it is translatable to 5 numbers separated by "-". (!)

Of course the RFC 4122 goes beyond that.

But let's focus on Java and the UUID class. https://docs.oracle.com/javase/8/docs/api/java/util/UUID.html

One could simply use the documented format to create a validator

UUID                   = <time_low> "-" <time_mid> "-"
                         <time_high_and_version> "-"
                         <variant_and_sequence> "-"
                         <node>
time_low               = 4*<hexOctet>
time_mid               = 2*<hexOctet>
time_high_and_version  = 2*<hexOctet>
variant_and_sequence   = 2*<hexOctet>
node                   = 6*<hexOctet>
hexOctet               = <hexDigit><hexDigit>
hexDigit               =
      "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
      | "a" | "b" | "c" | "d" | "e" | "f"
      | "A" | "B" | "C" | "D" | "E" | "F"

This could be translated in java to

private static final String TIME_LOW = "[0-9a-fA-F]{8}";
private static final String TIME_MID = "[0-9a-fA-F]{4}";
private static final String TIME_HIGH_AND_VERSION = "[0-9a-fA-F]{4}";
private static final String VARIANT_AND_SEQUENCE = "[0-9a-fA-F]{4}";
private static final String NODE = "[0-9a-fA-F]{12}";

private static final Pattern UUID_PATTERN = Pattern.compile( "^" + TIME_LOW + "-" + TIME_MID + "-" + TIME_HIGH_AND_VERSION + "-" + VARIANT_AND_SEQUENCE + "-" + NODE + "$" );

Of course, this is just to be externally descriptive.

This is a first try, that aligns with the documentation. But according to the RFC and other documents, there are extras constrains, given a layout dictated by the version and variant of the UUID.

Several people do propose regex as:

"^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"

Or

"(?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-5][0-9a-f]{3}-?[089ab][0-9a-f]{3}-?[0-9a-f]{12}$"

And other version specific regexes...

But this is desconsidering that Java also offers the following method

UUID uuid = new UUID(long mostSigBits, long leastSigBits);

Which leads to arbitrary types and those can be used to generate Strings; those regexes would cause issues for UUIDs like the following:

@Override
public String generate() {
    UUID uuid = new UUID(
        SecureRandomUtil.nextLong(), SecureRandomUtil.nextLong());

    return uuid.toString();
}

If it is worth going on validating versions and variations it is up to your needs. Unless you are sure that the UUIDs are in version 3 or 4 (which are the ones explicitly mentioned in the docs) or you if know the version range...

More code... as expected just one works

public class UuidValidatorTest {

    @Test
    public void isUuid( )  {

        assertEquals( UuidValidator.isUuid( "000-000-000-0-0" ), false );
        assertEquals( UuidValidator.isUuid( "1-1-1-1-1" ), false );
        assertEquals( UuidValidator.isUuid( "1-1-1-1-1-1" ), false );
        assertEquals( UuidValidator.isUuid( "0-0-0-0" ), false );
        assertEquals( UuidValidator.isUuid( "a-a-a-a-a" ), false );
        assertEquals( UuidValidator.isUuid( "#-b-c-4-3" ), false );
        assertEquals( UuidValidator.isUuid( "#-b-c-43" ), false );
        assertEquals( UuidValidator.isUuid( "#-b-c-4-3" ), false );

        for ( int i = 0; i < 100; i++ ) {
            assertEquals( UuidValidator.isUuid( UUID.randomUUID( )
                                                    .toString( ) ), true );
        }

        assertEquals( UuidValidator.isUuid( "0297bba3-910e-6672-89e8-c3eacecfe1fa" ), true );
        assertEquals( UuidValidator.isUuid( "02a67f91-c4ca-e886-309a-35cf7079babd" ), true );
        assertEquals( UuidValidator.isUuid( "02f07ba0-72a5-cdcd-d41e-e3b4859623b5" ), true );
        assertEquals( UuidValidator.isUuid( "0457a05a-4104-a4e9-ae09-a32491d42c5a" ), true );
        assertEquals( UuidValidator.isUuid( "07ee5f9a-aa75-ec6f-f73e-7e99d9a40354" ), true );
        assertEquals( UuidValidator.isUuid( "08623b7a-75a3-bd91-8d95-eb46eabfd53d" ), true );
        assertEquals( UuidValidator.isUuid( "089db790-954c-8db6-f5f6-bbb15e6ae860" ), true );
        assertEquals( UuidValidator.isUuid( "08e4be51-4799-2ef9-d2ee-1981fb00a41e" ), true );
        assertEquals( UuidValidator.isUuid( "0acf3eed-3455-e9b2-ee8e-5266e6a4d659" ), true );
        assertEquals( UuidValidator.isUuid( "0ff8fe99-ce2d-a492-78c6-4a5895f6ad10" ), true );
        assertEquals( UuidValidator.isUuid( "15d95f4b-958b-501f-5f73-997070c06a1a" ), true );
        assertEquals( UuidValidator.isUuid( "169269e9-044c-63d4-99b4-3661261b3be9" ), true );
        assertEquals( UuidValidator.isUuid( "1771bfb3-2c98-b0e9-271f-f59a9a314074" ), true );
        assertEquals( UuidValidator.isUuid( "1992d0b4-2c46-6912-f1ec-56f03e2b0ea7" ), true );
        assertEquals( UuidValidator.isUuid( "19fc7632-ac67-8cda-7d04-a549cee0585d" ), true );
        assertEquals( UuidValidator.isUuid( "1a4ae1c9-b225-b8b2-8dbf-6ba3f497c939" ), true );
        assertEquals( UuidValidator.isUuid( "1d71875f-7da2-52c8-ca28-6bd57ac6fb34" ), true );
        assertEquals( UuidValidator.isUuid( "1e2dafca-7dd8-ffca-9bf8-a4e6132b0437" ), true );
        assertEquals( UuidValidator.isUuid( "1e494bfe-cd24-c2dc-4ac8-0192a1766758" ), true );
        assertEquals( UuidValidator.isUuid( "1e50da64-ee2a-769d-187b-cafb04befece" ), true );
        assertEquals( UuidValidator.isUuid( "1f856c29-b2f7-d07d-7c2a-611e44628810" ), true );
        assertEquals( UuidValidator.isUuid( "2311842f-c032-0cec-3967-4f33b45cc24c" ), true );
        assertEquals( UuidValidator.isUuid( "2575d3db-3c8c-21ab-a458-dbc7a5655418" ), true );
        assertEquals( UuidValidator.isUuid( "25dc750d-afe7-3394-b199-760486888e74" ), true );
        assertEquals( UuidValidator.isUuid( "26293add-e373-90c9-4503-917c448bdcbd" ), true );
        assertEquals( UuidValidator.isUuid( "2dc8c6df-ab98-3546-935f-4ba1c3d6fe74" ), true );
        assertEquals( UuidValidator.isUuid( "30334014-fac7-1411-113d-1367f1eb6a1b" ), true );
        assertEquals( UuidValidator.isUuid( "3109e737-a1a2-cc87-c1dd-111329b3b1a4" ), true );
        assertEquals( UuidValidator.isUuid( "32e98007-0a3e-5242-8d0e-f2ae48bf0864" ), true );
        assertEquals( UuidValidator.isUuid( "362a1961-3da4-28c4-4067-0be4ce31c159" ), true );
        assertEquals( UuidValidator.isUuid( "3b95871a-4dbf-395f-5c9f-e5f323bdfd13" ), true );
        assertEquals( UuidValidator.isUuid( "3ef8cc6c-1296-d6d3-903f-d92240885cc9" ), true );
        assertEquals( UuidValidator.isUuid( "3fa4ef78-33f3-3e67-9eae-6a67c5716fa9" ), true );
        assertEquals( UuidValidator.isUuid( "4046d469-f1b4-ebfc-7264-500d3b4da506" ), true );
        assertEquals( UuidValidator.isUuid( "42b4f4c0-6b20-932f-f7c7-c2a2f62208b6" ), true );
        assertEquals( UuidValidator.isUuid( "42fb4ec7-a623-665d-73ac-14b4559ce1f0" ), true );
        assertEquals( UuidValidator.isUuid( "443e8753-01c4-7901-e839-3ac87573e2b5" ), true );
        assertEquals( UuidValidator.isUuid( "446f9fdb-0676-680a-ee49-f252ed4ec538" ), true );
        assertEquals( UuidValidator.isUuid( "464eb3e0-dff8-b68a-24a5-70a1753594fc" ), true );
        assertEquals( UuidValidator.isUuid( "46ba5592-d353-37a3-842d-1bcc04d6deb8" ), true );
        assertEquals( UuidValidator.isUuid( "48699a39-d976-6ef4-0ae0-241c931637d9" ), true );
        assertEquals( UuidValidator.isUuid( "4a5dbe49-7214-0d5d-a7b1-a5619b60f400" ), true );
        assertEquals( UuidValidator.isUuid( "4a8114ab-173a-d83b-b696-f7db487d2708" ), true );
        assertEquals( UuidValidator.isUuid( "4f0d7370-763b-7ea4-452b-39269e788a8c" ), true );
        assertEquals( UuidValidator.isUuid( "5086a7dc-c810-6ac4-6951-4212dde66537" ), true );
        assertEquals( UuidValidator.isUuid( "5237e6b4-a5d8-4eab-1acf-fff899453d34" ), true );
        assertEquals( UuidValidator.isUuid( "52f9a633-8ba1-1001-7d27-0c38a2e28232" ), true );
        assertEquals( UuidValidator.isUuid( "53dc03f1-a77e-2f43-d46c-6f166b14f540" ), true );
        assertEquals( UuidValidator.isUuid( "56634e53-730f-7a7e-4476-21b06fab20d9" ), true );
        assertEquals( UuidValidator.isUuid( "575215c7-69f6-7211-ddb5-a87dd5f755e5" ), true );
        assertEquals( UuidValidator.isUuid( "57dfaa94-150e-63e4-4172-bf042f27facf" ), true );
        assertEquals( UuidValidator.isUuid( "5802ab41-2543-ecd6-8571-46e6ce389b06" ), true );
        assertEquals( UuidValidator.isUuid( "5a7ed59e-8f1b-acde-6edb-3d116f3c99ed" ), true );
        assertEquals( UuidValidator.isUuid( "5a8feb9f-09ba-c1df-9407-a28aa743e797" ), true );
        assertEquals( UuidValidator.isUuid( "5d98e524-02f9-7dec-0838-feec68e0b95d" ), true );
        assertEquals( UuidValidator.isUuid( "5e92060a-a504-afce-3c27-7e1269f90999" ), true );
        assertEquals( UuidValidator.isUuid( "5edab579-10b4-7a77-b7cc-7a9688d5e63a" ), true );
        assertEquals( UuidValidator.isUuid( "66716e2e-dd18-8782-e33e-4fad7ec299ea" ), true );
        assertEquals( UuidValidator.isUuid( "680065c7-4897-46be-75bf-9c74167be8f1" ), true );
        assertEquals( UuidValidator.isUuid( "68e41661-9a24-89a1-489e-93ad934b0846" ), true );
        assertEquals( UuidValidator.isUuid( "6ac02e05-8bc7-f402-9401-4d54a61c44f6" ), true );
        assertEquals( UuidValidator.isUuid( "6b8e08c5-3ee6-b616-2646-38c7d4faa04c" ), true );
        assertEquals( UuidValidator.isUuid( "70f13ff1-e205-98f6-a1ff-ccb4af8255d4" ), true );
        assertEquals( UuidValidator.isUuid( "724c5782-8c40-8b80-0012-e1d832b9e066" ), true );
        assertEquals( UuidValidator.isUuid( "765519f4-51e9-0fd9-2f21-ce0b874b5482" ), true );
        assertEquals( UuidValidator.isUuid( "77b3acfd-b7eb-083e-c51c-7d5b30bad312" ), true );
        assertEquals( UuidValidator.isUuid( "783d2bc2-e745-d1ae-4cf6-c669e538cf21" ), true );
        assertEquals( UuidValidator.isUuid( "7c1d5469-df85-d157-deac-15e86e721f06" ), true );
        assertEquals( UuidValidator.isUuid( "7d63c847-037f-7a06-e7ac-981338ca4935" ), true );
        assertEquals( UuidValidator.isUuid( "7e60b2d4-94e3-e735-c8a4-16032886b94c" ), true );
        assertEquals( UuidValidator.isUuid( "7fed1a4e-59e0-9809-f857-363bbc526604" ), true );
        assertEquals( UuidValidator.isUuid( "8228784b-3090-e4a5-185d-97278db07ded" ), true );
        assertEquals( UuidValidator.isUuid( "88aedd2a-9785-5925-7105-455df71283c2" ), true );
        assertEquals( UuidValidator.isUuid( "89af347d-f602-d4a1-0b1b-545b142d24fd" ), true );
        assertEquals( UuidValidator.isUuid( "8a43653f-9268-35c4-2cf6-ebc682d0b68d" ), true );
        assertEquals( UuidValidator.isUuid( "8ba6284f-3829-7017-a63e-5b3d54002ac2" ), true );
        assertEquals( UuidValidator.isUuid( "8cb60b26-ddfa-ba7a-fb96-e088a94d78de" ), true );
        assertEquals( UuidValidator.isUuid( "8de06bac-305e-e1e6-809b-5c7e00c6e662" ), true );
        assertEquals( UuidValidator.isUuid( "8f3497bc-037e-d365-f3f2-1adb1c2abc45" ), true );
        assertEquals( UuidValidator.isUuid( "92d4d7d9-2c8c-9703-ba4f-3e69fd420a99" ), true );
        assertEquals( UuidValidator.isUuid( "92fff203-a3dd-6aa1-4deb-60e1ed929b0c" ), true );
        assertEquals( UuidValidator.isUuid( "99d7a461-b9a4-1ba3-0380-638148f097aa" ), true );
        assertEquals( UuidValidator.isUuid( "99e2be43-3064-5a6e-9d7f-0aab0ef62733" ), true );
        assertEquals( UuidValidator.isUuid( "9e7b55fb-7f9f-6aeb-90b3-4bc331cfae66" ), true );
        assertEquals( UuidValidator.isUuid( "a04065b8-c223-77a6-85c5-588ac84f8acf" ), true );
        assertEquals( UuidValidator.isUuid( "a1299e22-f2ba-437c-9d3a-cfcee841c76a" ), true );
        assertEquals( UuidValidator.isUuid( "a1d5a723-8a39-19ac-339e-78ac35ce96f4" ), true );
        assertEquals( UuidValidator.isUuid( "a394cfcd-867b-3ef2-2d0b-3b96ba2e40a8" ), true );
        assertEquals( UuidValidator.isUuid( "a3cce812-b718-2ddf-b7de-acd011e8f24a" ), true );
        assertEquals( UuidValidator.isUuid( "a4d4a700-7e9f-f4f7-9be3-4ed87b4ba157" ), true );
        assertEquals( UuidValidator.isUuid( "a88cb5ec-bc35-4b60-0840-4d541caf6258" ), true );
        assertEquals( UuidValidator.isUuid( "a952b4c1-7377-cce5-0b81-c770cd0c884a" ), true );
        assertEquals( UuidValidator.isUuid( "abf7d3d0-ae8c-1495-6a44-27cd098f0b2f" ), true );
        assertEquals( UuidValidator.isUuid( "ace167ab-2c57-d4a5-0e2a-d486445870cb" ), true );
        assertEquals( UuidValidator.isUuid( "ad6f7597-0aef-9ef0-e293-a6ce1583eb7e" ), true );
        assertEquals( UuidValidator.isUuid( "b0685971-fee9-38a2-ce30-17b4bd51c8d1" ), true );
    }

    @Test
    public void isUuidWithException( )  {

        assertEquals( UuidValidator.isUuidWithException( "000-000-000-0-0" ), false );
        assertEquals( UuidValidator.isUuidWithException( "1-1-1-1-1" ), false );
        assertEquals( UuidValidator.isUuidWithException( "1-1-1-1-1-1" ), false );
        assertEquals( UuidValidator.isUuidWithException( "0-0-0-0" ), false );
        assertEquals( UuidValidator.isUuidWithException( "a-a-a-a-a" ), false );
        assertEquals( UuidValidator.isUuidWithException( "#-b-c-4-3" ), false );
        assertEquals( UuidValidator.isUuidWithException( "#-b-c-43" ), false );
        assertEquals( UuidValidator.isUuidWithException( "#-b-c-4-3" ), false );

        for ( int i = 0; i < 100; i++ ) {
            assertEquals( UuidValidator.isUuidWithException( UUID.randomUUID( )
                                                    .toString( ) ), true );
        }

        assertEquals( UuidValidator.isUuidWithException( "0297bba3-910e-6672-89e8-c3eacecfe1fa" ), true );
        assertEquals( UuidValidator.isUuidWithException( "02a67f91-c4ca-e886-309a-35cf7079babd" ), true );
        assertEquals( UuidValidator.isUuidWithException( "02f07ba0-72a5-cdcd-d41e-e3b4859623b5" ), true );
        assertEquals( UuidValidator.isUuidWithException( "0457a05a-4104-a4e9-ae09-a32491d42c5a" ), true );
        assertEquals( UuidValidator.isUuidWithException( "07ee5f9a-aa75-ec6f-f73e-7e99d9a40354" ), true );
        assertEquals( UuidValidator.isUuidWithException( "08623b7a-75a3-bd91-8d95-eb46eabfd53d" ), true );
        assertEquals( UuidValidator.isUuidWithException( "089db790-954c-8db6-f5f6-bbb15e6ae860" ), true );
        assertEquals( UuidValidator.isUuidWithException( "08e4be51-4799-2ef9-d2ee-1981fb00a41e" ), true );
        assertEquals( UuidValidator.isUuidWithException( "0acf3eed-3455-e9b2-ee8e-5266e6a4d659" ), true );
        assertEquals( UuidValidator.isUuidWithException( "0ff8fe99-ce2d-a492-78c6-4a5895f6ad10" ), true );
        assertEquals( UuidValidator.isUuidWithException( "15d95f4b-958b-501f-5f73-997070c06a1a" ), true );
        assertEquals( UuidValidator.isUuidWithException( "169269e9-044c-63d4-99b4-3661261b3be9" ), true );
        assertEquals( UuidValidator.isUuidWithException( "1771bfb3-2c98-b0e9-271f-f59a9a314074" ), true );
        assertEquals( UuidValidator.isUuidWithException( "1992d0b4-2c46-6912-f1ec-56f03e2b0ea7" ), true );
        assertEquals( UuidValidator.isUuidWithException( "19fc7632-ac67-8cda-7d04-a549cee0585d" ), true );
        assertEquals( UuidValidator.isUuidWithException( "1a4ae1c9-b225-b8b2-8dbf-6ba3f497c939" ), true );
        assertEquals( UuidValidator.isUuidWithException( "1d71875f-7da2-52c8-ca28-6bd57ac6fb34" ), true );
        assertEquals( UuidValidator.isUuidWithException( "1e2dafca-7dd8-ffca-9bf8-a4e6132b0437" ), true );
        assertEquals( UuidValidator.isUuidWithException( "1e494bfe-cd24-c2dc-4ac8-0192a1766758" ), true );
        assertEquals( UuidValidator.isUuidWithException( "1e50da64-ee2a-769d-187b-cafb04befece" ), true );
        assertEquals( UuidValidator.isUuidWithException( "1f856c29-b2f7-d07d-7c2a-611e44628810" ), true );
        assertEquals( UuidValidator.isUuidWithException( "2311842f-c032-0cec-3967-4f33b45cc24c" ), true );
        assertEquals( UuidValidator.isUuidWithException( "2575d3db-3c8c-21ab-a458-dbc7a5655418" ), true );
        assertEquals( UuidValidator.isUuidWithException( "25dc750d-afe7-3394-b199-760486888e74" ), true );
        assertEquals( UuidValidator.isUuidWithException( "26293add-e373-90c9-4503-917c448bdcbd" ), true );
        assertEquals( UuidValidator.isUuidWithException( "2dc8c6df-ab98-3546-935f-4ba1c3d6fe74" ), true );
        assertEquals( UuidValidator.isUuidWithException( "30334014-fac7-1411-113d-1367f1eb6a1b" ), true );
        assertEquals( UuidValidator.isUuidWithException( "3109e737-a1a2-cc87-c1dd-111329b3b1a4" ), true );
        assertEquals( UuidValidator.isUuidWithException( "32e98007-0a3e-5242-8d0e-f2ae48bf0864" ), true );
        assertEquals( UuidValidator.isUuidWithException( "362a1961-3da4-28c4-4067-0be4ce31c159" ), true );
        assertEquals( UuidValidator.isUuidWithException( "3b95871a-4dbf-395f-5c9f-e5f323bdfd13" ), true );
        assertEquals( UuidValidator.isUuidWithException( "3ef8cc6c-1296-d6d3-903f-d92240885cc9" ), true );
        assertEquals( UuidValidator.isUuidWithException( "3fa4ef78-33f3-3e67-9eae-6a67c5716fa9" ), true );
        assertEquals( UuidValidator.isUuidWithException( "4046d469-f1b4-ebfc-7264-500d3b4da506" ), true );
        assertEquals( UuidValidator.isUuidWithException( "42b4f4c0-6b20-932f-f7c7-c2a2f62208b6" ), true );
        assertEquals( UuidValidator.isUuidWithException( "42fb4ec7-a623-665d-73ac-14b4559ce1f0" ), true );
        assertEquals( UuidValidator.isUuidWithException( "443e8753-01c4-7901-e839-3ac87573e2b5" ), true );
        assertEquals( UuidValidator.isUuidWithException( "446f9fdb-0676-680a-ee49-f252ed4ec538" ), true );
        assertEquals( UuidValidator.isUuidWithException( "464eb3e0-dff8-b68a-24a5-70a1753594fc" ), true );
        assertEquals( UuidValidator.isUuidWithException( "46ba5592-d353-37a3-842d-1bcc04d6deb8" ), true );
        assertEquals( UuidValidator.isUuidWithException( "48699a39-d976-6ef4-0ae0-241c931637d9" ), true );
        assertEquals( UuidValidator.isUuidWithException( "4a5dbe49-7214-0d5d-a7b1-a5619b60f400" ), true );
        assertEquals( UuidValidator.isUuidWithException( "4a8114ab-173a-d83b-b696-f7db487d2708" ), true );
        assertEquals( UuidValidator.isUuidWithException( "4f0d7370-763b-7ea4-452b-39269e788a8c" ), true );
        assertEquals( UuidValidator.isUuidWithException( "5086a7dc-c810-6ac4-6951-4212dde66537" ), true );
        assertEquals( UuidValidator.isUuidWithException( "5237e6b4-a5d8-4eab-1acf-fff899453d34" ), true );
        assertEquals( UuidValidator.isUuidWithException( "52f9a633-8ba1-1001-7d27-0c38a2e28232" ), true );
        assertEquals( UuidValidator.isUuidWithException( "53dc03f1-a77e-2f43-d46c-6f166b14f540" ), true );
        assertEquals( UuidValidator.isUuidWithException( "56634e53-730f-7a7e-4476-21b06fab20d9" ), true );
        assertEquals( UuidValidator.isUuidWithException( "575215c7-69f6-7211-ddb5-a87dd5f755e5" ), true );
        assertEquals( UuidValidator.isUuidWithException( "57dfaa94-150e-63e4-4172-bf042f27facf" ), true );
        assertEquals( UuidValidator.isUuidWithException( "5802ab41-2543-ecd6-8571-46e6ce389b06" ), true );
        assertEquals( UuidValidator.isUuidWithException( "5a7ed59e-8f1b-acde-6edb-3d116f3c99ed" ), true );
        assertEquals( UuidValidator.isUuidWithException( "5a8feb9f-09ba-c1df-9407-a28aa743e797" ), true );
        assertEquals( UuidValidator.isUuidWithException( "5d98e524-02f9-7dec-0838-feec68e0b95d" ), true );
        assertEquals( UuidValidator.isUuidWithException( "5e92060a-a504-afce-3c27-7e1269f90999" ), true );
        assertEquals( UuidValidator.isUuidWithException( "5edab579-10b4-7a77-b7cc-7a9688d5e63a" ), true );
        assertEquals( UuidValidator.isUuidWithException( "66716e2e-dd18-8782-e33e-4fad7ec299ea" ), true );
        assertEquals( UuidValidator.isUuidWithException( "680065c7-4897-46be-75bf-9c74167be8f1" ), true );
        assertEquals( UuidValidator.isUuidWithException( "68e41661-9a24-89a1-489e-93ad934b0846" ), true );
        assertEquals( UuidValidator.isUuidWithException( "6ac02e05-8bc7-f402-9401-4d54a61c44f6" ), true );
        assertEquals( UuidValidator.isUuidWithException( "6b8e08c5-3ee6-b616-2646-38c7d4faa04c" ), true );
        assertEquals( UuidValidator.isUuidWithException( "70f13ff1-e205-98f6-a1ff-ccb4af8255d4" ), true );
        assertEquals( UuidValidator.isUuidWithException( "724c5782-8c40-8b80-0012-e1d832b9e066" ), true );
        assertEquals( UuidValidator.isUuidWithException( "765519f4-51e9-0fd9-2f21-ce0b874b5482" ), true );
        assertEquals( UuidValidator.isUuidWithException( "77b3acfd-b7eb-083e-c51c-7d5b30bad312" ), true );
        assertEquals( UuidValidator.isUuidWithException( "783d2bc2-e745-d1ae-4cf6-c669e538cf21" ), true );
        assertEquals( UuidValidator.isUuidWithException( "7c1d5469-df85-d157-deac-15e86e721f06" ), true );
        assertEquals( UuidValidator.isUuidWithException( "7d63c847-037f-7a06-e7ac-981338ca4935" ), true );
        assertEquals( UuidValidator.isUuidWithException( "7e60b2d4-94e3-e735-c8a4-16032886b94c" ), true );
        assertEquals( UuidValidator.isUuidWithException( "7fed1a4e-59e0-9809-f857-363bbc526604" ), true );
        assertEquals( UuidValidator.isUuidWithException( "8228784b-3090-e4a5-185d-97278db07ded" ), true );
        assertEquals( UuidValidator.isUuidWithException( "88aedd2a-9785-5925-7105-455df71283c2" ), true );
        assertEquals( UuidValidator.isUuidWithException( "89af347d-f602-d4a1-0b1b-545b142d24fd" ), true );
        assertEquals( UuidValidator.isUuidWithException( "8a43653f-9268-35c4-2cf6-ebc682d0b68d" ), true );
        assertEquals( UuidValidator.isUuidWithException( "8ba6284f-3829-7017-a63e-5b3d54002ac2" ), true );
        assertEquals( UuidValidator.isUuidWithException( "8cb60b26-ddfa-ba7a-fb96-e088a94d78de" ), true );
        assertEquals( UuidValidator.isUuidWithException( "8de06bac-305e-e1e6-809b-5c7e00c6e662" ), true );
        assertEquals( UuidValidator.isUuidWithException( "8f3497bc-037e-d365-f3f2-1adb1c2abc45" ), true );
        assertEquals( UuidValidator.isUuidWithException( "92d4d7d9-2c8c-9703-ba4f-3e69fd420a99" ), true );
        assertEquals( UuidValidator.isUuidWithException( "92fff203-a3dd-6aa1-4deb-60e1ed929b0c" ), true );
        assertEquals( UuidValidator.isUuidWithException( "99d7a461-b9a4-1ba3-0380-638148f097aa" ), true );
        assertEquals( UuidValidator.isUuidWithException( "99e2be43-3064-5a6e-9d7f-0aab0ef62733" ), true );
        assertEquals( UuidValidator.isUuidWithException( "9e7b55fb-7f9f-6aeb-90b3-4bc331cfae66" ), true );
        assertEquals( UuidValidator.isUuidWithException( "a04065b8-c223-77a6-85c5-588ac84f8acf" ), true );
        assertEquals( UuidValidator.isUuidWithException( "a1299e22-f2ba-437c-9d3a-cfcee841c76a" ), true );
        assertEquals( UuidValidator.isUuidWithException( "a1d5a723-8a39-19ac-339e-78ac35ce96f4" ), true );
        assertEquals( UuidValidator.isUuidWithException( "a394cfcd-867b-3ef2-2d0b-3b96ba2e40a8" ), true );
        assertEquals( UuidValidator.isUuidWithException( "a3cce812-b718-2ddf-b7de-acd011e8f24a" ), true );
        assertEquals( UuidValidator.isUuidWithException( "a4d4a700-7e9f-f4f7-9be3-4ed87b4ba157" ), true );
        assertEquals( UuidValidator.isUuidWithException( "a88cb5ec-bc35-4b60-0840-4d541caf6258" ), true );
        assertEquals( UuidValidator.isUuidWithException( "a952b4c1-7377-cce5-0b81-c770cd0c884a" ), true );
        assertEquals( UuidValidator.isUuidWithException( "abf7d3d0-ae8c-1495-6a44-27cd098f0b2f" ), true );
        assertEquals( UuidValidator.isUuidWithException( "ace167ab-2c57-d4a5-0e2a-d486445870cb" ), true );
        assertEquals( UuidValidator.isUuidWithException( "ad6f7597-0aef-9ef0-e293-a6ce1583eb7e" ), true );
        assertEquals( UuidValidator.isUuidWithException( "b0685971-fee9-38a2-ce30-17b4bd51c8d1" ), true );
    }
}
Crocoite answered 9/3, 2018 at 22:12 Comment(0)
C
1

Using Scala, you can use this two liner:

val asTry = Try(UUID.fromString(str)) asTry.isSuccess && asTry.get.toString == str

Much cleaner than that regex :P

Passing tests:

test("testIsValidUUID") {

    isValidUUID("fooo") should be(false)
    isValidUUID("1-1-1-1-1") should be(false)
    isValidUUID(UUID.randomUUID().toString) should be(true)
  }
Clutter answered 30/9, 2018 at 7:20 Comment(0)
M
0

In Scala I prefer this method:

  Try(UUID.fromString(candidate))
    .filter(_.toString == candidate)
    .isSuccess

This way you can avoid using .get

Madox answered 12/7, 2019 at 21:58 Comment(0)
S
0

You could use class-validator.

import { isUUID } from 'class-validator';

isUUID(user.id);
Stenotypy answered 27/7, 2021 at 8:57 Comment(0)
P
0

Java-8 UUID class had few issues as mentioned in the comments in other posts. In Java-11 or Later There are few ways we can do this, with java.util.UUID or using a regex.

UUIDs are exactly 36 characters long and should be in 8-4-4-4-12 format, so if it's not it's invalid.

There are few things to note about java.util.UUID class.

  1. It will accept any string with in [0-9a-fA-F]{1,8}-[0-9a-fA-F]{1,4}-[0-9a-fA-F]{1,4}-[0-9a-fA-F]{1,4}-[0-9a-fA-F]{1,12} as a valid String and generate a UUID by appending leading zeros until it gets a format of ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$
  2. There is not isValid() method, the task of .fromString() is only to generate the UUID from a given String if it's in the above format, or throw an IllegalArgumentException
  3. If we are to use .fromString() because of the point 1, we need to check if the given String was adjusted by the UUID class, easiest way to do that is to check the before and after lengths.
  4. UUIDs can be in lowercase or uppercase, but this class will always generate lowercase UUIDs

a possible implementation of the above is,

public static boolean isValidUUID(String possibleUUID) {
    Objects.requireNonNull(possibleUUID, "possibleUUID cannot be null");

    try {
        UUID uuid = UUID.fromString(possibleUUID);
        // uuid generated by UUID will always be in lowercase
        // If the length is less than 36, it'll add leading zeros to the appropriate sections to ensure it reaches 36 characters, conforming to the 8-4-4-4-12 format.
        if(!uuid.toString().equalsIgnoreCase(possibleUUID)){
            // Due to potential length mismatches, it's necessary to verify that the passed value is indeed a valid UUID.
            return false;
        }
    } catch (IllegalArgumentException e) {
        e.printStackTrace(); // possible warn log goes here
        return false;
    }

    // for all the other cases it's safe to say the `possibleUUID` is a valid UUID
    return true;
}

This might not be the cleanest way to do this as catch statements should not be utilized to handle business logic. Since we know the format of the UUID we can actually write a regex check to match the String.

One Better way to do that is,

public static boolean isValidUUID(String possibleUUID) {
    // Regular expression for UUID format 8-4-4-4-12
    // Note that a UUID can contain lowercase and uppercase letters and numbers with `-`
    String uuidRegex = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$";

    // Check if the string matches the given regex, if not it's invalid
    return possibleUUID.matches(uuidRegex);
}
Presley answered 12/3, 2024 at 17:57 Comment(0)
C
0

In Kotlin, you could use this extension function:

fun String?.isValidUuid(): Boolean {
    if (this == null) return false
    return try {
        UUID.fromString(this)
        true
    } catch (exception: IllegalArgumentException) {
        false
    }
}
Chukchi answered 2/4, 2024 at 10:10 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.