私はJavaScriptでグローバルにユニークな識別子を作成しようとしています。すべてのブラウザでどのルーチンが利用できるのか、内蔵の乱数発生器がどのように「ランダム」でシードされているのかなどわかりません。
GUID/UUIDは32文字以上にし、ASCIIの範囲に収まるようにしてください。
RFC 4122 によると、GUID(Globally Unique IDentifier)とも呼ばれるUUID(Universally Unique IDentifier)は、特定の一意性を保証する識別子です。
それらを生成するための最良の方法は、前述のRFCの実装手順に従うか、コミュニティで吟味された多くのオープンソース実装のいずれかを使用するか、またはそれを持つ言語の場合は組み込み実装を使用することです。
いくつかの一般的なプログラミング言語用の、UUIDを扱うためのいくつかのオープンソースツールの例がここにリストされています。
JavaScript
_ php _
移動
ルビー
Python
バイト単位、または文字単位で識別子をランダムに生成しただけでは、準拠した実装と同じ保証は得られません。また、非常に重要なことに、準拠したUUIDを扱うシステムはランダムに生成されたものを受け入れないことを選択するかもしれず、そして多くのオープンソースバリデータは実際に有効な構造をチェックするでしょう。
UUIDは次の形式でなければなりません。
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
MとNの位置には、特定の値しかない場合があります。現時点では、Mの唯一の有効な値は1、2、3、4、5であるため、その位置をランダムに生成すると、ほとんどの結果が受け入れられなくなります。
RFC4122 バージョン4準拠のソリューションの場合、この1ライナー(ish)ソリューションは、私が思いつく最もコンパクトなソリューションです。
function uuidv4() {
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);
});
}
console.log(uuidv4())
更新、2015-06-02:UUIDの一意性は、基礎となる乱数ジェネレーター(RNG)に大きく依存していることに注意してください。上記のソリューションでは、簡潔にするためにMath.random()
を使用していますが、Math.random()
はnotで高品質のRNGであることが保証されています。詳細については、Adam Hylandの Math.random()に関する優れた記事 を参照してください。より堅牢なソリューションについては、 idモジュール [免責事項:私は著者です]のようなものを検討してください。これは、利用可能な場合により高品質のRNG APIを使用します。
更新、2015年8月26日:補足として、この Gist は、IDの数を決定する方法を説明しています衝突の特定の確率に達する前に生成されます。たとえば、3.26x1015 バージョン4のRFC4122 UUIDでは、100万分の1の衝突の可能性があります。
更新、2017-06-28:A Chrome開発者からの良い記事 Mathの状態についての議論Chrome、Firefox、およびSafariの.random PRNG品質。 tl; dr-2015年後半の時点では「かなり良い」が、暗号品質ではない。その問題に対処するために、ES6、crypto
API、および 私が信用できないJSウィザードの少し を使用する上記のソリューションの更新バージョンを以下に示します。
function uuidv4() {
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
)
}
console.log(uuidv4());
Broofaの答え がどれほどきれいであるかが本当に好きですが、Math.random
の貧弱な実装が衝突の可能性を残すのは残念です。
これは同様の RFC4122 バージョン4に準拠した解決策で、最初の13桁の16進数をタイムスタンプの16進数の部分でオフセットすることでこの問題を解決します。このように、たとえMath.random
が同じシード上にあったとしても、同じUUIDを得るためには両方のクライアントがまったく同じミリ秒(または10,000年以上後)でUUIDを生成する必要があります。
function generateUUID() { // Public Domain/MIT
var d = new Date().getTime();
if (typeof performance !== 'undefined' && typeof performance.now === 'function'){
d += performance.now(); //use high-precision timer if available
}
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
}
broofaの答えは非常に滑らかで、実に優れていて、本当に... rfc4122に準拠していて、やや読みやすくてコンパクトです。驚くばかり!
しかし、その正規表現、replace()
コールバック、toString()
、Math.random()
関数の呼び出し(彼は結果の4ビットしか使わず、残りを無駄にしている)を見ているのなら、パフォーマンスについて疑問に思うかもしれません。実際、joelptはgenerateQuickGUID
を使って一般的なGUIDスピードのためのRFCを捨てることさえ決心しました。
しかし、私たちはスピードの{and RFC準拠を手に入れることができますか?はい、そうです! 読みやすさを維持できますか?うーん...そうではありませんが、一緒に進めば簡単です。
しかし、最初に、私の結果を、broofa、guid
(受け入れられた答え)、およびrfcに準拠していないgenerateQuickGuid
と比較します。
Desktop Android
broofa: 1617ms 12869ms
e1: 636ms 5778ms
e2: 606ms 4754ms
e3: 364ms 3003ms
e4: 329ms 2015ms
e5: 147ms 1156ms
e6: 146ms 1035ms
e7: 105ms 726ms
guid: 962ms 10762ms
generateQuickGuid: 292ms 2961ms
- Note: 500k iterations, results will vary by browser/cpu.
それで、私の6回目の最適化の繰り返しで、最も人気のある答えをover 12X で、受け入れられた答えをover 9X で、そして速く順守できない答えを 2で打ちました。 -3X 。そして私はまだrfc4122に準拠しています。
方法に興味がありますか?私は http://jsfiddle.net/jcward/7hyaC/3/ と http://jsperf.com/uuid-generator-opt/4 に完全なソースを置いています。
説明として、broofaのコードから始めましょう。
'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);
});
そのためx
を任意のランダムな16進数に、y
をランダムデータに置き換え(RFC仕様に従って上位2ビットを10
に強制する場合を除く)、正規表現は-
または4
文字と一致しないため、対処する必要はありません彼らと。とても滑りにくい.
知っておくべき最初のことは、正規表現と同様に、関数呼び出しは高価であるということです(彼は1を使うだけですが、マッチごとに1つずつ、合計32のコールバックを持ち、32の各コールバックでMath.random()とvを呼び出します)。 toString(16).
パフォーマンスに向けた最初のステップは、RegExとそのコールバック関数を削除し、代わりに単純なループを使用することです。これは、-
と4
の文字を扱わなければならないのに対し、broofaはそうしなかったことを意味します。また、String Arrayインデックスを使用して、彼の滑らかなStringテンプレートアーキテクチャを維持することもできます。
function e1() {
var u='',i=0;
while(i++<36) {
var c='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'[i-1],r=Math.random()*16|0,v=c=='x'?r:(r&0x3|0x8);
u+=(c=='-'||c=='4')?c:v.toString(16)
}
return u;
}
基本的に、-
または4
をチェックし、(replace()
コールバックの代わりに)whileループを使用することを除けば、基本的に同じ内部ロジックで、ほぼ3倍の改善が見られます。
次のステップはデスクトップ上の小さなステップですが、モバイルにはかなりの違いがあります。各繰り返しをシフトアウトされるランダムバッファでそれらの87%を捨てる代わりに、より少ないMath.random()呼び出しを行い、それらすべてのランダムビットを利用しましょう。念のため、そのテンプレート定義をループから外してみましょう。
function e2() {
var u='',m='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx',i=0,rb=Math.random()*0xffffffff|0;
while(i++<36) {
var c=m[i-1],r=rb&0xf,v=c=='x'?r:(r&0x3|0x8);
u+=(c=='-'||c=='4')?c:v.toString(16);rb=i%8==0?Math.random()*0xffffffff|0:rb>>4
}
return u
}
これにより、プラットフォームによっては10〜30%節約できます。悪くない。しかし、次の大きなステップでは、toString関数呼び出しを最適化の古典的なルックアップテーブルと共に完全に取り除きます。単純な16要素のルックアップテーブルは、はるかに短い時間でtoString(16)の仕事をします。
function e3() {
var h='0123456789abcdef';
var k='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
/* same as e4() below */
}
function e4() {
var h=['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'];
var k=['x','x','x','x','x','x','x','x','-','x','x','x','x','-','4','x','x','x','-','y','x','x','x','-','x','x','x','x','x','x','x','x','x','x','x','x'];
var u='',i=0,rb=Math.random()*0xffffffff|0;
while(i++<36) {
var c=k[i-1],r=rb&0xf,v=c=='x'?r:(r&0x3|0x8);
u+=(c=='-'||c=='4')?c:h[v];rb=i%8==0?Math.random()*0xffffffff|0:rb>>4
}
return u
}
次の最適化は別の古典的なものです。各ループの反復では4ビットの出力しか処理していないので、ループの数を半分に減らし、各反復で8ビットを処理しましょう。 RFC準拠のビット位置を処理する必要があるため、これは注意が必要ですが、それほど難しくありません。次に、0x00 - 0xffを格納するために、より大きなルックアップテーブル(16x16、または256)を作成する必要があります。そして、e5()関数の外側で1回だけ作成します。
var lut = []; for (var i=0; i<256; i++) { lut[i] = (i<16?'0':'')+(i).toString(16); }
function e5() {
var k=['x','x','x','x','-','x','x','-','4','x','-','y','x','-','x','x','x','x','x','x'];
var u='',i=0,rb=Math.random()*0xffffffff|0;
while(i++<20) {
var c=k[i-1],r=rb&0xff,v=c=='x'?r:(c=='y'?(r&0x3f|0x80):(r&0xf|0x40));
u+=(c=='-')?c:lut[v];rb=i%4==0?Math.random()*0xffffffff|0:rb>>8
}
return u
}
私はまだ256要素のLUTを使用して、一度に16ビットを処理するe6()を試しました、そしてそれは最適化の減少する利益を示しました。繰り返し回数は少なくなりましたが、内部ロジックは処理の増加により複雑になり、デスクトップでも同じように実行され、モバイルではわずか10%高速になりました。
適用する最後の最適化手法 - ループを展開します。我々は一定の回数ループしているので、我々は技術的にこれをすべて手で書き出すことができる。再割り当てし続けた単一のランダム変数rを使ってこれを1回試し、パフォーマンスを向上させました。しかし、4つの変数に前もってランダムデータを割り当て、ルックアップテーブルを使用し、適切なRFCビットを適用することで、このバージョンではそれらすべてを喫煙します。
var lut = []; for (var i=0; i<256; i++) { lut[i] = (i<16?'0':'')+(i).toString(16); }
function e7()
{
var d0 = Math.random()*0xffffffff|0;
var d1 = Math.random()*0xffffffff|0;
var d2 = Math.random()*0xffffffff|0;
var d3 = Math.random()*0xffffffff|0;
return lut[d0&0xff]+lut[d0>>8&0xff]+lut[d0>>16&0xff]+lut[d0>>24&0xff]+'-'+
lut[d1&0xff]+lut[d1>>8&0xff]+'-'+lut[d1>>16&0x0f|0x40]+lut[d1>>24&0xff]+'-'+
lut[d2&0x3f|0x80]+lut[d2>>8&0xff]+'-'+lut[d2>>16&0xff]+lut[d2>>24&0xff]+
lut[d3&0xff]+lut[d3>>8&0xff]+lut[d3>>16&0xff]+lut[d3>>24&0xff];
}
モジュール化: http://jcward.com/UUID.js - UUID.generate()
面白いのは、16バイトのランダムデータを生成するのは簡単なことです。全体的なトリックは、RFCに準拠した文字列形式で表現することです。16バイトのランダムデータ、展開されたループ、およびルックアップテーブルを使用して、最も厳密に達成されています。
私の論理が正しいことを願っています - この種の面倒な作業を間違えるのはとても簡単です。しかし、出力は私にはよく見えます。私はあなたがコード最適化を通してこの狂った乗り心地を楽しんだことを望みます!
忠告: 私の主な目的は、最適化戦略の可能性を示して教えることでした。他の回答では、衝突や真の乱数などの重要なトピックについて説明します。これらは、優れたUUIDを生成するために重要です。
これは RFC 4122 、section 4.4(真に乱数または疑似乱数からUUIDを作成するためのアルゴリズム)に基づいたコードです。
function createUUID() {
// http://www.ietf.org/rfc/rfc4122.txt
var s = [];
var hexDigits = "0123456789abcdef";
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
s[8] = s[13] = s[18] = s[23] = "-";
var uuid = s.join("");
return uuid;
}
let uniqueId = Math.random().toString(36).substring(2) + Date.now().toString(36);
document.getElementById("unique").innerHTML =
Math.random().toString(36).substring(2) + (new Date()).getTime().toString(36);
<div id="unique">
</div>
IDが1ミリ秒以上離れて生成される場合、それらは100%一意です。
2つのIDがより短い間隔で生成され、ランダムメソッドが真にランダムであると仮定すると、99.99999999999999%がグローバルに一意である可能性が高いIDが生成されます(10分の1の衝突15)
数字を追加することでこの数を増やすことができますが、100%の一意のIDを生成するには、グローバルカウンターを使用する必要があります。
rFC互換性が必要な場合、このフォーマットは有効なバージョン4 GUIDとして渡されます。
let u = Date.now().toString(16) + Math.random().toString(16) + '0'.repeat(16);
let guid = [u.substr(0,8), u.substr(8,4), '4000-8' + u.substr(13,3), u.substr(16,12)].join('-');
let u = Date.now().toString(16)+Math.random().toString(16)+'0'.repeat(16);
let guid = [u.substr(0,8), u.substr(8,4), '4000-8' + u.substr(13,3), u.substr(16,12)].join('-');
document.getElementById("unique").innerHTML = guid;
<div id="unique">
</div>
編集:上記のコードは意図に従っていますが、RFCの文字ではありません。他の相違点の中でも、数桁の短いランダムな数字です。 (必要に応じてランダムな数字を追加します)利点は、100%準拠のコードと比較して、これが本当に速いことです。 ここでGUIDの有効性をテストする
フォーマットXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
の最速のGUIDのような文字列ジェネレータメソッド。これは標準準拠のGUIDを生成しません。
この実装の1000万回の実行にかかる時間はわずか32.5秒です。これは、ブラウザでこれまで見た中で最速の速度です(ループ/反復のない唯一の解決策)。
関数は以下のように単純です。
/**
* Generates a GUID string.
* @returns {String} The generated GUID.
* @example af8a8416-6e18-a307-bd9c-f2c947bbb3aa
* @author Slavik Meltser ([email protected]).
* @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()
関数は、小数点以下が16桁で、0から1までの10進数を返します(の例では0.4363923368509859
)。0.6fb7687f
が得られます)。Math.random().toString(16)
。0.
接頭辞(0.6fb7687f
=> 6fb7687f
)を切り捨てて、8桁の16進数の文字列を取得します。(Math.random().toString(16).substr(2,8)
。Math.random()
関数は、末尾にゼロがあるため(例えば0.4363
など)、より短い番号を返すことがあります(上の例では、実際には0.4363000000000000
です)。だから私はこの文字列"000000000"
(9個のゼロを含む文字列)を追加し、それからsubstr()
関数でそれを切り捨てて正確に9文字にしています(右にゼロを埋めます)。Math.random()
関数が正確に0または1(それぞれの確率で1/10 ^ 16の確率)を返すという最悪のシナリオのためです。そのため、9つのゼロ("0"+"000000000"
または"1"+"000000000"
)を追加し、それを2番目のインデックス(3番目の文字)から8文字の長さで切り取る必要があるのはそのためです。それ以外の場合は、ゼロを追加しても結果が損なわれることはありません。Math.random().toString(16)+"000000000").substr(2,8)
。総会:
XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
です。XXXXXXXX
と-XXXX-XXXX
の2つのタイプ(またはフォーマット)に分けられました。XXXXXXXX
-XXXX-XXXX
-XXXX-XXXX
XXXXXXXX
。_p8(s)
にflagパラメーターを追加しました。s
パラメーターは、関数にダッシュを追加するかどうかを指示します。_p8() + _p8(true) + _p8(true) + _p8()
という連鎖で構築し、それを返します。お楽しみください! :-)
これは、 トップ投票の回答 と、 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上 テストしたい場合は/。
これは2011年10月9日付けのユーザーのコメントによる解決策です: jed at https://Gist.github.com/982883 :
UUIDv4 = function b(a){return a?(a^Math.random()*16>>a/4).toString(16):([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,b)}
これは、 現在の最高評価の回答 と同じ目標を達成しますが、強制、再帰、および指数表記を使用することで、50バイト以上少なくなります。それがどのように機能するかについて興味がある人のために、これは関数の古いバージョンの注釈付きの形式です:
UUIDv4 =
function b(
a // placeholder
){
return a // if the placeholder was passed, return
? ( // a random number from 0 to 15
a ^ // unless b is 8,
Math.random() // in which case
* 16 // a random number from
>> a/4 // 8 to 11
).toString(16) // in hexadecimal
: ( // or otherwise a concatenated string:
[1e7] + // 10000000 +
-1e3 + // -1000 +
-4e3 + // -4000 +
-8e3 + // -80000000 +
-1e11 // -100000000000,
).replace( // replacing
/[018]/g, // zeroes, ones, and eights with
b // random hex digits
)
}
これは、ASCIIに安全なGUIDのような一意の識別子を生成するための、完全に非準拠だが非常に高性能な実装です。
function generateQuickGuid() {
return Math.random().toString(36).substring(2, 15) +
Math.random().toString(36).substring(2, 15);
}
26 [a-z0-9]文字を生成し、RFC準拠のGUIDよりも短く固有のUIDを生成します。読みやすさが重要な場合は、ダッシュを付け加えることができます。
この関数の使用例とタイミング、そしてこの質問の他のいくつかの答えはここにあります。タイミングはChrome m25、それぞれ1000万回の繰り返しで実行されました。
>>> generateQuickGuid()
"nvcjf1hs7tf8yyk4lmlijqkuo9"
"yq6gipxqta4kui8z05tgh9qeel"
"36dh5sec7zdj90sk2rx7pjswi2"
runtime: 32.5s
>>> GUID() // John Millikin
"7a342ca2-e79f-528e-6302-8f901b0b6888"
runtime: 57.8s
>>> regexGuid() // broofa
"396e0c46-09e4-4b19-97db-bd423774a4b3"
runtime: 91.2s
>>> createUUID() // Kevin Hakanson
"403aa1ab-9f70-44ec-bc08-5d5ac56bd8a5"
runtime: 65.9s
>>> UUIDv4() // Jed Schmidt
"f4d7d31f-fa83-431a-b30c-3e6cc37cc6ee"
runtime: 282.4s
>>> Math.uuid() // broofa
"5BD52F55-E68F-40FC-93C2-90EE069CE545"
runtime: 225.8s
>>> Math.uuidFast() // broofa
"6CB97A68-23A2-473E-B75B-11263781BBE6"
runtime: 92.0s
>>> Math.uuidCompact() // broofa
"3d7b7a06-0a67-4b67-825c-e5c43ff8c1e8"
runtime: 229.0s
>>> bitwiseGUID() // jablko
"baeaa2f-7587-4ff1-af23-eeab3e92"
runtime: 79.6s
>>>> betterWayGUID() // Andrea Turri
"383585b0-9753-498d-99c3-416582e9662c"
runtime: 60.0s
>>>> UUID() // John Fowler
"855f997b-4369-4cdb-b7c9-7142ceaf39e8"
runtime: 62.2s
これがタイミングコードです。
var r;
console.time('t');
for (var i = 0; i < 10000000; i++) {
r = FuncToTest();
};
console.timeEnd('t');
Node-uuid( https://github.com/kelektiv/node-uuid )を使用できます。
RFC4122 UUIDSのシンプルで速い世代。
特徴:
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'
ES6:
import uuid from 'uuid/v4';
const id = uuid();
function generateGuid() {
var result, i, j;
result = '';
for(j=0; j<32; j++) {
if( j == 8 || j == 12 || j == 16 || j == 20)
result = result + '-';
i = Math.floor(Math.random()*16).toString(16).toUpperCase();
result = result + i;
}
return result;
}
ActiveXコントロールを使用する方法は他にもありますが、それ以外の方法は避けてください。
編集: GUIDジェネレータが一意のキーを保証できないことを指摘する価値があると思いました( wikipediaの記事 を確認してください)。衝突の可能性は常にあります。 A GUIDは、衝突の変化をほぼゼロにするのに十分な大きさのキーのユニバースを単に提供します。
Webサービスは便利でしょう。
クイックGoogleが見つかりました: http://www.hoskinson.net/GuidGenerator/ /
この実装を保証することはできませんが、誰かが善意のGUIDジェネレータを公開する必要があります。
このようなWebサービスを使用すると、REST Webサービスを使用し、GUIDを介してブラウザのjavascriptに提供するAJAX Webインタフェースを開発できます。
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の答えと、バッファからニブルサイズのウィンドウを抽出するためのビット演算子に基づくバージョン。
前回、JavaのUUIDを使用して準拠していないUUIDを解析していたため、RFC Type 4(ランダム)スキーマに準拠する必要があります。
このスレッドのベストアンサーの組み合わせとしてのシンプルなJavaScriptモジュール。
var crypto = window.crypto || window.msCrypto || null; // IE11 fix
var Guid = Guid || (function() {
var EMPTY = '00000000-0000-0000-0000-000000000000';
var _padLeft = function(paddingString, width, replacementChar) {
return paddingString.length >= width ? paddingString : _padLeft(replacementChar + paddingString, width, replacementChar || ' ');
};
var _s4 = function(number) {
var hexadecimalResult = number.toString(16);
return _padLeft(hexadecimalResult, 4, '0');
};
var _cryptoGuid = function() {
var buffer = new window.Uint16Array(8);
window.crypto.getRandomValues(buffer);
return [_s4(buffer[0]) + _s4(buffer[1]), _s4(buffer[2]), _s4(buffer[3]), _s4(buffer[4]), _s4(buffer[5]) + _s4(buffer[6]) + _s4(buffer[7])].join('-');
};
var _guid = function() {
var currentDateMilliseconds = new Date().getTime();
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(currentChar) {
var randomChar = (currentDateMilliseconds + Math.random() * 16) % 16 | 0;
currentDateMilliseconds = Math.floor(currentDateMilliseconds / 16);
return (currentChar === 'x' ? randomChar : (randomChar & 0x7 | 0x8)).toString(16);
});
};
var create = function() {
var hasCrypto = crypto != 'undefined' && crypto !== null,
hasRandomValues = typeof(window.crypto.getRandomValues) != 'undefined';
return (hasCrypto && hasRandomValues) ? _cryptoGuid() : _guid();
};
return {
newGuid: create,
empty: EMPTY
};
})();
// DEMO: Create and show GUID
console.log(Guid.newGuid());
使用法:
Guid.newGuid()
"c6c2d12f-d76b-5739-e551-07e6de5b0807"
Guid.empty
"00000000-0000-0000-0000-000000000000"
古き良き 'wikipedia UUIDのJavaScript実装へのリンクがあります。
それはかなり優雅に見え、そしておそらくクライアントのIPアドレスのハッシュを使ってソルトすることによって改善されるかもしれません。このハッシュは、クライアントサイドのJavaScriptで使用するために、HTMLドキュメントのサーバーサイドに挿入される可能性があります。
UPDATE:オリジナルのサイトはシャッフルされています、これは 更新されたバージョンです
ええと、これにはすでにたくさんの答えがありますが、残念ながら「本当の」ランダムなものはありません。以下のバージョンは、broofaの答えを改変したものですが、利用可能な場合には暗号ライブラリを使用する「真の」ランダム関数、および代替としてのAlea()関数を含むように更新されています。
Math.log2 = Math.log2 || function(n){ return Math.log(n) / Math.log(2); }
Math.trueRandom = (function() {
var crypt = window.crypto || window.msCrypto;
if (crypt && crypt.getRandomValues) {
// if we have a crypto library, use it
var random = function(min, max) {
var rval = 0;
var range = max - min;
if (range < 2) {
return min;
}
var bits_needed = Math.ceil(Math.log2(range));
if (bits_needed > 53) {
throw new Exception("We cannot generate numbers larger than 53 bits.");
}
var bytes_needed = Math.ceil(bits_needed / 8);
var mask = Math.pow(2, bits_needed) - 1;
// 7776 -> (2^13 = 8192) -1 == 8191 or 0x00001111 11111111
// Create byte array and fill with N random numbers
var byteArray = new Uint8Array(bytes_needed);
crypt.getRandomValues(byteArray);
var p = (bytes_needed - 1) * 8;
for(var i = 0; i < bytes_needed; i++ ) {
rval += byteArray[i] * Math.pow(2, p);
p -= 8;
}
// Use & to apply the mask and reduce the number of recursive lookups
rval = rval & mask;
if (rval >= range) {
// Integer out of acceptable range
return random(min, max);
}
// Return an integer that falls within the range
return min + rval;
}
return function() {
var r = random(0, 1000000000) / 1000000000;
return r;
};
} else {
// From http://baagoe.com/en/RandomMusings/javascript/
// Johannes Baagøe <[email protected]>, 2010
function Mash() {
var n = 0xefc8249d;
var mash = function(data) {
data = data.toString();
for (var i = 0; i < data.length; i++) {
n += data.charCodeAt(i);
var h = 0.02519603282416938 * n;
n = h >>> 0;
h -= n;
h *= n;
n = h >>> 0;
h -= n;
n += h * 0x100000000; // 2^32
}
return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
};
mash.version = 'Mash 0.9';
return mash;
}
// From http://baagoe.com/en/RandomMusings/javascript/
function Alea() {
return (function(args) {
// Johannes Baagøe <[email protected]>, 2010
var s0 = 0;
var s1 = 0;
var s2 = 0;
var c = 1;
if (args.length == 0) {
args = [+new Date()];
}
var mash = Mash();
s0 = mash(' ');
s1 = mash(' ');
s2 = mash(' ');
for (var i = 0; i < args.length; i++) {
s0 -= mash(args[i]);
if (s0 < 0) {
s0 += 1;
}
s1 -= mash(args[i]);
if (s1 < 0) {
s1 += 1;
}
s2 -= mash(args[i]);
if (s2 < 0) {
s2 += 1;
}
}
mash = null;
var random = function() {
var t = 2091639 * s0 + c * 2.3283064365386963e-10; // 2^-32
s0 = s1;
s1 = s2;
return s2 = t - (c = t | 0);
};
random.uint32 = function() {
return random() * 0x100000000; // 2^32
};
random.fract53 = function() {
return random() +
(random() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53
};
random.version = 'Alea 0.9';
random.args = args;
return random;
}(Array.prototype.slice.call(arguments)));
};
return Alea();
}
}());
Math.guid = function() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.trueRandom() * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
};
GitHub上のJavaScriptプロジェクト - https://github.com/LiosK/UUID.js
UUID.js JavaScript用のRFC準拠のUUIDジェネレータ。
RFC 4122 http://www.ietf.org/rfc/rfc4122.txt を参照してください。
機能RFC 4122準拠のUUIDを生成します。
バージョン4のUUID(乱数からのUUID)とバージョン1のUUID (時間ベースのUUID)が利用可能です。
UUIDオブジェクトは、UUIDフィールドへのアクセスを含む、UUIDへの様々なアクセスを可能にする。
JavaScriptの低いタイムスタンプの解像度は乱数で補正されています。
これはバージョン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
// RFC 4122
//
// A UUID is 128 bits long
//
// String representation is five fields of 4, 2, 2, 2, and 6 bytes.
// Fields represented as lowercase, zero-filled, hexadecimal strings, and
// are separated by dash characters
//
// A version 4 UUID is generated by setting all but six bits to randomly
// chosen values
var uuid = [
Math.random().toString(16).slice(2, 10),
Math.random().toString(16).slice(2, 6),
// 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
(Math.random() * .0625 /* 0x.1 */ + .25 /* 0x.4 */).toString(16).slice(2, 6),
// Set the two most significant bits (bits 6 and 7) of the
// clock_seq_hi_and_reserved to zero and one, respectively
(Math.random() * .25 /* 0x.4 */ + .5 /* 0x.8 */).toString(16).slice(2, 6),
Math.random().toString(16).slice(2, 14)].join('-');
私自身のUUID/GUIDジェネレータをいくつか追加して調整しました ここ 。
私は 次のKybos 乱数ジェネレータを使ってもう少し暗号的に健全にしています。
下記はbaagoe.comのMashとKybosメソッドを除いたスクリプトです。
//UUID/Guid Generator
// use: UUID.create() or UUID.createSequential()
// convenience: UUID.empty, UUID.tryParse(string)
(function(w){
// From http://baagoe.com/en/RandomMusings/javascript/
// Johannes Baagøe <[email protected]>, 2010
//function Mash() {...};
// From http://baagoe.com/en/RandomMusings/javascript/
//function Kybos() {...};
var rnd = Kybos();
//UUID/GUID Implementation from http://frugalcoder.us/post/2012/01/13/javascript-guid-uuid-generator.aspx
var UUID = {
"empty": "00000000-0000-0000-0000-000000000000"
,"parse": function(input) {
var ret = input.toString().trim().toLowerCase().replace(/^[\s\r\n]+|[\{\}]|[\s\r\n]+$/g, "");
if ((/[a-f0-9]{8}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{12}/).test(ret))
return ret;
else
throw new Error("Unable to parse UUID");
}
,"createSequential": function() {
var ret = new Date().valueOf().toString(16).replace("-","")
for (;ret.length < 12; ret = "0" + ret);
ret = ret.substr(ret.length-12,12); //only least significant part
for (;ret.length < 32;ret += Math.floor(rnd() * 0xffffffff).toString(16));
return [ret.substr(0,8), ret.substr(8,4), "4" + ret.substr(12,3), "89AB"[Math.floor(Math.random()*4)] + ret.substr(16,3), ret.substr(20,12)].join("-");
}
,"create": function() {
var ret = "";
for (;ret.length < 32;ret += Math.floor(rnd() * 0xffffffff).toString(16));
return [ret.substr(0,8), ret.substr(8,4), "4" + ret.substr(12,3), "89AB"[Math.floor(Math.random()*4)] + ret.substr(16,3), ret.substr(20,12)].join("-");
}
,"random": function() {
return rnd();
}
,"tryParse": function(input) {
try {
return UUID.parse(input);
} catch(ex) {
return UUID.empty;
}
}
};
UUID["new"] = UUID.create;
w.UUID = w.Guid = UUID;
}(window || this));
もっと良い方法:
function(
a,b // placeholders
){
for( // loop :)
b=a=''; // b - result , a - numeric variable
a++<36; //
b+=a*51&52 // if "a" is not 9 or 14 or 19 or 24
? // return a random number or 4
(
a^15 // if "a" is not 15
? // genetate a random number from 0 to 15
8^Math.random()*
(a^20?16:4) // unless "a" is 20, in which case a random number from 8 to 11
:
4 // otherwise 4
).toString(16)
:
'-' // in other cases (if "a" is 9,14,19,24) insert "-"
);
return b
}
最小化:
function(a,b){for(b=a='';a++<36;b+=a*51&52?(a^15?8^Math.random()*(a^20?16:4):4).toString(16):'-');return b}
私はbroofaの答えを理解したかったので、それを拡張してコメントを加えました:
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);
}
);
};
ES6サンプル
const guid=()=> {
const s4=()=> Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
return `${s4() + s4()}-${s4()}-${s4()}-${s4()}-${s4() + s4() + s4()}`;
}
それは単なるAJAX呼び出しです...
それでも興味がある人は、ここに私の解決策があります。
サーバー側:
[WebMethod()]
public static string GenerateGuid()
{
return Guid.NewGuid().ToString();
}
クライアント側:
var myNewGuid = null;
PageMethods.GenerateGuid(
function(result, userContext, methodName)
{
myNewGuid = result;
},
function()
{
alert("WebService call failed.");
}
);
速度を考慮したrfc4122バージョン4準拠のソリューションをご希望の場合(Math.random()をほとんど呼び出さない)
function UUID() {
var nbr, randStr = "";
do {
randStr += (nbr = Math.random()).toString(16).substr(2);
} while (randStr.length < 30);
return [
randStr.substr(0, 8), "-",
randStr.substr(8, 4), "-4",
randStr.substr(12, 3), "-",
((nbr*4|0)+8).toString(16), // [89ab]
randStr.substr(15, 3), "-",
randStr.substr(18, 12)
].join("");
}
上記の関数は、速度とランダムさの間で適切なバランスをとるべきです。
Guidのうまく処理するjQueryプラグインがあります@ http://plugins.jquery.com/project/GUID_Helper
jQuery.Guid.Value()
内部Guidの値を返します。 guidが指定されていない場合は、新しい値を返します(値は内部的に格納されます)。
jQuery.Guid.New()
新しいGuidを返し、その値を内部的に設定します。
jQuery.Guid.Empty()
空のGuid 00000000-0000-0000-0000-000000000000を返します。
jQuery.Guid.IsEmpty()
ブール値を返します。空/未定義/空白/ nullの場合は真です。
jQuery.Guid.IsValid()
ブール値を返します。真の有効なguid、そうでなければfalse。
jQuery.Guid.Set()
Guidに戻ります。無効な場合、Guidをユーザー指定のGuidに設定し、空のguidを返します。
私は知っています、それは古い質問です。完全を期すために、あなたの環境がSharePointであれば、新しいguidを作成するSP.Guid.newGuid
( msdn link )と呼ばれるユーティリティ関数があります。この関数はsp.init.jsファイルの中にあります。この関数を書き換えると(他のプライベート関数から他の依存関係を取り除くため)、このようになります。
var newGuid = function () {
var result = '';
var hexcodes = "0123456789abcdef".split("");
for (var index = 0; index < 32; index++) {
var value = Math.floor(Math.random() * 16);
switch (index) {
case 8:
result += '-';
break;
case 12:
value = 4;
result += '-';
break;
case 16:
value = value & 3 | 8;
result += '-';
break;
case 20:
result += '-';
break;
}
result += hexcodes[value];
}
return result;
};
これは日付に基づいており、一意性を「確実に」するためにランダムな接尾辞を追加します。 css識別子に適しています。
uid-139410573297741
var getUniqueId = function (prefix) {
var d = new Date().getTime();
d += (parseInt(Math.random() * 100)).toString();
if (undefined === prefix) {
prefix = 'uid-';
}
d = prefix + d;
return d;
};
サポートされているブラウザでcrypto.getRandomValues(a)
を使用する単純なコード (IE11 +、iOS7 +、FF21 +、Chrome、Android Chrome)。衝突が発生する可能性があるため、Math.random()
の使用は避けてください(例えば、 Muxa によって実際の状況で4000の生成されたuuidに対して20の衝突)。
function uuid() {
function randomDigit() {
if (crypto && crypto.getRandomValues) {
var rands = new Uint8Array(1);
crypto.getRandomValues(rands);
return (rands[0] % 16).toString(16);
} else {
return ((Math.random() * 16) | 0).toString(16);
}
}
var crypto = window.crypto || window.msCrypto;
return 'xxxxxxxx-xxxx-4xxx-8xxx-xxxxxxxxxxxx'.replace(/x/g, randomDigit);
}
ノート:
特定のフォーマットの128ビットのランダムな文字列が必要なだけの場合は、
function uuid() {
return crypto.getRandomValues(new Uint32Array(4)).join('-');
}
これは2350143528-4164020887-938913176-2513998651
のようなものを返します。
あなた自身のものをこれのためにホイップする代わりに、1人以上の貢献者によって維持されているよくテストされたコードを使うことは重要です。これは、Xブラウザでは動作するがYの特異性を考慮に入れていない可能性のある最も賢いバージョンよりも、最も安定したコードを優先したいと思う場所の1つです。一部のユーザー向けです。個人的には https://github.com/aurigadl/uuid-js でuuid-jsを使用していますので、アップデートが簡単にできます。
たった2つの突然変異を持つ、もう1つのより読みやすい変種。
function uuid4()
{
function hex (s, b)
{
return s +
(b >>> 4 ).toString (16) + // high nibble
(b & 0b1111).toString (16); // low nibble
}
let r = crypto.getRandomValues (new Uint8Array (16));
r[6] = r[6] >>> 4 | 0b01000000; // Set type 4: 0100
r[8] = r[8] >>> 3 | 0b10000000; // Set variant: 100
return r.slice ( 0, 4).reduce (hex, '' ) +
r.slice ( 4, 6).reduce (hex, '-') +
r.slice ( 6, 8).reduce (hex, '-') +
r.slice ( 8, 10).reduce (hex, '-') +
r.slice (10, 16).reduce (hex, '-');
}
私はこの下の機能を使っています、それが役に立つかもしれないと思います。
function NewGuid()
{
var sGuid="";
for (var i=0; i<32; i++)
{
sGuid+=Math.floor(Math.random()*0xF).toString(0xF);
}
return sGuid;
}
あなたはnpmパッケージguid、guidジェネレータとバリデータを使うことができます。
https://www.npmjs.com/package/guid
例:
Guid.raw();
// -> '6fdf6ffc-ed77-94fa-407e-a7b86ed9e59d'
更新: このパッケージは非推奨となりました。代わりに uuid を使用してください。
https://www.npmjs.com/package/uuid
例:
const uuidv4 = require('uuid/v4');
uuidv4(); // ⇨ '10ba038e-48da-487b-96e8-8d3b99b6d18a'
万が一、グーグルで落としている人が小さなユーティリティライブラリを探しているのであれば、ShortId( https://www.npmjs.com/package/shortid )がこの質問のすべての要件を満たしています。許容される文字と長さを指定することを許可し、非連続的で非反復的な文字列を保証します。
これをより現実的な答えにするために、そのライブラリのコアは以下のロジックを使用してその短いIDを生成します。
function encode(lookup, number) {
var loopCounter = 0;
var done;
var str = '';
while (!done) {
str = str + lookup( ( (number >> (4 * loopCounter)) & 0x0f ) | randomByte() );
done = number < (Math.pow(16, loopCounter + 1 ) );
loopCounter++;
}
return str;
}
/** Generates the short id */
function generate() {
var str = '';
var seconds = Math.floor((Date.now() - REDUCE_TIME) * 0.001);
if (seconds === previousSeconds) {
counter++;
} else {
counter = 0;
previousSeconds = seconds;
}
str = str + encode(alphabet.lookup, version);
str = str + encode(alphabet.lookup, clusterWorkerId);
if (counter > 0) {
str = str + encode(alphabet.lookup, counter);
}
str = str + encode(alphabet.lookup, seconds);
return str;
}
only このアプローチの最も基本的な部分を反映するようにこれを編集したわけではないので、上記のコードにはライブラリからの追加のロジックが含まれています。あなたがそれがしていることすべてについて興味があるならば、ソースを見てください: https://github.com/dylang/shortid/tree/master/lib
Windows上でJavascriptを使っている人のためのものです(例えばWScript/CScript/MSHTA)。 ActiveX
を使うことができます。具体的には、Scriptlet.Typelib
オブジェクトは次のとおりです。
WScript.Echo((new ActiveXObject("Scriptlet.TypeLib")).Guid)
この答えは私がリストアップした技術でのみ機能することに注意してください、それはどんなMicrosoftブラウザでもなくまた動作しません!だから、あなたの走行距離はこの答えによって異なります。
私のユースケースでは、グローバルに一意であることが保証されたID生成が必要でした。例外なく。私はしばらく問題に苦労して、そしてtuid(本当にユニークなID)と呼ばれる解決策を思い付きました。システム生成の最初の32文字と、エポック以降のミリ秒を表す残りの数字でIDを生成します。クライアントサイドのJavaScriptでIDを生成する必要がある場合は、うまく機能します。見てください:
こんにちはここでそれは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)
1つの16オクテットのTypedArray
とDataView
を使った答えが見つからなかったので、 RFC ごとにバージョン4のUUIDを生成するための次の解決策がここでは成り立つと思います。
function uuid4() {
const ho = (n, p) => n.toString(16).padStart(p, 0); /// Return the hexadecimal text representation of number `n`, padded with zeroes to be of length `p`
const view = new DataView(new ArrayBuffer(16)); /// Create a view backed by a 16-byte buffer
crypto.getRandomValues(new Uint8Array(view.buffer)); /// Fill the buffer with random data
view.setUint8(6, (view.getUint8(6) & 0xf) | 0x40); /// Patch the 6th byte to reflect a version 4 UUID
view.setUint8(8, (view.getUint8(8) & 0x3f) | 0x80); /// Patch the 8th byte to reflect a variant 1 UUID (version 4 UUIDs are)
return `${ho(view.getUint32(0), 8)}-${ho(view.getUint16(4), 4)}-${ho(view.getUint16(6), 4)}-${ho(view.getUint16(8), 4)}-${ho(view.getUint32(10), 8)}${ho(view.getUint16(14), 4)}`; /// Compile the canonical textual form from the array data
}
標準のECMAScriptプラットフォームで利用可能な機能のみに依存しているので、私はそれを好む。
broofaの仕事に基づいて、math.random()にタイムスタンプを追加することで、さらにランダム性を追加しました
助けになることを願っています
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = parseFloat('0.' + Math.random().toString().replace('0.', '') + new Date().getTime()) * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
ここでは、uuidsを生成する非常に小さな関数を見つけることができます https://Gist.github.com/jed/982883
最終版の1つは以下のとおりです。
function b(
a // placeholder
){
var cryptoObj = window.crypto || window.msCrypto; // for IE 11
return a // if the placeholder was passed, return
? ( // a random number from 0 to 15
a ^ // unless b is 8,
cryptoObj.getRandomValues(new Uint8Array(1))[0] // in which case
% 16 // a random number from
>> a/4 // 8 to 11
).toString(16) // in hexadecimal
: ( // or otherwise a concatenated string:
[1e7] + // 10000000 +
-1e3 + // -1000 +
-4e3 + // -4000 +
-8e3 + // -80000000 +
-1e11 // -100000000000,
).replace( // replacing
/[018]/g, // zeroes, ones, and eights with
b // random hex digits
)
}
一意のIDを生成する簡単な解決策は、タイムトークンを使用してそれに乱数を追加することです。 "uuid-"を前に付けるのが好きです。
以下の関数は型: uuid-14d93eb1b9b4533e6 のランダムな文字列を生成します。 32文字のランダムな文字列を生成する必要はありません。この場合、16文字のランダムな文字列で、JavaScriptで一意のUUIDを提供できます。
var createUUID = function(){ return "uuid - " +((新しい日付).getTime()。toString(16)+ Math.floor(1E7 * Math.random()) .toString(16)); }
uuid packageを使用して、 バージョン1、3、4、および5のUUID doをサポート
yarn add uuid
その後:
const uuidv1 = require('uuid/v1');
uuidv1(); // ⇨ '45745c60-7b1a-11e8-9c9c-2d42b21b1a3e'
完全に指定されたオプションでそれをすることもできます:
const v1options = {
node: [0x01, 0x23, 0x45, 0x67, 0x89, 0xab],
clockseq: 0x1234,
msecs: new Date('2011-11-01').getTime(),
nsecs: 5678
};
uuidv1(v1options); // ⇨ '710b962e-041c-11e1-9234-0123456789ab'
詳細については、npmページにアクセスしてください ここ
私が同じことをするためのさらに別の方法を投稿しようと思っただけで。
function guid() {
var chars = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"];
var str = "";
for(var i=0;i<36;i++) {
var str = str + ((i == 8 || i == 13 || i == 18 || i == 23) ? "-" : chars[Math.floor(Math.random()*chars.length)]);
};
return str;
}
これは誰かに役立つかもしれません...
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++;
};
function randomHex(length) {
var random_string = '';
if(!length){
length = 1;
}
for(var i=0; i<length; i+=1){
random_string += Math.floor(Math.random() * 15).toString(16);
}
return random_string;
}
function guid() {
return randomHex(8);
}
Replaceとcrypto.getRandomValuesを使って次のような出力を得ることができます。
xxxxxxxx-xxxx-4xxx-xxxx-xxxxxxxxxxxx
最適な解決策を探しているなら、crypto.getRandomValues(new Uint8Array(1))[0]
を配列(32)に置き換えなければなりません。
const uuidv4 = () =>
([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
);
console.log(uuidv4());
このコードを入手するには:
function uuidv4() {
let bytes = window.crypto.getRandomValues(new Uint8Array(32));
const randomBytes = () => (bytes = bytes.slice(1)) && bytes[0];
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
(c ^ randomBytes() & 15 >> c / 4).toString(16)
);
}
for (var i = 0; i < 10; i++)
console.log(uuidv4());
Googleアナリティクスのようにして、タイムスタンプを追加することができます:uuidv4() + "." + (+new Date())
。
科学について。私はまだ誰もこれをやっているのを見たことがありません...それはv4に準拠していませんが、簡単になるように変更することができます。これは Uint8Array 型を拡張し、 crypto.getRandomValues() を使用してuuidバイト値を生成する単なる例です。
class uuid extends Uint8Array {
constructor() {
super(16)
/* not v4, just some random bytes */
window.crypto.getRandomValues(this)
}
toString() {
let id = new String()
for (let i = 0; i < this.length; i++) {
/*convert uint8 to hex string */
let hex = this[i].toString(16).toUpperCase()
/*add zero padding*/
while (hex.length < 2) {
hex = String(0).concat(hex)
}
id += hex
/* add dashes */
if (i == 4 || i == 6 || i == 8 || i == 10 || i == 16){
id += '-'
}
}
return id
}
}