90

Does anyone know of a good, solid, implementation of C# like GUID (UUID) in TypeScript?

Could do it myself but figured I'd spare my time if someone else done it before.

BuZZ-dEE
  • 6,075
  • 12
  • 66
  • 96
Gustav
  • 3,408
  • 4
  • 24
  • 41

2 Answers2

206

Updated Answer

This is now something you can do natively in JavaScript/TypeScript with crypto.randomUUID().

Here's an example generating 20 UUIDs.

for (let i = 0; i < 20; i++) {
    let id = crypto.randomUUID();
    console.log(id);
}

Original Answer

There is an implementation in my TypeScript utilities based on JavaScript GUID generators.

Here is the code:

class Guid {
  static newGuid() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
      var r = Math.random() * 16 | 0,
        v = c == 'x' ? r : (r & 0x3 | 0x8);
      return v.toString(16);
    });
  }
}

// Example of a bunch of GUIDs
for (var i = 0; i < 20; i++) {
  var id = Guid.newGuid();
  console.log(id);
}

Please note the following:

C# GUIDs are guaranteed to be unique. This solution is very likely to be unique. There is a huge gap between "very likely" and "guaranteed" and you don't want to fall through this gap.

JavaScript-generated GUIDs are great to use as a temporary key that you use while waiting for a server to respond, but I wouldn't necessarily trust them as the primary key in a database. If you are going to rely on a JavaScript-generated GUID, I would be tempted to check a register each time a GUID is created to ensure you haven't got a duplicate (an issue that has come up in the Chrome browser in some cases).

Fenton
  • 241,084
  • 71
  • 387
  • 401
  • 9
    Why are you generating GUIDs with the first character of the 3rd group always '4'? – Paul Gorbas Jun 16 '16 at 19:23
  • 31
    @PaulGorbas See https://en.wikipedia.org/wiki/Globally_unique_identifier - this 4 indicates a kind of GUID version. The 4 indicates it is not MAC-address bases but pseudo-random and might not be cryptographically safe. – ZoolWay Jul 15 '16 at 15:47
  • 9
    "C# GUIDs" are no more or no less unique than the ones produced by your function. A collision is so extremely unlikely that you can absolutely rely on their uniqueness. You can of course use it as a primary key and checking a registry is not helpful. This implementation is not cryptographically secure, though. So values may be predictable. But that's not a problem of uniqueness. – R2C2 Oct 16 '16 at 15:01
  • 2
    Note to potential editors of this answer: https://meta.stackoverflow.com/questions/260245/when-should-i-make-edits-to-code – Fenton Jun 07 '17 at 07:11
  • 1
    If you are using tslint and it complains about the bitwise operators https://stackoverflow.com/questions/34578677/how-to-ignore-a-particular-directory-or-file-for-tslint/46449169#46449169 check that. – DeadlyChambers Sep 27 '17 at 14:16
  • If you are using tslint, you can also just add braces around (r&0x3)|0x8 – Michiel Cornille Jun 13 '19 at 12:15
  • Not sure why but I ran jasmine test of let guid1=makeGuid(); let guid2=makeGuid(); and the two were the same. it changes in each Jasmine test, but not on each run. – GGizmos Dec 15 '19 at 03:41
  • one reason of collision is when GUIDs are generated from different machines at the same time. Mac based GUIDs avoids collisions in those cases – Code Name Jack Apr 05 '20 at 22:10
  • This answer seems incomplete: the OP asked for a C# like class which should contain implementations such as `Empty` and `TryParse`. – ctaleck Jan 06 '21 at 17:15
  • The Updated Answer only works in secure browser contexts. – C.M. Feb 12 '23 at 02:56
15

I found this https://typescriptbcl.codeplex.com/SourceControl/latest

here is the Guid version they have in case the link does not work later.

module System {
    export class Guid {
        constructor (public guid: string) {
            this._guid = guid;
        }

        private _guid: string;

        public ToString(): string {
            return this.guid;
        }

        // Static member
        static MakeNew(): Guid {
            var result: string;
            var i: string;
            var j: number;

            result = "";
            for (j = 0; j < 32; j++) {
                if (j == 8 || j == 12 || j == 16 || j == 20)
                    result = result + '-';
                i = Math.floor(Math.random() * 16).toString(16).toUpperCase();
                result = result + i;
            }
            return new Guid(result);
        }
    }
}
Peter Lillevold
  • 33,668
  • 7
  • 97
  • 131
dburmeister
  • 540
  • 5
  • 6
  • 5
    Sadly this one doesn't set the mandatory bit patters for random UUID's, the first digit in the third segment must be 4, that's the UUID version number, and the first digit in the fourth segment must use the bitmask 10xx, meaning only the values 8, 9, A and B are allowed in that position. Wiki URL: https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_.28random.29 – A.Grandt May 25 '16 at 15:36
  • 3
    +1 for pasting in the source code, because the link to that site no longer has any typescript files and the JS files they do host does not look like the code you posted. – Paul Gorbas Jun 16 '16 at 19:31
  • @PaulGorbas it does. I added the link for completeness – Peter Lillevold Mar 23 '17 at 14:22