UUID string validation in Java

How check if a string is a valid UUID in java? If you ask Google, there is a good chance that you’ll get an answer like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.UUID;

public class UUIDValidator {

    public static boolean isValidUUID(String uuidString) {
        if (uuidString == null) {
            return false;
        }

        try {
            UUID.fromString(uuidString);
            return true;

        } catch (IllegalArgumentException exception) {
            return false;
        }
    }
}
1
2
3
4
public static void main(String[] args) {
    System.out.println(isValidUUID("4d93693a-2804-4a31-8e09-3c3db2df3182")); // true
    System.out.println(isValidUUID("invalid-uuid-string")); // false
}

But this isn’t a completely correct solution. It’ll return false-positive true when the UUID string doesn’t have all the characters in the right places. For example: is 4d93693a-2804-4a31-8e09-3c3db2df318 a valid UUID? And what about a-a-a-a-a? In most of the cases in my practice the answer is “no”, but the example below will return true.

1
2
3
4
public static void main(String[] args) {
    System.out.println(isValidUUID("4d93693a-2804-4a31-8e09-3c3db2df318")); // true
    System.out.println(isValidUUID("a-a-a-a-a")); // true
}

The reason is that java.util.UUID interprets each group of characters as a HEX number.

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
    String uuidString1 = "4d93693a-2804-4a31-8e09-3c3db2df318";
    UUID uuid1 = UUID.fromString(uuidString1);
    System.out.println(uuid1.toString().equals(uuidString1)); // false
    System.out.println(uuid1); // 4d93693a-2804-4a31-8e09-03c3db2df318

    String uuidString2 = "a-a-a-a-a";
    UUID uuid2 = UUID.fromString(uuidString2);
    System.out.println(uuid2.toString().equals(uuidString2)); // false
    System.out.println(uuid2); // 0000000a-000a-000a-000a-00000000000a
}

It’s better to use pattern matching to validate UUID strings. The pattern can check if the characters count in each group is correct.

1
2
3
4
5
6
7
8
9
10
import java.util.regex.Pattern;

public class UUIDValidator {

    public static final Pattern UUID_PATTERN = Pattern.compile("^[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}$");

    public static boolean isValidUUID(String uuidString) {
        return UUID_PATTERN.matcher(uuidString).matches();
    }
}

Let’s write some final tests:

1
2
3
4
5
6
public static void main(String[] args) {
    System.out.println(isValidUUID("4d93693a-2804-4a31-8e09-3c3db2df3182")); // true
    System.out.println(isValidUUID("invalid-uuid-string")); // false
    System.out.println(isValidUUID("4d93693a-2804-4a31-8e09-3c3db2df318")); // false
    System.out.println(isValidUUID("a-a-a-a-a")); // false
}

Now it’s all right.