62

I'm working on a web service which requires a new GUID() passed as a reference to a method within the service.

I am not familiar with C# or the GUID() object, but require something similar for PHP (so create a new object which from my understanding returns an empty/blank GUID).

Any ideas?

Rajan
  • 199
  • 1
  • 5
  • 20
mauzilla
  • 3,574
  • 10
  • 50
  • 86
  • http://php.net/manual/en/function.uniqid.php – Realitätsverlust Feb 10 '14 at 07:22
  • (Note: Guid.NewGuid in .NET generates a UUIDv4.) – user2864740 Feb 10 '14 at 07:23
  • @YUNOWORK Usually better to link the non-localized ref. – user2864740 Feb 10 '14 at 07:24
  • Aaaah crap ... i just googled and copied the link, but i automatically get the german page, sry. – Realitätsverlust Feb 10 '14 at 07:26
  • check http://stackoverflow.com/questions/2040240/php-function-to-generate-v4-uuid – Damith Feb 10 '14 at 07:27
  • From my understanding new guid() within C# would return an object which returns a blank (00000000-0000-0000-000000000000) GUID from the constructor. As I have never seen the C# class/object I don't know what the procedures are to "replicate" a similiar class to have the same properties and methods which from what I can see the web service requires. Hence I more need to get a PHP equivalent of the C# new guid() method as appose to knowing to create it. Hope it makes sense? – mauzilla Feb 10 '14 at 08:35
  • 1
    Do not reinvent the wheel, just use https://github.com/ramsey/uuid. – localheinz Jul 01 '17 at 08:34

8 Answers8

82

You can try the following:

function GUID()
{
    if (function_exists('com_create_guid') === true)
    {
        return trim(com_create_guid(), '{}');
    }

    return sprintf('%04X%04X-%04X-%04X-%04X-%04X%04X%04X', mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(16384, 20479), mt_rand(32768, 49151), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535));
}

Source - com_create_guid

Michel Ayres
  • 5,891
  • 10
  • 63
  • 97
  • 4
    @MuhammadNaderi Why? The `function_exists` check is there specifically so that if `com_create_guid` is available (i.e. on Windows) the code uses that, but otherwise it falls back to the `sprintf` below on non-Windows systems, which should still work fine. – Matt Gibson Oct 18 '16 at 19:52
  • 3
    As far as I know, `mt_rand()` does not promise a unique value, so on non windows based systems, this might generate a GUID formatted string, but it is not promised to be Globally Unique. – Muhammad Naderi Oct 19 '16 at 06:01
  • @MuhammadNaderi As long as this implements the same underlying algorithm that the `come_create_guid()` function uses, it's sufficient enough. And you'd better use `mt_srand()` than `rand()`. But a call to `mt_srand()` may help. – Adam Oct 19 '16 at 07:49
  • 1
    Note that generating uuid's with `mt_rand()` is not nearly as unique as it seems to be. For a given seed, the resulting uuid will always the same. Therefore you will only get `mt_getrandmax()` different uid's - still a very big number, but only a tiny fraction of the uniqueness a better algorithm would produce. – Jerry Aug 20 '20 at 22:13
30

As an alternative to the above options:

$guid = bin2hex(openssl_random_pseudo_bytes(16));

It gives a string like 412ab7489d8b332b17a2ae127058f4eb

Alexey
  • 1,521
  • 1
  • 13
  • 24
10
<?php
function guid(){
if (function_exists('com_create_guid') === true)
    return trim(com_create_guid(), '{}');

$data = openssl_random_pseudo_bytes(16);
$data[6] = chr(ord($data[6]) & 0x0f | 0x40);
$data[8] = chr(ord($data[8]) & 0x3f | 0x80);
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}
?>

GUID Generator

user8240385
  • 101
  • 1
  • 2
7

According to Is there any difference between a GUID and a UUID?

GUID is Microsoft's implementation of the UUID standard.

So, here's a link to libraries, that let's you create UUIDs of the following types:

  • version 1 (time-based)
  • version 3 (name-based and hashed with MD5)
  • version 4 (random)
  • version 5 (name-based and hashed with SHA1)

https://github.com/search?p=1&q=uuid+php&ref=cmdform&type=Repositories

I don't know exactly, which one C# is using, but that's at least something you can use if you're writing some piece of software and want to have universal unique identifiers.

My perfered choice was https://github.com/fredriklindberg/class.uuid.php because it is just a simple PHP file and the most rated one (https://github.com/ramsey/uuid) had to much dependencies on other libraries, but his may change soon (see https://github.com/ramsey/uuid/issues/20).

But if you really need a GUID (according to the Microsoft standard), they have a different generation process than these 4122. Wikipedia claims that

GUIDs and RFC 4122 UUIDs should be identical when displayed textually

http://en.wikipedia.org/wiki/Globally_Unique_Identifier#Binary_encoding

In most cases, you should be fine by going for one of the PHP libs for UUIDs. I don't think you're meddling with Microsoft Component Object Model (COM), don't you?

Community
  • 1
  • 1
SimonSimCity
  • 6,415
  • 3
  • 39
  • 52
  • Hi Simon, thank you for your answer. I can confirm that the soap method call requires a reference to a new Guid() from ASP. The service will then verify credentials and then create a new GUID (I think the method is called new_guid() within the Guid() object which is then captured on both ends. With this said I am not sure how to approach this as (and I might be wrong) even if I recreate the Guid() object and send it along as a reference (possibly through tostring) their service would not be able to work with the PHP object (they use sharepoint). Any ideas? – mauzilla Feb 10 '14 at 15:45
  • Please explain why this got voted down.. I want to do better next time! – SimonSimCity Nov 15 '16 at 05:47
5

For googlers such as my self, I found this snipet more accurate:

function getGUID(){
    if (function_exists('com_create_guid')){
        return com_create_guid();
    }else{
        mt_srand((double)microtime()*10000);//optional for php 4.2.0 and up.
        $charid = strtoupper(md5(uniqid(rand(), true)));
        $hyphen = chr(45);// "-"
        $uuid = chr(123)// "{"
            .substr($charid, 0, 8).$hyphen
            .substr($charid, 8, 4).$hyphen
            .substr($charid,12, 4).$hyphen
            .substr($charid,16, 4).$hyphen
            .substr($charid,20,12)
            .chr(125);// "}"
        return $uuid;
    }
}

source http://guid.us/GUID/PHP

Muhammad Naderi
  • 3,090
  • 3
  • 24
  • 37
3

If you just need a very unique ID:

$uid = dechex( microtime(true) * 1000 ) . bin2hex( random_bytes(8) );

If ID's are generated more than 1 millisecond apart, they are 100% unique.

If two ID's are generated at shorter intervals, this would generate ID's that are 99.999999999999999999% likely to be globally unique (collision in 1 of 10^18)

You can increase this number by adding more digits, but to generate 100% unique ID's you will need to use a global counter.

if you really do need RFC compliance, this will pass as a valid version 4 GUID:

$guid = vsprintf('%s%s-%s-4000-8%.3s-%s%s%s0',str_split(dechex( microtime(true) * 1000 ) . bin2hex( random_bytes(8) ),4));

This follows the intention, but not the letter of the RFC. Among other discrepancies it's a few random digits short. (Add more random digits if you need it) The upside is that this is fast, compared to 100% compliant code. You can test your GUID here

Simon Rigét
  • 2,757
  • 5
  • 30
  • 33
  • second method you provided generates invalid GUIDs. I think there is an extra zero (0) character at the end of formatting part. – spetsnaz May 18 '20 at 15:23
  • it seems to work for me, tested with freecodeformat.com: Valid, The UUID is 1722f150-812e-4000-8287-bc4c73c3e8c0, It is UUID Version 4. Do you have an example? – Simon Rigét May 19 '20 at 22:39
1

You may have a look at this library to simply create a GUID that is compatible with Microsoft (C#) GUID: https://github.com/semiorbit/guid

To install: (No dependencies or requirements)

composer require semiorbit/guid

Then in your code:

use SemiorbitGuid\Guid;

echo Guid::NewGuid();

// OUTPUT:
// {6BE33503-D448-0264-11AC-38822224B694}

You can also create GUID without braces or dashes, by defining parameters:

Guid::NewGuid(string $separator = '-', bool $enclose = true) : string

Hope that would be helpful.

0

you can use this function if need to generate custom GIUD

public static function geterateGUID()
        {
            $hyphen = chr(45);
            $part_1 = self::take("0123456789abcdef", 8);
            $part_2 = self::take("0123456789abcdef", 4);
            $part_3 = self::take("12345", 1) . self::take("0123456789abcdef", 3);
            $part_4 = self::take("89ab", 1) . self::take("0123456789abcdef", 3);
            $part_5 = self::take("0123456789abcdef", 12);
    
            return $part_1 . $hyphen . $part_2 . $hyphen . $part_3 . $hyphen . $part_4 . $hyphen . $part_5;
        }
    
        public static function take($string, $len)
        {
            $random_string = "";
    
            for ($i = 0; $i < $len; $i++) {
                $random_string[$i] = $string[rand(0, strlen($string) - 1)];
            }
    
            return $random_string;
        }