简体   繁体   English

在客户端生成唯一 ID 的最佳方法(使用 Javascript)

[英]Best way to generate unique ids client-side (with Javascript)

I need to generate unique ids in the browser.我需要在浏览器中生成唯一的 ID。 Currently, I'm using this:目前,我正在使用这个:

Math.floor(Math.random() * 10000000000000001)

I'd like to use the current UNIX time ( (new Date).getTime() ), but I'm worried that if two clients generate ids at the exact same time, they wouldn't be unique.我想使用当前的UNIX时间( (new Date).getTime()但我担心,如果两个客户端产生的确切同时IDS,他们不会是唯一的。

Can I use the current UNIX time (I'd like to because that way ids would store more information)?我可以使用当前的 UNIX 时间吗(我想使用,因为那样 ids 会存储更多信息)? If not, what's the best way to do this (maybe UNIX time + 2 random digits?)如果不是,那么最好的方法是什么(也许是 UNIX 时间 + 2 个随机数字?)

you can create a GUID using the following links:您可以使用以下链接创建 GUID:

http://softwareas.com/guid0-a-javascript-guid-generator http://softwareas.com/guid0-a-javascript-guid-generator

Create GUID / UUID in JavaScript? 在 JavaScript 中创建 GUID/UUID?

This will maximise your chance of "uniqueness."这将最大限度地提高您获得“独特性”的机会。

Alternatively, if it is a secure page, you can concatenate the date/time with the username to prevent multiple simultaneous generated values.或者,如果它是一个安全页面,您可以将日期/时间与用户名连接起来,以防止同时生成多个值。

https://github.com/uuidjs/uuid provides RFC compliant UUIDs based on either timestamp or random #'s. https://github.com/uuidjs/uuid基于时间戳或随机 # 提供符合 RFC 的 UUID。 Single-file with no dependencies, supports timestamp or random #-based UUIDs, uses native APIs for crypto-quality random numbers if available, plus other goodies.没有依赖项的单个文件,支持时间戳或基于随机 # 的 UUID,使用本机 API 获取加密质量的随机数(如果可用),以及其他好东西。

In modern browser you can use crypto :在现代浏览器中,您可以使用crypto

var array = new Uint32Array(1);
window.crypto.getRandomValues(array);
console.log(array);
var c = 1;
function cuniq() {
    var d = new Date(),
        m = d.getMilliseconds() + "",
        u = ++d + m + (++c === 10000 ? (c = 1) : c);

    return u;
}

Here is my javascript code to generate guid.这是我生成 guid 的 javascript 代码。 It does quick hex mapping and very efficient:它可以快速进行十六进制映射并且非常高效:

AuthenticationContext.prototype._guid = function () {
    // RFC4122: The version 4 UUID is meant for generating UUIDs from truly-random or
    // pseudo-random numbers.
    // The algorithm is as follows:
    //     Set the two most significant bits (bits 6 and 7) of the
    //        clock_seq_hi_and_reserved to zero and one, respectively.
    //     Set the four most significant bits (bits 12 through 15) of the
    //        time_hi_and_version field to the 4-bit version number from
    //        Section 4.1.3. Version4 
    //     Set all the other bits to randomly (or pseudo-randomly) chosen
    //     values.
    // UUID                   = time-low "-" time-mid "-"time-high-and-version "-"clock-seq-reserved and low(2hexOctet)"-" node
    // time-low               = 4hexOctet
    // time-mid               = 2hexOctet
    // time-high-and-version  = 2hexOctet
    // clock-seq-and-reserved = hexOctet: 
    // clock-seq-low          = hexOctet
    // node                   = 6hexOctet
    // Format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
    // y could be 1000, 1001, 1010, 1011 since most significant two bits needs to be 10
    // y values are 8, 9, A, B
    var guidHolder = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
    var hex = '0123456789abcdef';
    var r = 0;
    var guidResponse = "";
    for (var i = 0; i < 36; i++) {
        if (guidHolder[i] !== '-' && guidHolder[i] !== '4') {
            // each x and y needs to be random
            r = Math.random() * 16 | 0;
        }

        if (guidHolder[i] === 'x') {
            guidResponse += hex[r];
        } else if (guidHolder[i] === 'y') {
            // clock-seq-and-reserved first hex is filtered and remaining hex values are random
            r &= 0x3; // bit and with 0011 to set pos 2 to zero ?0??
            r |= 0x8; // set pos 3 to 1 as 1???
            guidResponse += hex[r];
        } else {
            guidResponse += guidHolder[i];
        }
    }

    return guidResponse;
};

There are two ways to achieve this有两种方法可以实现这一点

  1. js const id = Date.now().toString()

While this does not guarantee uniqueness (When you are creating multiple objects within 1ms), this will work on a practical level, since it is usually not long before the objects on the client are sent to a real server.虽然这并不能保证唯一性(当您在 1 毫秒内创建多个对象时),这将在实用级别上起作用,因为通常不久之后客户端上的对象就会被发送到真实服务器。

  1. If you wanted to create multiple records withing 1ms, I suggest using the code below如果你想在 1ms 内创建多条记录,我建议使用下面的代码
const { randomBytes } = require("crypto");

// 32 Characters
const id = randomBytes(16).toString("hex");

It works similar to a uuid4 without needing to add an external library (Assuming you have access to NodeJs at some point)它的工作原理类似于 uuid4,无需添加外部库(假设您在某个时候可以访问 NodeJs)

You can always run a test against existing IDs in the set to accept or reject the generated random number recursively.您始终可以针对集合中的现有 ID 运行测试,以递归地接受或拒绝生成的随机数。

for example:例如:

const randomID = function(){
    let id = Math.floor(Math.random() * 10000000000000001) + new Date();

    if (idObjectArray.contains(id)) {
    randomID;
} else {
    idObjectArray.push(id);
}
};

This example assumes you would just be pushing the id into a 1D array, but you get the idea.此示例假设您只是将 id 推送到一维数组中,但您明白了。 There shouldn't be many collisions given the uniqueness of the random number with the date, so it should be efficient.鉴于随机数与日期的唯一性,不应该有很多冲突,所以它应该是有效的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM