سؤال

أنا أبحث عن طريقة خاصة في PHP التي سوف تكون مضمونة دائما للحصول على مفتاح فريد.

لقد فعلت التالية:

strtolower(substr(crypt(time()), 0, 7));

ولكن لقد وجدت أن مرة واحدة في حين كنت في نهاية المطاف مع مفتاح مكرر (نادرا ، ولكن في كثير من الأحيان بما فيه الكفاية).

يجب أيضا التفكير في القيام:

strtolower(substr(crypt(uniqid(rand(), true)), 0, 7));

ولكن وفقا PHP الموقع, uniqid () ، إذا uniqid() يسمى مرتين في نفس ميكروثانية ، فإنه يمكن توليد نفس المفتاح.أنا أفكر أن إضافة راند() أنه نادرا ، ولكن لا يزال ممكنا.

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

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

أي أفكار أخرى ؟ هل هناك أي من المواقع هناك التي تفعل هذا بالفعل أن يكون نوعا من API أو مجرد إعادة المفتاح.وجدت http://userident.com ولكن لست متأكدا إذا المفاتيح سوف تكون فريدة من نوعها تماما.

هذا يحتاج إلى تشغيل في الخلفية من دون أي إدخال المستخدم.

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

المحلول

هناك فقط 3 طرق لتوليد قيم فريدة ، بل تكون كلمات السر ، هوية المستخدم ، إلخ.:

  1. استخدام فعال GUID مولد - هذه هي طويلة ولا يمكن تقلصت.إذا كنت تستخدم فقط جزء تفشل.
  2. على الأقل جزء من رقم تسلسلي ولدت من تسلسل واحد.يمكنك إضافة زغب أو ترميز لجعلها تبدو أقل متتابعة.ميزة هي أنها تبدأ قصيرة العيب هو أنها تتطلب مصدر واحد.عمل حول مصدر واحد القيد أن يكون ترقيم المصادر ، لذا تشمل [المصدر #] + [seq #] ثم كل مصدر يمكن أن تولد التسلسل الخاص بها.
  3. تولد لهم عبر بعض الوسائل الأخرى ومن ثم تحقق لهم ضد واحد تاريخ ولدت سابقا القيم.

أي طريقة أخرى غير مضمونة.نأخذ في الاعتبار, في الأساس يتم توليد رقم ثنائي (هو الكمبيوتر) ، ولكن بعد ذلك يمكنك ترميز في الست عشري العشرية ، Base64, أو قائمة الكلمات.اختيار ترميز الذي يناسب الاستخدام.وعادة ما على المستخدم إدخال البيانات التي تريد بعض الاختلاف من Base32 (التي كنت ألمح في).

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

تحديث ملاحظة حول GUID:منذ كتابة هذا علمت أن العديد من GUID مولدات استخدام آمن مشفر مولد رقم عشوائي (من الصعب أو من المستحيل التنبؤ الرقم التالي ولدت, و ليس من المرجح أن تكرار).هناك في الواقع مختلفة 5 UUID الخوارزميات.خوارزمية 4 هو ما مايكروسوفت حاليا يستخدم Windows GUID الجيل API.A GUID هو تطبيق Microsoft UUID القياسية.

التحديث:إذا كنت تريد 7 إلى 16 حرفا ثم تحتاج إلى استخدام إما طريقة 2 أو 3.

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

حتى أفضل مولد رقم عشوائي لديه إمكانية تكرار يساوي مجموع حجم رقم عشوائي يتم توليد.تأخذ ربع على سبيل المثال.بل هو عشوائي تماما بت مولد و احتمالات تكرار هي 1 في 2.

بحيث يأتي كل ذلك إلى عتبة تفرد.هل يمكن أن يكون 100% التفرد في 8 أرقام على 1,099,511,627,776 الأرقام باستخدام تسلسل ثم base32 ترميز عليه.أي طريقة أخرى لا تنطوي على التحقق من قائمة من الأرقام السابقة فقط الاحتمالات يساوي n/1,099,511,627,776 (حيث n=عدد الأرقام السابقة ولدت) لا يجري فريدة من نوعها.

نصائح أخرى

أي خوارزمية سيؤدي التكرارات.

ولذلك أقترح أن استخدام الخوارزمية الحالية* و ببساطة التحقق من غيره ؟

*طفيف بالإضافة إلى ذلك:إذا uniqid() يمكن أن تكون غير فريدة من نوعها على أساس الوقت ، كما تشمل العالمي لمكافحة أن زيادة بعد كل احتجاج.هذا شيء بطريقة مختلفة حتى في نفس ميكروثانية.

دون كتابة التعليمات البرمجية ، المنطق ليكون:

إنشاء سلسلة عشوائية من أي مقبول الشخصيات تريد.
ثم يضاف نصف تاريخ ختم (جزئية ثانية وكل) إلى الجبهة و النصف الآخر إلى نهاية (أو في مكان ما في الوسط إذا كنت تفضل).

البقاء جولي!
ح

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

كنت قد تكون مهتمة في هذه المقالة التي تتناول نفس الموضوع: المعرفات الفريدة العمومية على الصعيد العالمي فريدة من نوعها ، ولكن سلاسل فرعية من المعرفات الفريدة العمومية لا.

الهدف من هذه الخوارزمية هو استخدام مزيج من الزمان والمكان ("الفضاء-الزمن الإحداثيات" عن النسبية المهوسون هناك) كما تفرد الرئيسية.بيد أن الوقت ليس مثاليا, لذلك هناك احتمال أن اثنين على سبيل المثال ، Guid يتم إنشاؤها في تعاقب سريع من نفس الجهاز حتى قريبة من بعضها البعض في الوقت الزمني سيكون نفسه.حيث uniquifier يأتي في.

وعادة ما تفعل ذلك من هذا القبيل:

$this->password = '';

for($i=0; $i<10; $i++)
{
    if($i%2 == 0)
        $this->password .= chr(rand(65,90));
    if($i%3 == 0)
        $this->password .= chr(rand(97,122));
    if($i%4 == 0)
        $this->password .= chr(rand(48,57));
}

أعتقد أن هناك بعض نظرية الثقوب ولكن لم يكن لدي مشكلة مع الازدواجية.أنا عادة استخدام كلمات المرور المؤقتة (مثل بعد إعادة تعيين كلمة المرور) و يعمل جيدا بما فيه الكفاية لذلك.

كما فرانك Kreuger وعلق تذهب مع GUID مولد.

مثل هذا واحد

ما زلت لا أرى لماذا كلمات السر يجب أن تكون فريدة من نوعها ؟ ما هو الجانب السلبي إذا 2 من المستخدمين لديهم نفس كلمة المرور ؟

هذا على افتراض أننا نتحدث عن كلمات السر التي ترتبط userids ، وليس مجرد معرفات فريدة من نوعها.إذا هذا ما تبحث عنه, لماذا لا تستخدم المعرفات الفريدة العمومية?

كنت قد تكون مهتمة في ستيف جيبسون أكثر من الأعلى-تأمين تنفيذ مولد كلمة السر (أي مصدر ، لكنه وصف مفصل كيف يعمل) في https://www.grc.com/passwords.htm.

موقع يخلق ضخمة 64 حرف كلمات السر ولكن بما أنهم عشوائية تماما, يمكنك أن تأخذ بسهولة الأول 8 (أو إلا أن العديد من) حرف أقل أمنا ولكن "عشوائي ممكن" كلمة المرور.

تحرير:من بعدها إجابات أرى أنك بحاجة إلى شيء أشبه GUID من المرور ، لذا ربما هذا ليس ما تريد...

أعتقد أن جزء من المشكلة هو أن تحاول الولايات المتحدة المفرد وظيفة منفصلة اثنين يستخدم...كلمات transaction_id

هذه هي اثنين من مختلف مناطق المشكلة و أنها في الحقيقة ليست أفضل في محاولة للتصدي لهم معا.

مؤخرا أردت سريعة و بسيطة عشوائية مفتاح فريد إذا فعلت التالي:

$ukey = dechex(time()) . crypt( time() . md5(microtime() + mt_rand(0, 100000)) ); 

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

لقد قمت بعمل اختبار حيث كنت توليد الآلاف من المفاتيح و ثم ابحث عن يكرر ، وبعد حوالي 800 مفاتيح في الثانية لا توجد التكرار ، لذلك ليس سيئا.أعتقد أن الأمر يعتمد كليا على mt_rand()

أنا استخدامها لإجراء مسح تعقب أين نحصل على معدل تقديم حوالي 1000 الدراسات الاستقصائية في الدقيقة...حتى الآن (الصلبان الأصابع) لا توجد التكرارات.وبطبيعة الحال ، فإن معدل غير ثابت (نحن الحصول على التقارير في أوقات معينة من اليوم) وهذا ليس دليلا على فشل ولا أفضل حل...تلميح باستخدام قيمة إضافية كجزء من المفتاح (في حالتي أنا استخدم الوقت () ، ولكن يمكن أن يكون أفضل).

Ingoring على crypting جزء ليس لديها الكثير لتفعله مع خلق قيمة فريدة من نوعها وعادة ما تستخدم هذا واحد:

function GetUniqueValue()
{
   static $counter = 0; //initalized only 1st time function is called
   return strtr(microtime(), array('.' => '', ' ' => '')) . $counter++;
}

عندما دعا في نفس العملية $العداد زيادة قيمة جدا دائما فريدة من نوعها في نفس العملية.

عندما دعا في عمليات مختلفة يجب أن تكون حقا محظوظين للحصول على 2 microtime() الاتصال مع نفس القيم ، أعتقد أن microtime() المكالمات عادة ما يكون لها قيم مختلفة أيضا عندما دعا في نفس السيناريو.

وعادة ما تفعل عشوائي substring (بطريقة عشوائية كم حرف بين 8 32 أو أقل لراحة المستخدم) أو MD5 من بعض القيمة لقد حصلت في ، أو الوقت ، أو مزيج.لمزيد من العشوائية أفعل MD5 من يأتي قيمة (أقول الاسم الأخير) لسلسلة أنه مع الوقت ، MD5 مرة أخرى ، ثم تأخذ عشوائية فرعية.نعم ، يمكن أن الحصول على كلمات السر ، ولكن ليس من المرجح جدا على الإطلاق.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top