Bagaimana cara menguji UUID / GUID yang valid?

270

Bagaimana cara memeriksa apakah variabel berisi pengidentifikasi UUID / GUID yang valid?

Saat ini saya hanya tertarik untuk memvalidasi tipe 1 dan 4, tetapi seharusnya tidak menjadi batasan untuk jawaban Anda.

Marek Sebera
sumber
dalam format string, bukan hex, bukan bin, atau saya tidak tahu apa yang Anda minta
Marek Sebera
^ (\ {) {0,1} [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} (\}) {0,1} $
Brandon Moretz
Jika Anda tidak dapat mengecualikan variabel yang berisi rantai 32 digit hex berturut-turut (tanpa pengelompokan), lihat jawaban saya
Wolf

Jawaban:

413

Saat ini, UUID adalah sebagaimana ditentukan dalam RFC4122. Kasus tepi yang sering diabaikan adalah UUID NIL, yang disebutkan di sini . Regex berikut mempertimbangkan ini dan akan mengembalikan kecocokan untuk UUID NIL. Lihat di bawah ini untuk UUID yang hanya menerima UUID non-NIL. Kedua solusi ini adalah untuk versi 1 hingga 5 (lihat karakter pertama dari blok ketiga).

Karena itu untuk memvalidasi 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

... memastikan Anda memiliki UUID yang diformat kanonik yaitu Versi 1 hingga 5 dan merupakan Varian yang sesuai sesuai RFC4122.

CATATAN: Kawat gigi {dan }bukan kanonik. Mereka adalah artefak dari beberapa sistem dan penggunaan.

Mudah untuk memodifikasi regex di atas untuk memenuhi persyaratan pertanyaan aslinya.

PETUNJUK: regex grup / tangkapan

Untuk menghindari pencocokan 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
Lompat
sumber
9
+1 Untuk menyebutkan Satuan Tugas Rekayasa Internet (IETF)
mate64
1
Saya pikir [1-5] [0-9a-f] {3} salah. Saya memiliki UUID yang valid yang memiliki "b06a" di bagian itu, dan ini gagal bagi saya.
Felipe Brahm
1
@FelipeBrahm, [1-5] benar menurut RFC, bahwa 4 bit menunjukkan versi, dan hanya ada 5 versi.
rvignacio
749d0000-0194-1005-2e05-08d61613bf2f gagal untuk saya dalam biola
merampas
1
Karena penasaran, (mengapa) tidak akan hal berikut ini berlaku juga: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
tjeerdnet
58

regex untuk menyelamatkan

/^[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');

atau dengan kurung

/^\{?[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}‌​\}?$/
ryanb
sumber
3
atau jika Anda mungkin memiliki tanda kurung: / ^ \ {? [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');
ryanb
Ini tidak sepenuhnya benar. ia melewatkan bahwa [1-5] (versi) memulai blok ke-3 dan [89AB] (varian) memulai blok ke-4. Jawaban Gambol benar.
Wolf
7
Versi yang lebih ringkas (mengabaikan kurung):/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/i
c24w
41

Jika Anda ingin memeriksa atau memvalidasi versi UUID tertentu, berikut adalah regex yang sesuai.

Perhatikan bahwa satu-satunya perbedaan adalah nomor versi , yang dijelaskan dalam 4.1.3. Versionbab UUID 4122 RFC .

Nomor versi adalah karakter pertama dari grup ketiga [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
Ivan Gabriele
sumber
39

Jika Anda menggunakan Node.js untuk pengembangan, disarankan untuk menggunakan paket yang disebut Validator. Ini mencakup semua regex yang diperlukan untuk memvalidasi versi berbeda dari UUID plus Anda mendapatkan berbagai fungsi lainnya untuk validasi.

Inilah tautan npm: Validator

var a = 'd3aa88e2-c754-41e0-8ba6-4198a34aa0a2'
v.isUUID(a)
true
v.isUUID('abc')
false
v.isNull(a)
false
Neeraj Sharma
sumber
Menarik, tetapi sepertinya ia mengharapkan tanda hubung? Berikut adalah empat regex yang saat ini digunakan - /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i dan / atau /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i dan / atau /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i dan / atau /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
ruffin
1
Validator hanya mendukung UUID v3-5 bukan v1
peteb
13

Selain jawaban Gambol yang akan melakukan pekerjaan dalam hampir semua kasus , semua jawaban yang diberikan sejauh ini terlewatkan sehingga pemformatan yang dikelompokkan (8-4-4-4-12) tidak wajib untuk menyandikan GUID dalam teks . Ini digunakan sangat sering tetapi jelas juga rantai polos 32 digit heksadesimal dapat valid. [1] peningkatan regex :

/^[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] Pertanyaannya adalah tentang cek ing variabel s, jadi kami harus mencakup bentuk tidak ramah-pengguna juga.

Serigala
sumber
Yang ini adalah fave saya. Bahkan lebih baik{?[0-9a-f]{8}-?[0-9a-f]{4}-?[1-5][0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}}?
mike nelson
10

Semua regex spesifik tipe yang diposting sejauh ini gagal pada UUID "tipe 0", didefinisikan dalam 4.1.7 dari RFC sebagai:

NIL UUID adalah bentuk khusus UUID yang ditentukan untuk mengatur semua 128 bit menjadi nol: 00000000-0000-0000-0000-000000000000

Untuk memodifikasi jawaban Wolf:

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

Atau, untuk mengecualikan "tipe 0" dengan benar tanpa semua nol, kami memiliki yang berikut (terima kasih kepada 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
Evan Edwards
sumber
Segmen UUID pertama dari nihil UUID harus memiliki 8 nol, bukan 7. Regex yang disediakan tidak memvalidasinya dengan 7.
Rich Seviora
2
Anda terlihat lebih baik tetapi memungkinkan beberapa UUID yang tidak valid, misalnya: abcdef00-0000-0000-0000-000000000000 akan cocok dengan regex Anda. Regex ini akan cocok dengan UUID yang valid, termasuk nol:/^(?:[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
Luke
10

terima kasih kepada @usertatha dengan beberapa modifikasi

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;
}
Souhaieb
sumber
2

Saya pikir jawaban Gambol hampir sempurna, tetapi salah mengartikan RFC 4122 § 4.1.1. Bagian varian sedikit.

Ini mencakup Varian-1 UUIDs (10xx = 8..b), tetapi tidak mencakup Varian-0 (0xxx = 0..7) dan varian Varian-2 (110x = c..d) yang dicadangkan untuk kompatibilitas ke belakang, jadi itu adalah UUID yang secara teknis valid. Varian-4 (111x = e..f) memang disediakan untuk penggunaan di masa mendatang, sehingga saat ini tidak valid.

Juga, 0 type tidak valid, "digit" itu hanya boleh 0 jika itu NIL UUID (seperti disebutkan dalam jawaban Evan ).

Jadi saya pikir regex paling akurat yang sesuai dengan spesifikasi RFC 4122 saat ini adalah (termasuk tanda hubung):

/^([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)
B. Zoli
sumber
1

Gunakan metode .match () untuk memeriksa apakah String adalah 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}$");
}
userTatha
sumber
Uncaught TypeError: s.matches bukan fungsi
Deep Kakkar
1
Skrip yang diberikan bukan Javascript, yang diminta OP.
StefanJanssen
Jawaban yang disesuaikan dengan alamat komentar di atas. Solusi sekarang berfungsi seperti yang diharapkan.
DeeZone
Itu masih bukan js.
ktilcu
1

Versi yang sedikit dimodifikasi dari jawaban di atas ditulis dengan cara yang lebih ringkas. Ini akan memvalidasi GUID apa pun dengan tanda hubung (namun mudah dimodifikasi untuk menjadikan tanda hubung opsional). Ini juga akan mendukung karakter huruf besar dan kecil yang telah menjadi konvensi terlepas dari spesifikasinya:

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

Kuncinya di sini adalah bagian berulang di bawah ini

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

Yang hanya mengulangi pola 4 char 3 kali

James Morrison
sumber
1
A-fharus A-Fseperti itu:/^([0-9a-fA-F]{8})-(([0-9a-fA-F]{4}\-){3})([0-9a-fA-F]{12})$/i
DeeZone
jika Anda membawa case (/ i), mengapa mengulang af dan AF?
Nimrod
0

Cara yang baik untuk melakukannya di Node adalah dengan menggunakan ajvpaket ( https://github.com/epoberezkin/ajv ).

const Ajv = require('ajv');
const ajv = new Ajv({ allErrors: true, useDefault: 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
blackcatweb
sumber
-1

Saya pikir cara yang lebih baik adalah menggunakan metode statis dari Strtring untuk menghindari ekspresi reguler itu.

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

Di samping itu

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

throws java.lang.IllegalArgumentException: String UUID tidak valid: x

Werner Diwischek
sumber