سؤال

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

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

فيما يلي بعض المتطلبات:

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

وبالنظر إلى هذه المتطلبات، كيف يمكنك إنشاء مثل هذا الرقم؟

يحرر :

@هاكد:يجب أن يكون الرمز رقميًا لأن المستخدم يكتبه بهاتفه.

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

متابعة :لقد وجدت العديد من الخوارزميات ل يفحص صحة الأرقام (راجع مشروع Google Code المثير للاهتمام: checkDigits).

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

المحلول

بعد بعض البحث، أعتقد أنني سأذهب مع آيزو 7064 مود 97,10 معادلة.يبدو الأمر قويًا جدًا حيث يتم استخدامه للتحقق من صحة رقم IBAN (رقم الحساب البنكي الدولي).

الصيغة بسيطة جدا:

  1. اختر رقم : 123456
  2. قم بتطبيق الصيغة التالية للحصول على المجموع الاختباري المكون من رقمين: mod(98 - mod(number * 100, 97), 97) => 76
  3. الرقم المتسلسل والمجموع الاختباري للحصول على الكود => 12345676
  4. للتحقق من صحة الرمز، تحقق من ذلك mod(code, 97) == 1

امتحان :

  • mod(12345676, 97) = 1 => جيد
  • mod(21345676, 97) = 50 => سيء!
  • mod(12345678, 97) = 10 => سيء!

من الواضح أن هذه الخوارزمية تكتشف معظم الأخطاء.

خيار آخر مثير للاهتمام كان خوارزمية فيرهوف.يحتوي على رقم تحقق واحد فقط ويكون تنفيذه أكثر صعوبة (مقارنة بالصيغة البسيطة أعلاه).

نصائح أخرى

بالنسبة لمجموعات 1M، ستحتاج إلى 6 أرقام.للتأكد من عدم وجود أي رموز صالحة عن طريق الخطأ، أقترح 9 أرقام مع احتمال 1/1000 أن يعمل رمز عشوائي.أقترح أيضًا استخدام رقم آخر (إجمالي 10) لإجراء عملية التحقق من النزاهة.وفيما يتعلق بأنماط التوزيع، يكفي العشوائي وسيضمن رقم التحقق أن خطأ واحد لن يؤدي إلى رمز صحيح.

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

تريد تقسيم التعليمات البرمجية الخاصة بك.يجب أن يكون جزء منه عبارة عن CRC مكونة من 16 بت من بقية الكود.

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

ثم تقوم ببدء التسلسل بـ CRC-16 لهذا الرقم التسلسلي وبعض المفاتيح الخاصة.يمكنك استخدام أي شيء للمفتاح الخاص، طالما أنك تحافظ عليه خاصًا.اجعله شيئًا كبيرًا، على الأقل أ GUID, ، ولكن يمكن أن يكون النص ل الحرب والسلام من مشروع جوتنبرج.فقط يجب أن تكون سرية وثابتة.إن امتلاك مفتاح خاص يمنع الأشخاص من تزوير المفتاح، ولكن استخدام CR 16 بت يجعل من السهل اختراقه.

للتحقق من صحة الرقم، ما عليك سوى تقسيم الرقم إلى جزأين، ثم أخذ CRC-16 من الرقم التسلسلي والمفتاح الخاص.

إذا كنت تريد إخفاء الجزء المتسلسل أكثر، فقم بتقسيم اتفاقية حقوق الطفل إلى جزأين.ضع 3 أرقام في المقدمة ورقمين في الجزء الخلفي من التسلسل (لوحة صفر بحيث يكون طول CRC ثابتًا).

تسمح لك هذه الطريقة بالبدء بمفاتيح أصغر أيضًا.المفاتيح العشرة الأولى ستكون مكونة من 6 أرقام.

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

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

  • يجب أن يكون لدي عدد معقول من المجموعات الممكنة (دعنا نقول مليونًا)
  • يجب أن يكون الرمز قصيرًا قدر الإمكان لتجنب الأخطاء من المستخدم

حسنًا، إذا كنت تريد أن تحتوي على مليون مجموعة على الأقل، فأنت بحاجة إلى ستة أرقام على الأقل.هل هذا قصير بما فيه الكفاية؟

عندما تقوم بإنشاء رمز التحقق، هل يمكنك الوصول إلى رقم هاتف المتصل؟

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

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

بالطبع لن ينجح هذا إذا كان رقم الهاتف المستخدم في الخطوة 1 مختلفًا عن الرقم الذي يتصلون منه في الخطوة 2.

بافتراض أنك تعرف بالفعل كيفية اكتشاف المفتاح الذي ضغط عليه المستخدم، فمن المفترض أن يكون هذا ممكنًا بسهولة إلى حد معقول.في عالم الأمن، هناك فكرة كلمة المرور "لمرة واحدة".يشار إلى هذا أحيانًا باسم "كلمة مرور يمكن التخلص منها". عادةً ما تقتصر هذه على قيم ASCII (بسهولة).لذا، [a-zA-z0-9] ومجموعة من الرموز القابلة للكتابة بسهولة.مثل الفاصلة والنقطة وشبه النقطتين والأقواس.في حالتك، على الرغم من ذلك، قد ترغب في تحديد النطاق بـ [0-9] وربما تضمين * و#.

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

بدلاً من الفشل في شرح تفاصيل التنفيذ بنفسي، سأوجهك إلى مقالة مكونة من 9 صفحات حيث يمكنك قراءتها بنفسك: https://www.grc.com/ppp.htm

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

هناك عدة طرق قام بها الناس بذلك في الماضي.

  1. قم بإنشاء مفتاح عام ومفتاح خاص.قم بتشفير الأرقام من 0 إلى 999,999 باستخدام المفتاح الخاص، ثم قم بتسليم النتائج.ستحتاج إلى إدخال بعض الأرقام العشوائية حتى تظهر النتيجة إلى الإصدار الأطول، وسيتعين عليك تحويل النتيجة من الأساس 64 إلى الأساس 10.عندما تحصل على رقم مُدخل، قم بتحويله مرة أخرى إلى base64، وقم بتطبيق المفتاح الخاص، ومعرفة ما إذا كانت الأرقام المثيرة للاهتمام أقل من 1,000,000 (تجاهل الأرقام العشوائية).
  2. إستخدم وظيفة التجزئة القابلة للعكس
  3. استخدم أول مليون رقم من PRN المصنف بقيمة محددة.يمكن لوظيفة "الفحص" الحصول على البذرة ومعرفة أن المليون قيمة التالية جيدة.يمكنه إما توليدها في كل مرة والتحقق منها واحدًا تلو الآخر عند استلام الرمز، أو عند بدء تشغيل البرنامج، تخزينها جميعًا في جدول، وفرزها، ثم استخدام البحث الثنائي (الحد الأقصى للمقارنات) نظرًا لأن مليون عدد صحيح ليس عددًا كبيرًا من الفضاء.

هناك مجموعة من الخيارات الأخرى، لكنها شائعة وسهلة التنفيذ.

-آدم

لقد ربطت التحقق من الأرقام المشروع، واستخدام وظيفة "التشفير" يبدو حلاً جيدًا.انها تقول:

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

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

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