web-dev-qa-db-ja.com

JavaScript時間で一意の番号を作成する

JavaScriptを使用してその場で一意のID番号を生成する必要があります。過去には、時間を使用して数値を作成することでこれを行ってきました。数字は、4桁の年、2桁の月、2桁の日、2桁の時間、2桁の分、2桁の秒、3桁のミリ秒で構成されます。したがって、次のようになります。20111104103912732...これは、私の目的にとって一意の番号の十分な確実性を提供します。

私がこれを行ってからしばらく経ちましたが、もうコードを持っていません。誰でもこれを行うコードを持っていますか、一意のIDを生成するためのより良い提案がありますか?

85
Nick Petrie

一意のような番号が必要な場合は、

var timestamp = new Date().getUTCMilliseconds();

簡単な番号を取得します。ただし、読み取り可能なバージョンが必要な場合は、少し処理を行います。

var now = new Date();

timestamp = now.getFullYear().toString(); // 2011
timestamp += (now.getFullMonth < 9 ? '0' : '') + now.getFullMonth().toString(); // JS months are 0-based, so +1 and pad with 0's
timestamp += (now.getDate < 10) ? '0' : '') + now.getDate().toString(); // pad with a 0
... etc... with .getHours(), getMinutes(), getSeconds(), getMilliseconds()
56
Marc B

より良いアプローチは次のとおりです。

new Date().valueOf();

の代わりに

new Date().getUTCMilliseconds();

valueOf()は「最も可能性が高い」一意の番号です。 http://www.w3schools.com/jsref/jsref_valueof_date.asp

99
3lRicko

あなたが考えることができる多くの別々のインスタンスの中で一意であると確信できる数を作成する最短の方法は

Date.now() + Math.random()

関数呼び出しに1ミリ秒の差がある場合、100%が異なる数値を生成することが保証されます。同じミリ秒内での関数呼び出しでは、この同じミリ秒内で数百万を超える数を作成する場合にのみ、心配する必要があります。

同じミリ秒以内に繰り返し数を取得する確率の詳細については、 https://stackoverflow.com/a/28220928/4617597 を参照してください

47

これは、次のコードで簡単に実現できます。

var date = new Date();
var components = [
    date.getYear(),
    date.getMonth(),
    date.getDate(),
    date.getHours(),
    date.getMinutes(),
    date.getSeconds(),
    date.getMilliseconds()
];

var id = components.join("");
22
August Lilleaas

これは、Dateインスタンスを作成するよりも高速に実行され、使用するコードが少なく、alwaysが一意の番号を生成します(ローカル):

function uniqueNumber() {
    var date = Date.now();

    // If created at same millisecond as previous
    if (date <= uniqueNumber.previous) {
        date = ++uniqueNumber.previous;
    } else {
        uniqueNumber.previous = date;
    }

    return date;
}

uniqueNumber.previous = 0;

jsfiddle: http://jsfiddle.net/j8aLocan/

Bowerとnpmでこれをリリースしました: https://github.com/stevenvachon/unique-number

cuidpuid 、または shortid などのより複雑なものを使用して、非数値を生成することもできます。

15
Steven Vachon

数字の束よりも小さなものが必要なときは、次のようにします-ベースを変更します。

var uid = (new Date().getTime()).toString(36)
15
frumbert

私が使う

Math.floor(new Date().valueOf() * Math.random())

そのため、万が一コードが同時に実行された場合、乱数が同じになる可能性もあります。

12
BaleineBleue

これはすべきです:

var uniqueNumber = new Date().getTime(); // milliseconds since 1st Jan. 1970
4
FacePalm

オンライン調査から、セッションごとに一意のIDを作成する次のオブジェクトを思い付きました。

        window.mwUnique ={
        prevTimeId : 0,
        prevUniqueId : 0,
        getUniqueID : function(){
            try {
                var d=new Date();
                var newUniqueId = d.getTime();
                if (newUniqueId == mwUnique.prevTimeId)
                    mwUnique.prevUniqueId = mwUnique.prevUniqueId + 1;
                else {
                    mwUnique.prevTimeId = newUniqueId;
                    mwUnique.prevUniqueId = 0;
                }
                newUniqueId = newUniqueId + '' + mwUnique.prevUniqueId;
                return newUniqueId;                     
            }
            catch(e) {
                mwTool.logError('mwUnique.getUniqueID error:' + e.message + '.');
            }
        }            
    }

一部の人にとっては役立つかもしれません。

乾杯

アンドリュー

4
abarber

ES6の場合:

const ID_LENGTH = 36
const START_LETTERS_ASCII = 97 // Use 64 for uppercase
const ALPHABET_LENGTH = 26

const uniqueID = () => [...new Array(ID_LENGTH)]
  .map(() => String.fromCharCode(START_LETTERS_ASCII + Math.random() * ALPHABET_LENGTH))
 .join('')

例:

 > uniqueID()
 > "bxppcnanpuxzpyewttifptbklkurvvetigra"
3
cntdwn

これも行う必要があります:

(function() {
    var uniquePrevious = 0;
    uniqueId = function() {
        return uniquePrevious++;
    };
}());
    function UniqueValue(d){
        var dat_e = new Date();
        var uniqu_e = ((Math.random() *1000) +"").slice(-4)

        dat_e = dat_e.toISOString().replace(/[^0-9]/g, "").replace(dat_e.getFullYear(),uniqu_e);
        if(d==dat_e)
            dat_e = UniqueValue(dat_e);
        return dat_e;
    }

呼び出し1:UniqueValue( '0')
Call 2:UniqueValue(UniqueValue( '0'))//複雑になります

サンプル出力:
for(var i = 0; i <10; i ++){console.log(UniqueValue(UniqueValue( '0')));}
60950116113248802
26780116113248803
53920116113248803
35840116113248803
47430116113248803
41680116113248803
42980116113248804
34750116113248804
20950116113248804
03730116113248804

1

数字だけが「chars」変数を変更したい場合、これにより、ほぼ保証された一意の32文字キークライアント側が作成されます。

var d = new Date().valueOf();
var n = d.toString();
var result = '';
var length = 32;
var p = 0;
var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

for (var i = length; i > 0; --i){
    result += ((i & 1) && n.charAt(p) ? '<b>' + n.charAt(p) + '</b>' : chars[Math.floor(Math.random() * chars.length)]);
    if(i & 1) p++;
};

https://jsfiddle.net/j0evrdf1/1/

1
lugreen

数ミリ秒後に一意の番号が必要な場合はDate.now()を使用し、for loop内で使用する場合はDate.now() and Math.random()を一緒に使用します

forループ内の一意の番号

function getUniqueID(){
    for(var i = 0; i< 5; i++)
      console.log(Date.now() + ( (Math.random()*100000).toFixed()))
}
getUniqueID()

出力::すべての数字は一意です

15598251485988384 155982514859810330 155982514859860737 155982514859882244 155982514859883316

Math.random()なしの一意の番号

function getUniqueID(){
        for(var i = 0; i< 5; i++)
          console.log(Date.now())
    }
    getUniqueID()

出力::数字が繰り返されます

1559825328327 1559825328327 1559825328327 1559825328328 1559825328328

1
Raj Rj

私自身の将来の参照のために、このコードスニペットをここに投稿します(保証はされませんが、十分な「ユニークな」十分な):

// a valid floating number
window.generateUniqueNumber = function() {
    return new Date().valueOf() + Math.random();
};

// a valid HTML id
window.generateUniqueId = function() {
    return "_" + new Date().valueOf() + Math.random().toFixed(16).substring(2);
};
1
noseratio

GetTime()またはvalueOf()を使用するのがさらに良いかもしれませんが、このように一意の値と人間が理解できる数値(日付と時刻を表す)を返します。

window.getUniqNr = function() {
  var now = new Date(); 
  if (typeof window.uniqCounter === 'undefined') window.uniqCounter = 0; 
  window.uniqCounter++; 
  var m = now.getMonth(); var d = now.getDay(); 
  var h = now.getHours(); var i = now.getMinutes(); 
  var s = now.getSeconds(); var ms = now.getMilliseconds();
  timestamp = now.getFullYear().toString() 
  + (m <= 9 ? '0' : '') + m.toString()
  +( d <= 9 ? '0' : '') + d.toString() 
  + (h <= 9 ? '0' : '') + h.toString() 
  + (i <= 9 ? '0' : '') + i.toString() 
  + (s <= 9 ? '0' : '') + s.toString() 
  + (ms <= 9 ? '00' : (ms <= 99 ? '0' : '')) + ms.toString() 
  + window.uniqCounter; 

  return timestamp;
};
window.getUniqNr();
0

これを使用:javascriptで一意の番号を作成するため

var uniqueNumber=(new Date().getTime()).toString(36);

それは実際に動作します。 :)

0
Bprajhh

私はこのようにしました

function uniqeId() {
   var ranDom = Math.floor(new Date().valueOf() * Math.random())
   return _.uniqueId(ranDom);
}
0
DarkNominis
let now = new Date();
let timestamp = now.getFullYear().toString();
let month = now.getMonth() + 1;
timestamp += (month < 10 ? '0' : '') + month.toString();
timestamp += (now.getDate() < 10 ? '0' : '') + now.getDate().toString();
timestamp += (now.getHours() < 10 ? '0' : '') + now.getHours().toString();
timestamp += (now.getMinutes() < 10 ? '0' : '') + now.getMinutes().toString();
timestamp += (now.getSeconds() < 10 ? '0' : '') + now.getSeconds().toString();
timestamp += (now.getMilliseconds() < 100 ? '0' : '') + now.getMilliseconds().toString();
0
Manaaf Fanam

ノードではミリ秒がミリ秒ごとに更新されないため、次の答えがあります。これにより、人間が読み取れる一意のチケット番号が生成されます。プログラミングとnodejsは初めてです。私が間違っている場合は修正してください。

function get2Digit(value) {
if (value.length == 1) return "0" + "" + value;
else return value;

}

function get3Digit(value) {
if (value.length == 1) return "00" + "" + value;
else return value;

}

function generateID() {
    var d = new Date();
    var year = d.getFullYear();
    var month = get2Digit(d.getMonth() + 1);
    var date = get2Digit(d.getDate());
    var hours = get2Digit(d.getHours());
    var minutes = get2Digit(d.getMinutes());
    var seconds = get2Digit(d.getSeconds());
    var millSeconds = get2Digit(d.getMilliseconds());
    var dateValue = year + "" + month + "" + date;
    var uniqueID = hours + "" + minutes + "" + seconds + "" + millSeconds;

    if (lastUniqueID == "false" || lastUniqueID < uniqueID) lastUniqueID = uniqueID;
    else lastUniqueID = Number(lastUniqueID) + 1;
    return dateValue + "" + lastUniqueID;
}
0
Sai
function getUniqueNumber() {

    function shuffle(str) {
        var a = str.split("");
        var n = a.length;
        for(var i = n - 1; i > 0; i--) {
            var j = Math.floor(Math.random() * (i + 1));
            var tmp = a[i];
            a[i] = a[j];
            a[j] = tmp;
        }
        return a.join("");
    }
    var str = new Date().getTime() + (Math.random()*999 +1000).toFixed() //string
    return Number.parseInt(shuffle(str));   
}
0
Alex Pilugin

@ abarber によって提案された解決策は(new Date()).getTime()を使用するので良い解決策であると仮定し、ミリ秒のウィンドウを持ち、この間隔で衝突の場合にtickを合計します。ここで実際に動作を確認できるように、組み込みの使用を検討できます。

最初に、(new Date()).getTime()を使用して1/1000ウィンドウフレームに衝突が発生する様子を確認できます。

console.log( (new Date()).getTime() ); console.log( (new Date()).getTime() )
VM1155:1 1469615396590
VM1155:1 1469615396591
console.log( (new Date()).getTime() ); console.log( (new Date()).getTime() )
VM1156:1 1469615398845
VM1156:1 1469615398846
console.log( (new Date()).getTime() ); console.log( (new Date()).getTime() )
VM1158:1 1469615403045
VM1158:1 1469615403045

次に、1/1000ウィンドウでの衝突を回避する提案されたソリューションを試します。

console.log( window.mwUnique.getUniqueID() ); console.log( window.mwUnique.getUniqueID() ); 
VM1159:1 14696154132130
VM1159:1 14696154132131

それは、イベントループで単一のtickとして呼び出されるノードprocess.nextTickのような関数を使用することを検討できることを意味し、 here もちろん、ブラウザにはprocess.nextTickがないので、その方法を理解する必要があります。 この 実装は、setTimeout(fnc,0)setImmediate(fnc)window.requestAnimationFrameであるブラウザーのI/Oに最も近い関数を使用して、ブラウザーにnextTick関数をインストールします。提案どおり herewindow.postMessageを追加できますが、addEventListenerも必要なので、これは読者に任せます。ここで簡単にするために、元のモジュールバージョンを変更しました。

getUniqueID = (c => {
 if(typeof(nextTick)=='undefined')
nextTick = (function(window, prefixes, i, p, fnc) {
    while (!fnc && i < prefixes.length) {
        fnc = window[prefixes[i++] + 'equestAnimationFrame'];
    }
    return (fnc && fnc.bind(window)) || window.setImmediate || function(fnc) {window.setTimeout(fnc, 0);};
})(window, 'r webkitR mozR msR oR'.split(' '), 0);
 nextTick(() => {
   return c( (new Date()).getTime() )  
 })
})

したがって、1/1000ウィンドウに次のように表示されます。

getUniqueID(function(c) { console.log(c); });getUniqueID(function(c) { console.log(c); });
undefined
VM1160:1 1469615416965
VM1160:1 1469615416966
0
loretoparisi

簡単で常にユニークな価値を得る:

const uniqueValue = (new Date()).getTime() + Math.trunc(365 * Math.random());
**OUTPUT LIKE THIS** : 1556782842762
0