如何在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)。

其他回答

我想了解布罗法的答案,所以我扩展了它并添加了评论:

var uuid = function () {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(
        /[xy]/g,
        function (match) {
            /*
            * Create a random nibble. The two clever bits of this code:
            *
            * - Bitwise operations will truncate floating point numbers
            * - For a bitwise OR of any x, x | 0 = x
            *
            * So:
            *
            * Math.random * 16
            *
            * creates a random floating point number
            * between 0 (inclusive) and 16 (exclusive) and
            *
            * | 0
            *
            * truncates the floating point number into an integer.
            */
            var randomNibble = Math.random() * 16 | 0;

            /*
            * Resolves the variant field. If the variant field (delineated
            * as y in the initial string) is matched, the nibble must
            * match the mask (where x is a do-not-care bit):
            *
            * 10xx
            *
            * This is achieved by performing the following operations in
            * sequence (where x is an intermediate result):
            *
            * - x & 0x3, which is equivalent to x % 3
            * - x | 0x8, which is equivalent to x + 8
            *
            * This results in a nibble between 8 inclusive and 11 exclusive,
            * (or 1000 and 1011 in binary), all of which satisfy the variant
            * field mask above.
            */
            var nibble = (match == 'y') ?
                (randomNibble & 0x3 | 0x8) :
                randomNibble;

            /*
            * Ensure the nibble integer is encoded as base 16 (hexadecimal).
            */
            return nibble.toString(16);
        }
    );
};
var uuid = function() {
    var buf = new Uint32Array(4);
    window.crypto.getRandomValues(buf);
    var idx = -1;
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        idx++;
        var r = (buf[idx>>3] >> ((idx%8)*4))&15;
        var v = c == 'x' ? r : (r&0x3|0x8);
        return v.toString(16);
    });
};

这个版本是基于Briguy37的答案和一些Bitwise运营商从泡沫中提取Nibble大小的窗户。

它应该遵守RFC类型4(随机)方案,因为我上次遇到麻烦与Java的UUID不符合的UUID。

這裡是一個工作例子. 它生成一個 32 位數的獨特 UUID。

function generateUUID() {
    var d = new Date();
    var k = d.getTime();
    var str = k.toString(16).slice(1)
    var UUID = 'xxxx-xxxx-4xxx-yxxx-xzx'.replace(/[xy]/g, function (c)
    {
        var r = Math.random() * 16 | 0;
        v = c == 'x' ? r : (r & 3 | 8);
        return v.toString(16);
    });

    var newString = UUID.replace(/[z]/, str)
    return newString;
}

var x = generateUUID()
console.log(x, x.length)

原始 URL.createObjectURL 正在产生 UUID. 您可以利用此。

function uuid() {
  const url = URL.createObjectURL(new Blob())
  const [id] = url.toString().split('/').reverse()
  URL.revokeObjectURL(url)
  return id
}

最酷的方式:

function uuid(){
    var u = URL.createObjectURL(new Blob([""]))
    URL.revokeObjectURL(u);
    return u.split("/").slice(-1)[0]
}

它可能不是快速,高效,或支持在 IE2 但它肯定是酷的