admin管理员组

文章数量:1126380

How to check if variable contains valid UUID/GUID identifier?

I'm currently interested only in validating types 1 and 4, but it should not be a limitation to your answers.

How to check if variable contains valid UUID/GUID identifier?

I'm currently interested only in validating types 1 and 4, but it should not be a limitation to your answers.

Share Improve this question edited Jan 21, 2020 at 3:45 DeeZone 8308 silver badges16 bronze badges asked Oct 26, 2011 at 16:40 Marek SeberaMarek Sebera 40.6k37 gold badges164 silver badges248 bronze badges 3
  • in string format, not hex, not bin, or I don't know what do you ask for – Marek Sebera Commented Oct 26, 2011 at 16:44
  • If you cannot exclude variables containing a chain of 32 consecutive hex digits (without grouping), have a look at my answer – Wolf Commented Apr 20, 2015 at 8:38
  • Might be helpful: npmjs.com/package/uuid-validate – Ben Commented Jul 18, 2020 at 18:13
Add a comment  | 

19 Answers 19

Reset to default 605

Currently, UUID's are as specified in RFC4122. An often neglected edge case is the NIL UUID, noted here. The following regex takes this into account and will return a match for a NIL UUID. See below for a UUID which only accepts non-NIL UUIDs. Both of these solutions are for versions 1 to 5 (see the first character of the third block).

Therefore to validate a UUID...

/^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i

...ensures you have a canonically formatted UUID that is Version 1 through 5 and is the appropriate Variant as per RFC4122.

NOTE: Braces { and } are not canonical. They are an artifact of some systems and usages.

Easy to modify the above regex to meet the requirements of the original question.

HINT: regex group/captures

To avoid matching NIL UUID:

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

If you want to check or validate a specific UUID version, here are the corresponding regexes.

Note that the only difference is the version number, which is explained in 4.1.3. Version chapter of UUID 4122 RFC.

The version number is the first character of the third group : [VERSION_NUMBER][0-9A-F]{3} :

  • UUID v1 :

    /^[0-9A-F]{8}-[0-9A-F]{4}-[1][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
    
  • UUID v2 :

    /^[0-9A-F]{8}-[0-9A-F]{4}-[2][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
    
  • UUID v3 :

    /^[0-9A-F]{8}-[0-9A-F]{4}-[3][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
    
  • UUID v4 :

    /^[0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
    
  • UUID v5 :

    /^[0-9A-F]{8}-[0-9A-F]{4}-[5][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
    

regex to the rescue

/^[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}$/.test('01234567-9ABC-DEF0-1234-56789ABCDEF0');

or with brackets

/^\{?[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}‌​\}?$/

If you use the uuid package, this package brings a boolean validation function where it tells you if a uuid is valid or not.

Example:

import { validate as isValidUUID } from 'uuid';

if (!isValidUUID(tx.originId)) {
  return Promise.reject('Invalid OriginID');
}

If you are using Node.js for development, it is recommended to use a package called Validator. It includes all the regexes required to validate different versions of UUID's plus you get various other functions for validation.

Here is the npm link: Validator

var a = 'd3aa88e2-c754-41e0-8ba6-4198a34aa0a2'
v.isUUID(a)
true
v.isUUID('abc')
false
v.isNull(a)
false

thanks to @usertatha with some modification

function isUUID ( uuid ) {
    let s = "" + uuid;

    s = s.match('^[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}$');
    if (s === null) {
      return false;
    }
    return true;
}

Beside Gambol's answer that will do the job in nearly all cases, all answers given so far missed that the grouped formatting (8-4-4-4-12) is not mandatory to encode GUIDs in text. It's used extremely often but obviously also a plain chain of 32 hexadecimal digits can be valid.[1] regexenh:

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

[1] The question is about checking variables, so we should include the user-unfriendly form as well.

  • Why are there dashes in a .NET GUID? - Stack Overflow plus Accepted answer
  • Test and validate a GUID (guid.us)
  • Guid.ToString Method (String) (MSDN)

All type-specific regexes posted so far are failing on the "type 0" Nil UUID, defined in 4.1.7 of the RFC as:

The nil UUID is special form of UUID that is specified to have all 128 bits set to zero: 00000000-0000-0000-0000-000000000000

To modify Wolf's answer:

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

Or, to properly exclude a "type 0" without all zeros, we have the following (thanks to Luke):

/^(?:[0-9a-f]{8}-?[0-9a-f]{4}-?[1-5][0-9a-f]{3}-?[89ab][0-9a‌​-f]{3}-?[0-9a-f]{12}‌​|00000000-0000-0000-‌​0000-000000000000)$/‌​i

if you use the uuid package, you can import the validate and pass the id into it

const { v4: uuidv4, validate } = require('uuid');

const { id } = request.params;
validate(id) ? true : false;

If someone is using yup , JavaScript schema validator library, This functionality can be achieved with below code.

const schema = yup.object().shape({
   uuid: yup.string().uuid()
 });
 const isValid = schema.isValidSync({uuid:"string"});

A slightly modified version of the above answers written in a more concise way. This will validate any GUID with hyphens (however easily modified to make hyphens optional). This will also support upper and lower case characters which has become the convention regardless of the specification:

/^([0-9a-fA-F]{8})-(([0-9a-fA-F]{4}\-){3})([0-9a-fA-F]{12})$/i

The key here is the repeating part below

(([0-9a-fA-F]{4}\-){3})

Which simply repeats the 4 char patterns 3 times

I think Gambol's answer is almost perfect, but it misinterprets the RFC 4122 § 4.1.1. Variant section a bit.

It covers Variant-1 UUIDs (10xx = 8..b), but does not cover Variant-0 (0xxx = 0..7) and Variant-2 (110x = c..d) variants which are reserved for backward compatibility, so they are technically valid UUIDs. Variant-4 (111x = e..f) is indeed reserved for future use, so they are not valid currently.

Also, 0 type is not valid, that "digit" is only allowed to be 0 if it's a NIL UUID (like mentioned in Evan's answer).

So I think the most accurate regex that complies with current RFC 4122 specification is (including hyphens):

/^([0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[0-9a-d][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i
                            ^                ^^^^^^
                    (0 type is not valid)  (only e..f variant digit is invalid currently)

Versions 1 to 5, without using a multi-version regex when version is omitted.

const uuid_patterns = {
  1: /^[0-9A-F]{8}-[0-9A-F]{4}-1[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,
  2: /^[0-9A-F]{8}-[0-9A-F]{4}-2[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,
  3: /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,
  4: /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,
  5: /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
};

const isUUID = (input, version) => {    
    if(typeof input === "string"){
        if(Object.keys(uuid_patterns).includes(typeof version === "string" ? version : String(version))){
            return uuid_patterns[version].test(input);
        } else {
            return Object.values(uuid_patterns).some(pattern => pattern.test(input));
        }
    }
    return false;
}

// Testing
let valid = [
    'A987FBC9-4BED-3078-CF07-9141BA07C9F3',
    'A987FBC9-4BED-4078-8F07-9141BA07C9F3',
    'A987FBC9-4BED-5078-AF07-9141BA07C9F3',
];

let invalid = [
    '',
    'xxxA987FBC9-4BED-3078-CF07-9141BA07C9F3',
    'A987FBC9-4BED-3078-CF07-9141BA07C9F3xxx',
    'A987FBC94BED3078CF079141BA07C9F3',
    '934859',
    '987FBC9-4BED-3078-CF07A-9141BA07C9F3',
    'AAAAAAAA-1111-1111-AAAG-111111111111',
];

valid.forEach(test => console.log("Valid case, result: "+isUUID(test)));
invalid.forEach(test => console.log("Invalid case, result: "+isUUID(test)));

A good way to do it in Node is to use the ajv package (https://github.com/epoberezkin/ajv).

const Ajv = require('ajv');
const ajv = new Ajv({ allErrors: true, useDefaults: true, verbose: true });
const uuidSchema = { type: 'string', format: 'uuid' };
ajv.validate(uuidSchema, 'bogus'); // returns false
ajv.validate(uuidSchema, 'd42a8273-a4fe-4eb2-b4ee-c1fc57eb9865'); // returns true with v4 GUID
ajv.validate(uuidSchema, '892717ce-3bd8-11ea-b77f-2e728ce88125'); // returns true with a v1 GUID

I have this function, but it's essentially the same as the accepted answer.

export default function isUuid(uuid: string, isNullable: boolean = false): boolean {
    return isNullable
        ? /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(uuid)
        : /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(uuid);
}

Use the .match() method to check whether String is UUID.

public boolean isUUID(String s){
    return s.match("^[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}$");
}

Here is the easiest way to check if a string is a valid UUID in JavaScript

function isUUID(str) {
    return /^(?:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89AB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$/.test(str);
}

// Example usage:
const myId = "550e8400-e29b-41d4-a716-446655440000"; // Replace with your UUID
console.log(isUUID(myId)); // Output: true for UUID version 1

You can use class-validator with community support..

// IsUUID.d.ts
import { ValidationOptions } from '../ValidationOptions';
export type UUIDVersion = '3' | '4' | '5' | 'all' | 3 | 4 | 5;
export declare const IS_UUID = "isUuid";
/**
 * Checks if the string is a UUID (version 3, 4 or 5).
 * If given value is not a string, then it returns false.
 */
export declare function isUUID(value: unknown, version?: UUIDVersion): boolean;
/**
 * Checks if the string is a UUID (version 3, 4 or 5).
 * If given value is not a string, then it returns false.
 */
export declare function IsUUID(version?: UUIDVersion, validationOptions?: ValidationOptions): PropertyDecorator;

I think a better way is using the static method fromString to avoid those regular expressions.

    id = UUID.randomUUID();
    UUID uuid = UUID.fromString(id.toString());
    Assert.assertEquals(id.toString(), uuid.toString());

On the other hand

   UUID uuidFalse = UUID.fromString("x");

throws java.lang.IllegalArgumentException: Invalid UUID string: x

本文标签: javascriptHow to test valid UUIDGUIDStack Overflow