如何在JavaScript中创建GUID(全球独特识别器)?GUID/UUID应该至少有32个字符,并且应该保持在ASCII范围内,以避免在通过它们时遇到麻烦。

我不确定在所有浏览器上有哪些习惯,如何“随机”和种植内置的随机号码发电机等。


当前回答

事实上,在非Microsoft 循环中称之为 GUID 或 UUID,只是一个 128 位数码的随机数字,而 UUID 版本号(1-5)则位于固定位置比特。

因此,当你只是在0和65535之间创建一个随机数字的集合,并编码它们时,如下:

function guid()
{
    function s4()
    {
        return Math.floor(Math.random() * 65536).toString(16).padStart(4, '0')
    } // End Function s4

    return s4() + s4() + '-' + s4() + '-' + "4" + s4().substr(1) + '-' + s4() + '-' + s4() + s4() + s4();
} // End Function guid

您可以获得有效的 GUID,但由于随机实施,它不是加密安全的。

要创建一个加密安全的 GUID,您需要使用 window.crypto (或 window.msCrypto for Internet Explorer)。

这就是这样:

function cryptGuid()
{
    var array = new Uint16Array(8);
    (window.crypto || window.msCrypto).getRandomValues(array);
    var dataView = new DataView(array.buffer);

    var parts = [];

    for(var i = 0; i < array.length; ++i)
    {
        // 0&1,2,3,4,5-7 dataView.getUint16(0-7)
        if(i>1 && i<6) parts.push("-");
        parts.push(dataView.getUint16(i).toString(16).padStart(4, '0'));
    }

    parts[5] = "4" + parts[5].substr(1);
    // console.log(parts);
    return parts.join('').toUpperCase();// .toLowerCase();
}

cryptGuid();

此外,您还需要决定,如果您将数字返回为下或上案字符串,某些软件需要下案字符(例如,报告服务),而其他则会产生上案字符(SQL Server)。

其他回答

这里是一个方法,使用真实的随机通过 random.org 生成 RFC4122 如果错误,它会回到浏览器的内置加密图书馆,这应该几乎是相同的好。

async function UUID() {
    //get 31 random hex characters
    return (await (async () => {
        let output;
        try {
            //try from random.org
            output = (await (
                await fetch('https://www.random.org/integers/?num=31&min=0&max=15&col=31&base=16&format=plain&rnd=new')
            ).text())
                //get rid of whitespace
                .replace(/[^0-9a-fA-F]+/g, '')
            ;
            if (output.length != 31)
                throw '';
        }
        catch {
            output = '';
            try {
                //failing that, try getting 16 8-bit digits from crypto
                for (let num of crypto.getRandomValues(new Uint8Array(16)))
                    //interpret as 32 4-bit hex numbers
                    output += (num >> 4).toString(16) + (num & 15).toString(16);
                //we only want 31
                output = output.substr(1);
            }
            catch {
                //failing THAT, use Math.random
                while (output.length < 31)
                    output += (0 | Math.random() * 16).toString(16);
            }
        }
        return output;
    })())
        //split into appropriate sections, and set the 15th character to 4
        .replace(/^(.{8})(.{4})(.{3})(.{4})/, '$1-$2-4$3-$4-')
        //force character 20 to the correct range
        .replace(/(?<=-)[^89abAB](?=[^-]+-[^-]+$)/, (num) => (
            (parseInt(num, 16) % 4 + 8).toString(16)
        ))
    ;
}

此分類上一篇

下面是顶级投票答案的组合,与Chrome的冲突工作组合:

generateGUID = (typeof(window.crypto) != 'undefined' &&
                typeof(window.crypto.getRandomValues) != 'undefined') ?
    function() {
        // If we have a cryptographically secure PRNG, use that
        // https://stackoverflow.com/questions/6906916/collisions-when-generating-uuids-in-javascript
        var buf = new Uint16Array(8);
        window.crypto.getRandomValues(buf);
        var S4 = function(num) {
            var ret = num.toString(16);
            while(ret.length < 4){
                ret = "0"+ret;
            }
            return ret;
        };
        return (S4(buf[0])+S4(buf[1])+"-"+S4(buf[2])+"-"+S4(buf[3])+"-"+S4(buf[4])+"-"+S4(buf[5])+S4(buf[6])+S4(buf[7]));
    }

    :

    function() {
        // Otherwise, just use Math.random
        // https://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
        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);
        });
    };

这是在Jsbin,如果你想测试它。

根據 RFC 4122 的 UUID (Universally Unique IDentifier),也被稱為 GUID (Globally Unique IDentifier),是為提供某些獨特性保證而設計的識別。

虽然可以在JavaScript代码的几个行中实施符合RFC的UUID(例如,请参见 @broofa的答案,下面),但有几个常见的漏洞:

无效 ID 格式(UUID 必须是“xxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx”的格式,其中 x 是 [0-9, a-f] M 是 [1-5] 的格式,而 N 是 [8, 9, a 或 b] 使用低质量的随机性来源(如 Math.random)

因此,开发人员为生产环境编写代码被鼓励使用严格,良好的实施,如新模块。

对于我的使用案例,我需要 ID 世代,保证在全球范围内是独一无二的;没有例外.我与问题斗争了一段时间,并提出了一个名为 TUID (真正独一无二的 ID ) 的解决方案。

这创建了一个版本 4 UUID (创建于假冒随机数字):

function uuid()
{
   var chars = '0123456789abcdef'.split('');

   var uuid = [], rnd = Math.random, r;
   uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
   uuid[14] = '4'; // version 4

   for (var i = 0; i < 36; i++)
   {
      if (!uuid[i])
      {
         r = 0 | rnd()*16;

         uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r & 0xf];
      }
   }

   return uuid.join('');
}

下面是产生的 UUID 的样本:

682db637-0f31-4847-9cdf-25ba9613a75c
97d19478-3ab2-4aa1-b8cc-a1c3540f54aa
2eed04c9-2692-456d-a0fd-51012f947136