الأفكار لإنشاء صغير (<10 أرقام)، وليس (جدا) "التجزئة"

StackOverflow https://stackoverflow.com/questions/890907

سؤال

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

  • يجب أن تكون كل "رمز التذكرة" مختلفا بما فيه الكفاية عن بعضها البعض (أي غير مرقمة بالتتابع)
  • من الناحية المثالية سيتم فحص التذكرة مقابل DB Central DB لمنع إعادة الاستخدام، ولكن يجب أن تكون قادرا على العمل خارج الخط أيضا، وفي هذه الحالة يجب على النظام التحقق من رمز التذاكر "صالح" وأنه لم يتم استخدامه في هذه بوابة.
  • يجب أن يكون "رمز التذكرة" صغيرا بما يكفي لتسهيل إدخاله إذا لزم الأمر
  • سيحتاج حامل التذاكر فقط إلى التذكرة للاستمرار (أي عدم وجود معرف)

نطاق البيانات صغير جدا، سيكون هناك فقط حوالي 20 حدثا أكثر من 4 أيام مع حوالي 5000 تذكرة لكل حدث (حوالي 100000 رموز تذكرة مختلفة)

الآن لدي العديد من الحقول التي لا تتم طباعتها على التذكرة وغير معروفة للمستخدم الذي يمكنني استخدامه لتشفير جزء من "رمز التذكرة"، حتى أتمكن من استخدام EventID وترتيب OrderID و Warl Salt لإنشاء صغير " التجزئة "لجزء من الرمز (الأفكار؟)، لكنني ما زلت عالقا مع معرف التذاكر المتسلسل أو GUID (سيكون طويلا جدا)

لذلك أي أفكار أو مؤشرات حول كيفية القيام بذلك؟

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

المحلول

فكر في مخطط بسيط للغاية بناء على شبكة FeiStel للسماح به، ويقول، رقم معرف التذاكر. هذه الرسالة (الذي يحدث في قوائم postgresql ولكن لا يكون لديك الكثير للقيام به مع postgresql) يصف بسيطة شبكة feistel. وبعد في كل تذكرة، يمكنك طباعة رقم معرف التذاكر (مختارة بالتتابع)، ثم "رمز سري التذاكر" نتيجة وضع رقم المعرف عبر شبكة FeiStel. تتضمن الاختلافات المحتملة إلغاء رقم التحقق من التعليمات البرمجية السرية، واستنادا إلى الإدخال إلى شبكة FeiStel على أكثر من الرقم الذي تم إنشاؤه بالتتابع (رقم + 10000 * رقم معرف الحدث، ET Cetera).

نصائح أخرى

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

import hashlib

secretpassword = "blah"

def createticket(eventnum, ticketnum):
    m = hashlib.md5() # or any crypto hash you like
    m.update("%s%s%s" % (eventnum, ticketnum, secretpassword))
    return m.hexdigest()[:10]

مثال:

رقم الحدث 1.

رقم التذكرة 123.

createticket(1,123)
# output: 2d7f242597

يأتي السيد Ticketman مع المدقق الذي يدخله في الحدث / رقم التذاكر والتجزئة:

def verifier(eventnum, ticketnum, hash):
    return hash == createticket(eventnum, ticketnum)

verifier(1,123, "2d7f242597")
# ouput: True

أقترح عليك إعطاء خوارزمية Verhoeff. محاولة.

طريقتان أستطيع أن أرى:

  1. توليد رقم عشوائي، أو جزءا عشوائيا على الأقل للحصول على رقم، وتخزينه في قاعدة بيانات مركزية. ثم قم بتنزيل قاعدة البيانات في جميع أنظمة البوابة للتحقق من.
  2. يجب أن يكون الرقم كافيا. بمعنى آخر، يجب أن يكون الرقم قادرا على تسجيل الخروج دون القائمة المحفوظة. هذا يبدو وكأنه نوع من نظام الاختباري. على سبيل المثال، يمكنك إصدار أرقام من 1 وأعلى، وجعلها 5 أرقام (00000-99999 = 100.000 أرقام)، وسرد 1-3 أحرف، والتأكد من أن تنتهي بك المطاف باستخدام المجموع الاختباري الذي سيحقق ذلك.

للتحقق دون اتصال، أرى حل واحد سهلا فقط ..

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

يتيح لك ذلك تحديد حجم معرف التذكرة ولديه أمان متناسب بوضوح فيما يتعلق بحجم معرف التذاكر.

يمكنك القيام بحساب CRC.

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

قد تبدأ برقم عشوائي معروف وتخزينه في أول 4 بايت، ويكون آخر الأربعة يكون حسابا كما وصفته سابقا.

سيكون هذا اثنين من دولتين، أو ثمانية بايت.

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

Ticket.0 = substring(HASH(SALT + IV        ), 0, LENGTH)
Ticket.i = substring(HASH(SALT + Ticket.i-1), 0, LENGTH)

أين

  • HASH هو أي وظيفة التجزئة التي توزع الانتروبيا بالتساوي نسبيا عبر سلسلة الإخراج
  • SALT هو ثابت تبقي سر؛ إنها فكرة جيدة استخدام واحدة مختلفة لكل حدث
  • IV هو ثابت آخر تبقي سر
  • الطول هو طول معرف التذاكر الذي تريده (10 في سؤالك، ولكن 12 ليس من السؤال ويمنحك 256 مرة أكبر عدد معرفات التذاكر)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top