سؤال

عند إنشاء Uuid في Python ، LiveSo:

>>> uuid.uuid1()
UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')

كيف يمكن لأحد الخريطة التي تعاني من uuid في سلسلة مكونة من الأبجدية ذات الرسملة ناقص الأحرف D و F و I و O و Q و U ، بالإضافة إلى الأرقام العددية ، بالإضافة إلى الأحرف "+" و "=". أي من عدد صحيح أو سلسلة على مجموعة من 32 (صديقة للرسائل التعريفي نسبيا):

[ABCEGHJKLMNPRSTVWXYZ1234567890+=]

سأسمي هذا OCRf مجموعة (لـ OCR Friendly).

أرغب في الحصول على وظيفة متساوية الشكل:

def uuid_to_ocr_friendly_chars(uid)
    """takes uid, an integer, and transposes it into a string made 
       of the the OCRf set
    """
    ...

فكرتي الأولى هي أن أذهب إلى عملية تغيير UUID إلى قاعدة 32. على سبيل المثال

OCRf = "ABCEGHJKLMNPRSTVWXYZ1234567890+="

def uuid_to_ocr_friendly_chars(uid):
     ocfstr = ''
     while uid > 1:
        ocfstr += OCRf[uid % 32]
        uid /= 32
     return ocfstr

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

أنا ممتن لمدخلاتك. شكرًا لك.

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

المحلول

ما مدى أهمية "الضغط" على التمثيل بنسبة 18.75 ٪ ، أي من 32 إلى 26 حرفًا؟ لأنه ، إذا كان توفير هذه النسبة المئوية الصغيرة من البايتات ليس أمرًا بالغ الأهمية ، فإن شيئًا مثل uid.hex.upper().replace('D','Z') ستفعل ما تطلبه (عدم استخدام الأبجدية بأكملها التي توفرها ، ولكن التكلفة الوحيدة لهذا المفقودة هي أن 18.75 ٪ "الضغط").

إذا كان الضغط على كل بايت أخيرة أمرًا بالغ الأهمية ، فسأعمل على فرعية من 20 بت لكل منهما - وهي 5 أحرف سداسية ، 4 أحرف في الأبجدية غير التقليدية. هناك 6 من هؤلاء (بالإضافة إلى 8 بتات متبقية ، يمكنك أخذها hex.upper().replace كما هو مذكور أعلاه لأنه لا يوجد شيء يكسبه في فعل أي شيء مربي). يمكنك بسهولة الحصول على الفرعية عن طريق التقطيع .hex وتحويل كل منها إلى int مع int(theslice, 16). بعد ذلك ، يمكنك تطبيق نفس الخوارزمية التي تستخدمها أعلاه بشكل أساسي-ولكن يتم إجراء جميع الحساب على الأرقام التي يتمتع بها الكثير ، وبالتالي يجب أن يكون كسب السرعة مادة. أيضًا ، لا تبني السلسلة عن طريق الحلق += - قم بعمل قائمة بجميع "الأرقام" و ''.join لهم جميعًا في النهاية - هذا أيضًا تحسين في الأداء.

نصائح أخرى

>>> OCRf = 'ABCEGHJKLMNPRSTVWXYZ1234567890+='
>>> uuid = 'a8098c1a-f86e-11da-bd1a-00112444be1e'
>>> binstr = bin(int(uuid.replace("-",""),16))[2:].zfill(130)
>>> ocfstr = "".join(OCRf[int(binstr[i:i+5],2)] for i in range(0,130,5))
>>> ocfstr
'HLBJJB2+ETCKSP7JWACGYGMVW+'

لتحويل مرة أخرى

>>> "%x"%(int("".join(bin(OCRf.index(i))[2:].zfill(5) for i in ocfstr),2))
'a8098c1af86e11dabd1a00112444be1e'
transtbl = string.maketrans(
  'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',
  'ABCEGHJKLMNPRSTVWXYZ1234567890+='
)

uuidstr = uuid.uuid1()

print base64.b32encode(str(uuidstr).replace('-', '').decode('hex')).rstrip('=').translate(transtbl)

نعم ، هذه الطريقة يفعل اجعلني مريضًا بعض الشيء ، شكرًا على السؤال.

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