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

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


当前回答

不要使用 Math.random 在任何情况下,因为它产生一个非加密的随机数字来源。

下面的解决方案使用crypto.getRandomValues

function uuidv4() {
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
    // tslint:disable-next-line: no-bitwise
    const r =
      (window.crypto.getRandomValues(new Uint32Array(1))[0] *
        Math.pow(2, -32) * 16) |
      0;
    // tslint:disable-next-line: no-bitwise
    const v = c === "x" ? r : (r & 0x3) | 0x8;
    return v.toString(16);
  });
}

此链接有助于您了解由 Fortify Scanner 投下的不安全的随机性。

其他回答

这个应用程序的100万次执行只需要32.5秒,这是我从未在浏览器中看到的最快(唯一的解决方案没有漏洞/漏洞)。

/**
 * Generates a GUID string.
 * @returns {string} The generated GUID.
 * @example af8a8416-6e18-a307-bd9c-f2c947bbb3aa
 * @author Slavik Meltser.
 * @link http://slavik.meltser.info/?p=142
 */
function guid() {
    function _p8(s) {
        var p = (Math.random().toString(16)+"000000000").substr(2,8);
        return s ? "-" + p.substr(0,4) + "-" + p.substr(4,4) : p ;
    }
    return _p8() + _p8(true) + _p8(true) + _p8();
}

console.time('t');
for (var i = 0; i < 10000000; i++) {
    guid();
};
console.timeEnd('t');

算法:

Math.random() 函数返回 0 和 1 之间的十数数,在十数分数点(例如 0.4363923368509859 )之后有 16 个数字。 然后我们采取这个数字并将其转换为 16 个基线(从上面的示例中,我们将获得 0.6fb7687f)。 Math.random(.toString(16 ) 然后我们切断了 0 个预定(.0.6fb7687f => 6fb7687f ) 并获得八个六分数字符的序列。

链接到我的博客上的这篇文章

享受吧:)

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

它提供简单,快速的生成RFC4122 UUIDS。

特性:

创建 RFC4122 版本 1 或版本 4 UUIDs 在 Node.js 和浏览器中运行. 在支持平台上加密强大的随机 # 发行。


使用 NPM 安装:

npm install uuid

或者通过浏览器使用 uuid:

下载原始文件(uuid v1): https://raw.githubusercontent.com/kelektiv/node-uuid/master/v1.js 下载原始文件(uuid v4): https://raw.githubusercontent.com/kelektiv/node-uuid/master/v4.js


想要更小? 查看此: https://gist.github.com/jed/982883


使用:

// Generate a v1 UUID (time-based)
const uuidV1 = require('uuid/v1');
uuidV1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a'

// Generate a v4 UUID (random)
const uuidV4 = require('uuid/v4');
uuidV4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1'

// Generate a v5 UUID (namespace)
const uuidV5 = require('uuid/v5');

// ... using predefined DNS namespace (for domain names)
uuidV5('hello.example.com', v5.DNS)); // -> 'fdda765f-fc57-5604-a269-52a7df8164ec'

// ... using predefined URL namespace (for, well, URLs)
uuidV5('http://example.com/hello', v5.URL); // -> '3bbcee75-cecc-5b56-8031-b6641c1ed1f1'

// ... using a custom namespace
const MY_NAMESPACE = '(previously generated unique uuid string)';
uuidV5('hello', MY_NAMESPACE); // -> '90123e1c-7512-523e-bb28-76fab9f2f73d'

ECMAScript 2015(ES6):

import uuid from 'uuid/v4';
const id = uuid();

这里是一个类似的 RFC4122 版本 4 符合的解决方案,解决了这个问题,通过将第一个 13 个 hex 数字以一个 hex 部分的时光,并一旦被一个 hex 部分的微秒从 pageload. 因此,即使 Math.random 是相同的种子,两个客户将不得不产生 UUID 相同的数量的微秒从 pageload (如果高性能


const generateUUID = () => { let d = new Date().getTime(), d2 = ((typeof performance !== 'undefined') && performance.now && (performance.now() * 1000)) || 0; return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { let r = Math.random() * 16; if (d > 0) { r = (d + r) % 16 | 0; d = Math.floor(d / 16); } else { r = (d2 + r) % 16 | 0; d2 = Math.floor(d2 / 16); } return (c == 'x' ? r : (r & 0x7 | 0x8)).toString(16); }); }; const onClick = (e) => document.getElementById('uuid').textContent = generateUUID(); document.getElementById('generateUUID').addEventListener('click', onClick); onClick(); #uuid { font-family: monospace; font-size: 1.5em; } <p id="uuid"></p> <button id="generateUUID">Generate UUID</button>

這只是一個概念,大多數人肯定可以以多種方式改進,但並不像我認為那樣緩慢。

总的来说,这个代码包含在毫秒内编码的黑客时间表(有某些黑客它给了12个数字,所以代码甚至在2527-06-24,但不是在5138-11-16之后工作),这意味着它是可编码的。

我知道这可能会缩短,性能提高,但我对结果感到高兴(除了MAC地址)。

目前Nanoseconds = () => { return nodeMode? process.hrtime.bigint() : BigInt(Date.now() * 1000000); } nodeFindMacAddress = () => { // 提取 MAC 地址 const 界面 = require('os').network 界面(); let result = null; for (index in interfaces) { let entry = interfaces[index]; entry.forEach(item => { if (item.mac!== '00:00:00:00:00:00') { result = '-'