سؤال

أحاول إنشاء معرفات فريدة عالميًا في JavaScript.لست متأكدًا من الإجراءات المتاحة في جميع المتصفحات، وكيف يكون مولد الأرقام العشوائي المدمج "عشوائيًا" ومصنفًا، وما إلى ذلك.

يجب أن يتكون GUID / UUID من 32 حرفًا على الأقل ويجب أن يظل في نطاق ASCII لتجنب حدوث مشكلات عند تمريرهما.

هل كانت مفيدة؟

المحلول

UUIDs (المعرف الفريد عالميًا)، والمعروف أيضًا باسم GUIDs (المعرف الفريد العالمي)، وفقًا لـ آر إف سي 4122, ، هي معرفات مع ضمان تفرد معين.

أفضل طريقة لإنشائها هي اتباع تعليمات التنفيذ في RFC المذكور، واستخدام أحد التطبيقات مفتوحة المصدر العديدة التي تم فحصها من قبل المجتمع.

إحدى الأدوات الشائعة مفتوحة المصدر للعمل مع UUIDs في JavaScript هي node-uuid

لاحظ أن مجرد إنشاء المعرفات عشوائيًا بايتًا تلو الآخر، أو حرفًا تلو الآخر، لن يمنحك نفس الضمانات التي يوفرها التنفيذ المطابق.من المهم أيضًا أن تختار الأنظمة التي تعمل مع UUIDs المتوافقة عدم قبول تلك التي يتم إنشاؤها عشوائيًا، وسيقوم العديد من أدوات التحقق من الصحة مفتوحة المصدر بالتحقق من وجود بنية صالحة.

يجب أن يكون UUID بهذا التنسيق:

xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

أين ال م و ن قد تحتوي المواقف على قيم معينة فقط.في هذا الوقت، القيم الوحيدة الصالحة لـ M هي 1 و2 و3 و4 و5، لذا فإن توليد هذا الموضع عشوائيًا سيجعل معظم النتائج غير مقبولة.

نصائح أخرى

ل RFC4122 الحل المتوافق مع الإصدار 4، هذا الحل ذو الخطوط الواحدة هو الحل الأكثر إحكاما الذي يمكنني التوصل إليه.:

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() يكون لا مضمون أن يكون RNG عالي الجودة.انظر آدم هايلاند كتابة ممتازة على Math.random() للتفاصيل.للحصول على حل أكثر قوة، فكر في شيء من هذا القبيل وحدة uuid[تنصل:أنا المؤلف]، والذي يستخدم واجهات برمجة تطبيقات RNG عالية الجودة حيثما كان ذلك متاحًا.

تحديث، 2015-08-26:كملاحظة جانبية، هذا جوهر يصف كيفية تحديد عدد المعرفات التي يمكن إنشاؤها قبل الوصول إلى احتمال معين للاصطدام.على سبيل المثال، مع 3.26x1015 الإصدار 4 من UUIDs RFC4122 لديك فرصة تصادم بنسبة 1 في المليون.

تحديث، 2017-06-28مقالة جيدة من مطوري Chrome مناقشة حالة جودة Math.random PRNG في Chrome وFirefox وSafari.tl;dr - اعتبارًا من أواخر عام 2015، أصبحت "جيدة جدًا"، ولكنها ليست بجودة التشفير.لمعالجة هذه المشكلة، إليك إصدار محدث من الحل أعلاه الذي يستخدم ES6، crypto واجهة برمجة التطبيقات، و القليل من سحر 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());

أنا حقا أحب كيف نظيفة إجابة بروفا هو، ولكن من المؤسف أن سوء التنفيذ Math.random اترك فرصة الاصطدام.

وهنا مماثل RFC4122 حل متوافق مع الإصدار 4 يعمل على حل هذه المشكلة عن طريق موازنة أول 13 رقمًا سداسيًا عشريًا بجزء سداسي عشري من الطابع الزمني.بهذه الطريقة، حتى لو Math.random على نفس المصدر، سيتعين على كلا العميلين إنشاء UUID في نفس المللي ثانية بالضبط (أو بعد أكثر من 10000 سنة) للحصول على نفس 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);
    });
}


وهنا كمان للاختبار.

إجابة بروفا رائعة جدًا، بالفعل - ذكية بشكل مثير للإعجاب، حقًا...متوافق مع RFC4122، وقابل للقراءة إلى حد ما، وصغير الحجم.مذهل!

لكن إذا كنت تنظر إلى هذا التعبير العادي، فهؤلاء كثيرون replace() عمليات الاسترجاعات, toString()'رمل Math.random() استدعاءات الوظائف (حيث يستخدم فقط 4 أجزاء من النتيجة ويضيع الباقي)، قد تبدأ في التساؤل عن الأداء.في الواقع، قرر joelpt التخلص من RFC للحصول على سرعة GUID العامة باستخدام generateQuickGUID.

لكن هل يمكننا الحصول على السرعة؟ و الامتثال RFC؟أقول، نعم! هل يمكننا الحفاظ على سهولة القراءة؟حسنًا...ليس حقًا، لكن الأمر سهل إذا تابعت الأمر.

لكن أولاً، نتائجي، مقارنة بـ بروفا، 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.

لذلك، من خلال التكرار السادس للتحسينات، تغلبت على الإجابة الأكثر شيوعًا بفارق كبير 12X, ، الإجابة المقبولة من خلال 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 مع أي رقم سداسي عشري عشوائي، y مع بيانات عشوائية (باستثناء إجبار أعلى 2 بت على 10 وفقًا لمواصفات RFC)، ولا يتطابق التعبير العادي مع - أو 4 الشخصيات، حتى لا يضطر للتعامل معها.أملس جدًا.

أول شيء يجب معرفته هو أن استدعاءات الدوال باهظة الثمن، كما هو الحال مع التعبيرات العادية (على الرغم من أنه يستخدم 1 فقط، إلا أنه يحتوي على 32 رد اتصال، واحد لكل تطابق، وفي كل من 32 رد اتصال يستدعي Math.random() و v. إلى السلسلة (16)).

الخطوة الأولى نحو الأداء هي إزالة RegEx ووظائف رد الاتصال الخاصة به واستخدام حلقة بسيطة بدلاً من ذلك.وهذا يعني أنه يتعين علينا التعامل مع - و 4 الشخصيات في حين لم broofa.لاحظ أيضًا أنه يمكننا استخدام فهرسة String Array للحفاظ على بنية قالب السلسلة الرائعة:

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, واستخدام حلقة while (بدلاً من replace() عمليات الاسترجاعات) تجعلنا نتحسن بمقدار 3 أضعاف تقريبًا!

الخطوة التالية هي خطوة صغيرة على سطح المكتب ولكنها تُحدث فرقًا جيدًا على الهاتف المحمول.لنقم بإجراء عدد أقل من استدعاءات Math.random() ونستخدم كل تلك البتات العشوائية بدلاً من التخلص من 87% منها باستخدام مخزن مؤقت عشوائي يتم إزاحته خارج كل تكرار.لننقل أيضًا تعريف القالب هذا خارج الحلقة، فقط في حال كان ذلك مفيدًا:

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، ولكنه ليس صعبًا للغاية.يتعين علينا بعد ذلك إنشاء جدول بحث أكبر (16x16، أو 256) لتخزين 0x00 - 0xff، وقمنا ببنائه مرة واحدة فقط، خارج الدالة e5().

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
}

لقد قمت بتجربة e6() الذي يعالج 16 بت في المرة الواحدة، ولا أزال أستخدم جدول البحث LUT المكون من 256 عنصرًا، وقد أظهر انخفاض عوائد التحسين.على الرغم من أنه يحتوي على عدد أقل من التكرارات، إلا أن المنطق الداخلي كان معقدًا بسبب زيادة المعالجة، وكان يؤدي نفس الشيء على سطح المكتب، وأسرع بنسبة 10٪ فقط على الهاتف المحمول.

تقنية التحسين النهائية التي سيتم تطبيقها هي فتح الحلقة.وبما أننا نقوم بالتكرار لعدد محدد من المرات، يمكننا تقنيًا كتابة كل ذلك يدويًا.لقد جربت ذلك مرة واحدة باستخدام متغير عشوائي واحد r والذي ظللت أعيد تعيينه، وتراجع الأداء.ولكن مع تعيين بيانات عشوائية لأربعة متغيرات مقدمًا، ثم استخدام جدول البحث، وتطبيق بتات 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 بايت من البيانات العشوائية هو الجزء السهل.الحيلة بأكملها هي التعبير عنها بتنسيق String مع توافق RFC، ويتم إنجازها بشكل محكم باستخدام 16 بايت من البيانات العشوائية وحلقة غير ملفوفة وجدول بحث.

آمل أن يكون منطقى صحيحًا - فمن السهل جدًا ارتكاب خطأ في هذا النوع من العمل الممل.لكن النواتج تبدو جيدة بالنسبة لي.أتمنى أن تستمتع بهذه الرحلة المجنونة من خلال تحسين الكود!

كن نصوح: كان هدفي الأساسي هو عرض وتعليم إستراتيجيات التحسين المحتملة.تغطي الإجابات الأخرى موضوعات مهمة مثل التصادمات والأرقام العشوائية حقًا، والتي تعتبر مهمة لإنشاء معرفات UUID جيدة.

وإليك بعض التعليمات البرمجية على أساس آر إف سي 4122, ، القسم 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;
}
var uniqueId = Math.random().toString(36).substring(2) + (new Date()).getTime().toString(36);

إذا تم إنشاء المعرفات بفارق يزيد عن 1 مللي ثانية، فستكون فريدة بنسبة 100%.

إذا تم إنشاء معرفين على فترات زمنية أقصر، وبافتراض أن الطريقة العشوائية عشوائية حقًا، فسيؤدي ذلك إلى إنشاء معرفات من المحتمل أن تكون فريدة عالميًا بنسبة 99.9999999999999% (تصادم في 1 من 10^15)

يمكنك زيادة هذا الرقم عن طريق إضافة المزيد من الأرقام، ولكن لإنشاء معرفات فريدة بنسبة 100%، ستحتاج إلى استخدام عداد عالمي.

إذا كنت حقًا بحاجة إلى الامتثال لـ RFC، فسيتم تمرير هذا التنسيق كإصدار 4 GUID صالح:

const uid = (new Date()).getTime().toString(16) + Math.random().toString(16).substring(2) + "0".repeat(16);
const guid = uid.substr(0,8) + '-' + uid.substr(8,4) + '-4000-8' + uid.substr(12,3) + '-' + uid.substr(15,12);

يحرر:يتبع الكود أعلاه النية، ولكن ليس حرف RFC.من بين التناقضات الأخرى، هناك بضعة أرقام عشوائية قصيرة.(أضف المزيد من الأرقام العشوائية إذا كنت في حاجة إليها) الجانب الإيجابي هو أن هذا سريع حقًا، مقارنة بالكود المتوافق بنسبة 100٪.أنت تستطيع اختبار GUID الخاص بك هنا

أسرع GUID مثل طريقة إنشاء السلسلة في التنسيق XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.لا يؤدي هذا إلى إنشاء GUID المتوافق مع المعايير.

تستغرق عشرة ملايين عملية تنفيذ لهذا التنفيذ 32.5 ثانية فقط، وهو أسرع ما رأيته في المتصفح على الإطلاق (الحل الوحيد بدون حلقات/تكرارات).

الوظيفة بسيطة مثل:

/**
 * Generates a GUID string.
 * @returns {String} The generated GUID.
 * @example af8a8416-6e18-a307-bd9c-f2c947bbb3aa
 * @author Slavik Meltser (slavik@meltser.info).
 * @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 مع 16 رقمًا بعد نقطة الكسر العشري (على سبيل المثال 0.4363923368509859).
  • ثم نأخذ هذا الرقم ونحوله إلى سلسلة مع قاعدة 16 (من المثال أعلاه سنحصل عليه0.6fb7687f).
    Math.random().toString(16).
  • ثم نقطع 0. بادئة (0.6fb7687f => 6fb7687f) والحصول على سلسلة مع ثمانية شخصيات سداسية عشرية طويلة.
    (Math.random().toString(16).substr(2,8).
  • في بعض الأحيان Math.random() ستعود الوظيفة رقم أقصر (على سبيل المثال 0.4363)، بسبب وجود أصفار في النهاية (من المثال أعلاه، الرقم في الواقع هو 0.4363000000000000).لهذا السبب أقوم بإلحاق هذه السلسلة "000000000" (سلسلة بها تسعة أصفار) ثم تقطعها substr() وظيفة لجعلها تسعة أحرف بالضبط (ملء الأصفار إلى اليمين).
  • سبب إضافة تسعة أصفار بالضبط هو السيناريو الأسوأ، وهو عندما Math.random() سترجع الدالة بالضبط 0 أو 1 (احتمال 1/10^16 لكل واحد منهم).لهذا السبب كنا بحاجة إلى إضافة تسعة أصفار إليها ("0"+"000000000" أو "1"+"000000000")، ثم قطعه من الفهرس الثاني (الحرف الثالث) بطول ثمانية أحرف.وفي بقية الحالات فإن إضافة الأصفار لن يضر بالنتيجة لأنها تقطعها على أية حال.
    Math.random().toString(16)+"000000000").substr(2,8).

الجمعية:

  • GUID بالتنسيق التالي XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.
  • لقد قسمت GUID إلى 4 أجزاء، كل قطعة مقسمة إلى نوعين (أو تنسيقين): XXXXXXXX و -XXXX-XXXX.
  • الآن أقوم بإنشاء المعرف الفريد العمومي (GUID) باستخدام هذين النوعين لتجميع المعرف الفريد العمومي (GUID) باستدعاء 4 قطع، كما يلي: XXXXXXXX -XXXX-XXXX -XXXX-XXXX XXXXXXXX.
  • للاختلاف بين هذين النوعين، قمت بإضافة معلمة العلم إلى وظيفة منشئ الزوج _p8(s), ، ال s تخبر المعلمة الوظيفة ما إذا كانت تريد إضافة شرطات أم لا.
  • في النهاية، نقوم ببناء المعرف الفريد العمومي (GUID) بالتسلسل التالي: _p8() + _p8(true) + _p8(true) + _p8(), ، وإعادته.

رابط لهذا المنصب على مدونتي

يتمتع!:-)

هنا مزيج من أعلى إجابة التصويت, ، مع وجود حل بديل لـ اصطدامات كروم:

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);
        });
    };

على جبين إذا كنت تريد اختباره.

فيما يلي تطبيق غير متوافق تمامًا ولكنه عالي الأداء لإنشاء معرف فريد يشبه GUID آمن لـ ASCII.

function generateQuickGuid() {
    return Math.random().toString(36).substring(2, 15) +
        Math.random().toString(36).substring(2, 15);
}

يُنشئ 26 حرفًا [a-z0-9]، مما يؤدي إلى الحصول على معرف فريد (UID) أقصر وأكثر تميزًا من المعرفات الفريدة العمومية (GUIDs) المتوافقة مع RFC.يمكن إضافة الشرطات بشكل تافه إذا كانت سهولة القراءة البشرية مهمة.

فيما يلي أمثلة الاستخدام والتوقيت لهذه الوظيفة والعديد من الإجابات الأخرى لهذا السؤال.تم إجراء التوقيت تحت Chrome m25، مع 10 ملايين تكرار لكل منهما.

>>> 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');

إليك الحل بتاريخ أكتوبر.9, 2011 من تعليق المستخدم جيد في 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
      )
}

من مدونة ساجي شكيدي التقنية:

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 يمكنه ضمان مفاتيح فريدة (راجع ملف مقالة ويكيبيديا).هناك دائما فرصة للاصطدامات.يوفر المعرّف الفريد العمومي (GUID) ببساطة مجموعة كبيرة بما يكفي من المفاتيح لتقليل تغير التصادمات إلى الصفر تقريبًا.

يمكنك استخدام العقدة uuid (https://github.com/kelektiv/node-uuid)

جيل بسيط وسريع من 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'

ES6:

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

خدمة الويب ستكون مفيدة.

العثور السريع على Google: http://www.hoskinson.net/GuidGenerator/

لا يمكن ضمان هذا التنفيذ، ولكن يجب على شخص ما نشر منشئ GUID جيد.

باستخدام خدمة الويب هذه، يمكنك تطوير واجهة ويب REST التي تستهلك خدمة الويب GUID، وتخدمها من خلال AJAX إلى جافا سكريبت في المتصفح.

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 وبعض عوامل البت لاستخراج النوافذ ذات الحجم الصغير من المخزن المؤقت.

يجب الالتزام بمخطط RFC Type 4 (العشوائي)، حيث واجهت مشاكل في المرة الأخيرة في تحليل uuids غير المتوافقة مع UUID الخاص بـ Java.

وحدة 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());

الاستخدام:

دليل.newGuid()

"c6c2d12f-d76b-5739-e551-07e6de5b0807"

دليل.فارغ

"00000000-0000-0000-0000-000000000000"

من ويكيبيديا جيدة هناك رابط لتطبيق جافا سكريبت لـ UUID.

إنه يبدو أنيقًا إلى حد ما، وربما يمكن تحسينه عن طريق إضافة تجزئة لعنوان IP الخاص بالعميل.ربما يمكن إدراج هذا التجزئة في جانب خادم مستند html لاستخدامه بواسطة جافا سكريبت من جانب العميل.

تحديث :الموقع الأصلي كان به خلط ورق اللعب، هنا هو نسخة محدثة

حسنًا، يحتوي هذا على مجموعة من الإجابات بالفعل، ولكن لسوء الحظ لا يوجد عشوائي "حقيقي" في المجموعة.الإصدار أدناه عبارة عن تعديل لإجابة 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 <baagoe@baagoe.com>, 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 <baagoe@baagoe.com>, 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);
  });
};

يؤدي هذا إلى إنشاء الإصدار 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('');
}

فيما يلي عينة من UUIDs التي تم إنشاؤها:

682db637-0f31-4847-9cdf-25ba9613a75c
97d19478-3ab2-4aa1-b8cc-a1c3540f54aa
2eed04c9-2692-456d-a0fd-51012f947136

مشروع جافا سكريبت على جيثب - https://github.com/LiosK/UUID.js

UUID.js منشئ UUID المتوافق مع RFC لجافا سكريبت.

انظر RFC 4122 http://www.ietf.org/rfc/rfc4122.txt.

الميزات تنشئ UUIDs المتوافقة مع RFC 4122.

الإصدار 4 uuids (uuids من أرقام عشوائية) والنسخة 1 UUIDs (UUIDs القائمة على الوقت) متوفرة.

يتيح كائن UUID مجموعة متنوعة من الوصول إلى UUID بما في ذلك الوصول إلى حقول UUID.

يتم تعويض دقة انخفاض الطابع الزمني لجافا سكريبت بأرقام عشوائية.

  // 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 الخاص بي مع بعض الإضافات هنا.

أنا استخدم كيبوس التالية سيكون مولد الأرقام العشوائية أكثر صوتًا من حيث التشفير.

يوجد أدناه البرنامج النصي الخاص بي مع استبعاد أساليب Mash وKybos من baagoe.com.

//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 <baagoe@baagoe.com>, 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}

أردت أن أفهم إجابة بروفا، فوسعتها وأضفت تعليقات:

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.");
    }
);

بالنسبة لأولئك الذين يريدون حلًا متوافقًا مع الإصدار 4 من rfc4122 مع اعتبارات السرعة (استدعاءات قليلة إلى 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("");
}

يجب أن تتمتع الوظيفة المذكورة أعلاه بتوازن جيد بين السرعة والعشوائية.

يعتمد هذا على التاريخ، وإضافة لاحقة عشوائية "لضمان" التفرد.يعمل بشكل جيد لمعرفات CSS.يُرجع دائمًا شيئًا مثل ويسهل اختراقه:

معرف المستخدم-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;
        };

أعلم أنه سؤال قديم.فقط للاكتمال، إذا كانت بيئتك هي SharePoint، فهناك وظيفة مساعدة تسمى SP.Guid.newGuid (رابط ام اس دي ان) مما يؤدي إلى إنشاء دليل جديد.هذه الوظيفة موجودة داخل الملف 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;
};

يوجد مكون إضافي لـ jQuery يتعامل مع Guid's بشكل جيد @ http://plugins.jquery.com/project/GUID_Helper

jQuery.Guid.Value()

إرجاع قيمة المرشد الداخلي.إذا لم يتم تحديد أي دليل إرشادي، فسيتم إرجاع دليل جديد (ثم يتم تخزين القيمة داخليًا).


jQuery.Guid.New()

إرجاع دليل جديد وتعيين قيمته داخليًا.


jQuery.Guid.Empty()

تقوم بإرجاع دليل فارغ 00000000-0000-0000-0000-000000000000.


jQuery.Guid.IsEmpty()

ترجع منطقية.صحيح إذا كان فارغًا/غير محدد/فارغًا/خاليًا.


jQuery.Guid.IsValid()

ترجع منطقية.دليل صحيح صحيح، كاذب إذا لم يكن كذلك.


jQuery.Guid.Set()

دليل العائدين.يضبط المعرف الفريد العمومي (Guid) على المعرف الفريد العمومي (Guid) المحدد بواسطة المستخدم، وإذا كان غير صالح، فإنه يُرجع معرّفًا إرشاديًا فارغًا.

كود بسيط يستخدم crypto.getRandomValues(a) على المتصفحات المدعومة (IE11+، iOS7+، FF21+، كروم، أندرويد كروم).يتجنب استخدامه Math.random() لأن ذلك يمكن أن يسبب تصادمات (على سبيل المثال 20 تصادمًا لـ 4000 وحدة uuids تم إنشاؤها في موقف حقيقي بواسطة موكسا).

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);
}

ملحوظات:

  • تم تحسينه لسهولة قراءة التعليمات البرمجية وليس للسرعة، لذا فهو مناسب لبضع مئات من وحدات uuid في الثانية على سبيل المثال.يولد حوالي 10000 uuid() في الثانية في Chromium على الكمبيوتر المحمول الخاص بي باستخدام http://jsbin.com/fuwigo/1 لقياس الأداء.
  • يستخدم 8 فقط لـ "y" لأن ذلك يبسط إمكانية قراءة التعليمات البرمجية (يُسمح لـ y أن تكون 8 أو 9 أو A أو B).
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top