11

I found the following Javascript function in another answer:

function createUUID() {
    var s = [];
    var hexDigits = "0123456789abcdef";

    for (var i = 0; i < 36; i++) {
        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
    }

    s[14] = "4";
    s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
    s[8] = s[13] = s[18] = s[23] = "-";

    var uuid = s.join("");
    return uuid;
}

This creates an RFC valid UUID/GUID in javascript.. What I want to know is if there is a way to validate the string once it arrives to the PHP side. I found a regex that would potentially validate everything roughly that format as true:

/^[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}$/

but using that as long as you specified a string of equal length and format it would pass validation.

Is there any way to add some sort of seed to the javascript function and then verify that in the PHP or if there was a way for PHP to validate the number that was passed matches with the correct format or something?

Any help is greatly appreciated.

miken32
  • 42,008
  • 16
  • 111
  • 154
Peter
  • 3,144
  • 11
  • 37
  • 56

4 Answers4

23

According to Wikipedia the format of UUID v4 is:

Version 4 UUIDs have the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx where x is any hexadecimal digit and y is one of 8, 9, A, or B. e.g. f47ac10b-58cc-4372-a567-0e02b2c3d479.

The corresponding regex is:

/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
AndreKR
  • 32,613
  • 18
  • 106
  • 168
  • My major question with this and maybe I don't need v4 UUID for this, if I were to take that string `f47ac10b-58cc-4372-a567-0e02b2c3d479` and change any 1 element so long as it's not the 4 or the 8,9,A or B in Character 20 does that still validate? It must I would imagine. I'm wondering if there is a way to seed it so it's still valid v4 UUID but server side I can still verify it's actually coming from my application. – Peter Oct 09 '12 at 21:36
  • It is completely random. If you are looking for public/private key signing describe your application in a new question, that has nothing to do with UUIDs. – AndreKR Oct 09 '12 at 23:53
  • Completely off topic but what/how would you suggest to do some sort of public/private key that can be transferred via http? – Peter Oct 10 '12 at 00:19
  • Depends on your application which you didn't describe. You could just send a password ("$eCrEt") to the client and then create an ID from that ("$eCrEt123456") which you can check then: `if (substr($_POST['id'], 0, 6) == $password) $id_ok = true;` – AndreKR Oct 10 '12 at 03:17
  • I use `'/^[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}$/'` for UUID validation – Eduard Brokan Aug 18 '21 at 11:17
  • @EduardBrokan Then you missed two restrictions, i.e. you get false-valid results. – AndreKR Aug 18 '21 at 11:23
8

I use regex validation along with string validation to check if the given string is in valid UUID format.

if (!is_string($uuid) || (preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/', $uuid) !== 1)) {
    return false;
}

You can see the full gist here.

Joel James
  • 1,315
  • 1
  • 20
  • 37
0

You should use regex. For this, you can use this quick regex:

/^[a-f\d]{8}(-[a-f\d]{4}){4}[a-f\d]{8}$/i

It ignore the case of chars, and works the same a some regex which are longer.

You can find full explaination here.

To use it, you can do:

if(is_string($uuid) && preg_match('/^[a-f\d]{8}(-[a-f\d]{4}){4}[a-f\d]{8}$/i', $uuid)) {
   // your code here
}
Elikill58
  • 4,050
  • 24
  • 23
  • 45
-1

I am using this function. I found the regex from github from the link on the comments. It also seems to be faster than many others.

/**
 * @link https://gist.github.com/Joel-James/3a6201861f12a7acf4f2?permalink_comment_id=3030120#gistcomment-3030120
 */
public static function isValidUUID(string $uuid): bool
{
    return preg_match('/^[a-f\d]{8}(-[a-f\d]{4}){4}[a-f\d]{8}$/i', $uuid) !== 1 ? false : true;
}
Firze
  • 3,939
  • 6
  • 48
  • 61
  • 1
    Please avoid answers that just state "I am using". You answer should contain an explanation, why exactly this solution must be used and what improvement it offers over the same solution offered in the other answer already – Your Common Sense Jun 07 '23 at 06:10