बेस 62 रूपांतरण


92

आप एक पूर्णांक को बेस 62 में कैसे बदलेंगे (जैसे हेक्साडेसिमल, लेकिन इन अंकों के साथ: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMPOPQRSTUVWXYZ')।

मैं इसके लिए एक अच्छा पायथन पुस्तकालय खोजने की कोशिश कर रहा हूं, लेकिन वे सभी परिवर्तित तारों के साथ कब्जा कर रहे हैं। पायथन बेस 64 मॉड्यूल केवल तार को स्वीकार करता है और एक एकल अंक को चार वर्णों में बदल देता है। मैं कुछ के लिए देख रहा था जो यूआरएल shorteners उपयोग करते हैं।


लगता है जैसे किसी को बस एक खुला स्रोत परियोजना विचार मिला :) मुझे पता है कि क्या आपको कुछ भी मिलता है या अपना खुद का निर्माण करने का निर्णय लेना है ...
samoz

यदि आप लघु URL बनाना चाहते हैं, तो आप उन वर्णों के पूरे सेट का उपयोग करना चाहते हैं, जिन्हें इनकोड करने की आवश्यकता नहीं है: en.wikipedia.org/wiki/Percent-encoding#Types_of_URI_characters । वह 66 अक्षर का है।
l0b0

मुझे लगता है कि मैं केवल उपयोगकर्ता के भ्रम से बचने के लिए डॉट और टिल्ड पर से गुजरूंगा, लेकिन डैश और अंडरस्कोर सार्थक योग होने चाहिए, धन्यवाद।
मिकाल

Base64 के बारे में क्या? आपके पास इसके लिए पुस्तकालय खोजने के लिए बेहतर भाग्य हो सकता है।
माइक कूपर

इस सवाल के कई लागू जवाब हैं: stackoverflow.com/questions/561486/…
Miles

जवाबों:


169

इसके लिए कोई मानक मॉड्यूल नहीं है, लेकिन मैंने इसे प्राप्त करने के लिए अपने स्वयं के कार्यों को लिखा है।

BASE62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

def encode(num, alphabet):
    """Encode a positive number into Base X and return the string.

    Arguments:
    - `num`: The number to encode
    - `alphabet`: The alphabet to use for encoding
    """
    if num == 0:
        return alphabet[0]
    arr = []
    arr_append = arr.append  # Extract bound-method for faster access.
    _divmod = divmod  # Access to locals is faster.
    base = len(alphabet)
    while num:
        num, rem = _divmod(num, base)
        arr_append(alphabet[rem])
    arr.reverse()
    return ''.join(arr)

def decode(string, alphabet=BASE62):
    """Decode a Base X encoded string into the number

    Arguments:
    - `string`: The encoded string
    - `alphabet`: The alphabet to use for decoding
    """
    base = len(alphabet)
    strlen = len(string)
    num = 0

    idx = 0
    for char in string:
        power = (strlen - (idx + 1))
        num += alphabet.index(char) * (base ** power)
        idx += 1

    return num

इस तथ्य पर ध्यान दें कि आप इसे एन्कोडिंग और डिकोडिंग के लिए उपयोग करने के लिए कोई भी वर्णमाला दे सकते हैं। यदि आप alphabetतर्क को छोड़ देते हैं, तो आपको कोड की पहली पंक्ति पर परिभाषित 62 वर्ण वर्णमाला प्राप्त होने वाली है, और इसलिए 62 बेस से / को एन्कोडिंग / डिकोडिंग करना है।

उम्मीद है की यह मदद करेगा।

PS - URL शॉर्टर्स के लिए, मैंने पाया है कि कुछ भ्रमित करने वाले पात्रों जैसे 0O1oI आदि को छोड़ना बेहतर है। इस प्रकार मैं अपनी URL की छोटी जरूरतों के लिए इस वर्णमाला का उपयोग करता हूं - "23456789abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"

मज़े करो।


5
+1: अच्छा! यह संभवतः अधिक URL के अनुकूल वर्णों के साथ बढ़ाया जा सकता है ताकि संभवतः एक वर्ण को यहां और वहां बचाया जा सके। वर्ण मैं जानता हूँ कि सुरक्षित हैं कर रहे हैं: $-_.+!*'(),;/?:@&= आप शायद भी जैसे कुछ अन्य वर्णों का उपयोग कर सकते हैं []~आदि
Blixt

24
नामकरण बग: यह 62 का आधार नहीं है, क्योंकि वर्णमाला अनुकूलन योग्य है।
खोलना

3
डिकोड के लिए, यह शक्तियों की गणना नहीं करने के लिए एक बेहतर आदत है (समय बचाता है, लिखने के लिए कम है, लेकिन अधिक महत्वपूर्ण रूप से ऑफ-बाय-वन त्रुटियों से बचा जाता है), इस प्रकार: num = 0; स्ट्रिंग में चार के लिए: num = num * base + alphabet.index (char)
श्रीवत्सआर

1
@ श्रीवत्सआर: शब्दकोश देखने के बजाय str.index () का उपयोग करने का कोई विशेष कारण? मेरा जवाब देखिए ...
जॉन माचिन

2
>>> 256 * (62 ** 100) 44402652562862911414971048359760030835982580330786570771137804709455598239929932673552190201125730101070867075377228748911717860448985185350731601887476350502973424822800696272224256L: जोनाथन - - अजगर मनमाना लंबाई की संख्या संभाल कर सकते हैं कि वहाँ कोई अतिप्रवाह है
एंथोनी ब्रिग्स

53

मैंने एक बार इस अस्वस्थ को करने के लिए एक स्क्रिप्ट लिखी थी, मुझे लगता है कि यह काफी सुरुचिपूर्ण है :)

import string
# Remove the `_@` below for base62, now it has 64 characters
BASE_LIST = string.digits + string.letters + '_@'
BASE_DICT = dict((c, i) for i, c in enumerate(BASE_LIST))

def base_decode(string, reverse_base=BASE_DICT):
    length = len(reverse_base)
    ret = 0
    for i, c in enumerate(string[::-1]):
        ret += (length ** i) * reverse_base[c]

    return ret

def base_encode(integer, base=BASE_LIST):
    if integer == 0:
        return base[0]

    length = len(base)
    ret = ''
    while integer != 0:
        ret = base[integer % length] + ret
        integer /= length

    return ret

उदाहरण उपयोग:

for i in range(100):                                    
    print i, base_decode(base_encode(i)), base_encode(i)

9
यह संस्करण बैशम्पायन से स्वीकृत समाधान की तुलना में काफी तेज है। मैं फ़ंक्शन के बाहर की लंबाई की गणना करके आगे अनुकूलित हुआ। परीक्षण के परिणाम (100,000 पुनरावृत्तियों): संस्करण-WoLpH: .403 .399 .399 .39 .39398 | संस्करण-बैशम्पायन: 1.783 1.785 1.782 1.788 1.784। यह संस्करण लगभग 4x तेज है।
जॉर्डन

अगर base_decode फ़ंक्शन में reversed(string)स्लाइसिंग की तुलना में अधिक तेज़ी से उपयोग string[::-1]किया जाता है।
ENDOH takanao

1
इस प्रश्न को खोजने के लिए मुझे बहुत समय लगा। कभी नहीं पता था कि इसे बेस 62 रूपांतरण कहा जाता था। अच्छा जवाब।

1
मैं बदलना पड़ा integer /= lengthकरने के लिए integer //=lengthसही शेष पाने के लिए
karlgold

10

निम्नलिखित डिकोडर-निर्माता किसी भी उचित आधार के साथ काम करता है, इसमें बहुत अधिक टिडियर लूप होता है, और यह एक अमान्य चरित्र को पूरा करने पर एक स्पष्ट त्रुटि संदेश देता है।

def base_n_decoder(alphabet):
    """Return a decoder for a base-n encoded string
    Argument:
    - `alphabet`: The alphabet used for encoding
    """
    base = len(alphabet)
    char_value = dict(((c, v) for v, c in enumerate(alphabet)))
    def f(string):
        num = 0
        try:
            for char in string:
                num = num * base + char_value[char]
        except KeyError:
            raise ValueError('Unexpected character %r' % char)
        return num
    return f

if __name__ == "__main__":
    func = base_n_decoder('0123456789abcdef')
    for test in ('0', 'f', '2020', 'ffff', 'abqdef'):
        print test
        print func(test)

जबकि मैं शायद इसका इस्तेमाल कभी नहीं करूंगा, मैंने भी आपको रचनात्मकता के लिए अंगूठा दिया था। इस कोड ने मुझे हंसा दिया। :)
सेपरो

@ शेपरो: क्या इतना मज़ेदार है? यह गंभीर मजबूत औद्योगिक शक्ति सॉफ्टवेयर है। कोई मिकी-माउस **लूप में एक ऑपरेटर के साथ उलट नहीं करता है।
जॉन माकिन

खुद को शांत करें। आप सही हे। मुझे आपके भीतर के पाश की सच्ची अच्छाई याद आ गई क्योंकि यह सामान के भीतर दफन हो रहा है जो कि प्रश्न से जुड़ा हुआ है (रैपिंग, एरर चेकिंग, यूनिट टेस्टिंग)।
सेपरो

अच्छा लग रहा है, लेकिन क्या आप एक "औद्योगिक-ताकत" एनकोडर को नहीं भूले हैं जो एक स्ट्रिंग बनाने के लिए पूर्णांक प्लस वर्णमाला लेता है?
मार्टिउ

1
क्या ValueError को बढ़ा-चढ़ा कर दिखाने के इरादे से q अंतिम मान था?
थॉमस वैंडर स्टिकल

8

यदि आप उच्चतम दक्षता (जैसे django) की तलाश कर रहे हैं, तो आप निम्नलिखित की तरह कुछ चाहते हैं। यह कोड बैशम्पायन घोष और WoLpH और जॉन माचिन के कुशल तरीकों का एक संयोजन है।

# Edit this list of characters as desired.
BASE_ALPH = tuple("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
BASE_DICT = dict((c, v) for v, c in enumerate(BASE_ALPH))
BASE_LEN = len(BASE_ALPH)

def base_decode(string):
    num = 0
    for char in string:
        num = num * BASE_LEN + BASE_DICT[char]
    return num

def base_encode(num):
    if not num:
        return BASE_ALPH[0]

    encoding = ""
    while num:
        num, rem = divmod(num, BASE_LEN)
        encoding = BASE_ALPH[rem] + encoding
    return encoding

आप पहले से ही अपने शब्दकोश की गणना करना चाहते हैं। (नोट: एक स्ट्रिंग के साथ एन्कोडिंग एक सूची की तुलना में अधिक दक्षता दिखाता है, यहां तक ​​कि बहुत लंबी संख्या के साथ।)

>>> timeit.timeit("for i in xrange(1000000): base.base_decode(base.base_encode(i))", setup="import base", number=1)
2.3302059173583984

2.5 सेकंड के भीतर 1 मिलियन की संख्या में एन्कोड और डीकोड किया गया। (2.2Ghz i7-2670QM)


जरूरी नहीं कि शुरुआत में tuple()आसपास की जरूरत हो BASE_ALPH। पायथन में हर स्ट्रिंग चलने योग्य है। यह सुविधा निश्चित रूप से शोषण की है enumerate()। तो कोड भी दुबला हो जाता है :)
लुइस नेल

7
हे ओरिनेल, आप सही कह रहे हैं कि टपल () की आवश्यकता नहीं है, लेकिन मेरे सिस्टम पर, यह कोड को लगभग 20% तेज बनाता है। टपल () के बिना इसका परीक्षण करने का प्रयास करें और देखें कि आपके लिए सबसे अच्छा काम क्या है। चियर्स :)
सेपरो

1
दिलचस्प बिंदु। टुपल्स स्ट्रिंग्स की तुलना में अधिक हल्के होने के कारण कुल समझ में आता है। ज्ञानोदय के लिए धन्यवाद :)!
लुइस नेल

@ शेपरो मैंने स्वरूपण, नामकरण, परीक्षण और कार्यक्षमता के मामले में आपके संस्करण को और बेहतर किया (नकारात्मक संख्याएँ समर्थित हैं): pastebin.com/4uket7iu (आप इसके साथ अपने उत्तर को अपडेट कर सकते हैं)
जोशुआ 15:12

@ जोशुआ - आपके URL पर आपका कोड मेरे काम नहीं आया। base_encode () केवल उन संख्याओं के लिए एक एन्कोडेड अंक उत्पन्न करता है जो मैंने परीक्षण किए थे।
एसएमग्रीनफील्ड

4

अगर आपको किसी चीज़ को एनकोड / डीकोड करने के बजाय एक छोटी आईडी (चूंकि आप URL शॉर्टर्स का उल्लेख करते हैं) उत्पन्न करना है, तो यह मॉड्यूल निम्न हो सकता है:

https://github.com/stochastic-technologies/shortuuid/


मुझे यकीन नहीं है कि छोटे URL के लिए उपयुक्त है। एक UUID आमतौर पर एक बहुत बड़ी संख्या होती है, इसलिए यह भी base57 एन्कोडिंग की तरह वह एक छोटे URL के लिए लंबे समय तक होना बाध्य है।
मिकाल

आप बस उतना ही काट सकते हैं जितना आप चाहते हैं, टक्कर अभी भी संभावना नहीं होगी क्योंकि यह पूरी तरह से यादृच्छिक है, लेकिन कोई भी विशिष्ट आईडी नहीं होगी।
स्टावरोस कोरोकिथेकस

4

यदि आप django ढांचे का उपयोग करते हैं, तो आप django.utils.baseconv मॉड्यूल का उपयोग कर सकते हैं।

>>> from django.utils import baseconv
>>> baseconv.base62.encode(1234567890)
1LY7VK

बेस 62 के अलावा, बेसकॉनव ने बेस 2 / बेस 16 / बेस 36 / बेस 56 / बेस 64 को भी परिभाषित किया।


3

आप शायद base64 चाहते हैं, base62 नहीं। इसके चारों ओर एक यूआरएल-संगत संस्करण चल रहा है, इसलिए अतिरिक्त दो भराव पात्रों को कोई समस्या नहीं होनी चाहिए।

प्रक्रिया काफी सरल है; विचार करें कि बेस 64 6 बिट्स का प्रतिनिधित्व करता है और एक नियमित बाइट का प्रतिनिधित्व करता है। चुने गए 64 पात्रों में से प्रत्येक के लिए 000000 से 111111 तक मान असाइन करें, और 3 बेस 256 बाइट्स के सेट से मिलान करने के लिए 4 मानों को एक साथ रखें। 3 बाइट्स के प्रत्येक सेट के लिए दोहराएं, पैडिंग चरित्र की अपनी पसंद के साथ अंत में पैडिंग (0 आम तौर पर उपयोगी है)।


5
मानक पायथन बेस 64 एन्कोडिंग विधियां वास्तव में शॉर्ट यूआरएल के लिए उपयुक्त नहीं हैं, क्योंकि यह एन्कोडिंग बाइट्स (यानी। स्ट्रिंग्स / पत्र) के लिए अनुकूलित है, और संख्यात्मक मान को आधार-शिफ्टिंग की तुलना में लंबे समय तक आउटपुट देगा।
mikl

@ निश्चित रूप से, पायथन का बेस 64 मॉड्यूल लघु URL उत्पन्न करने के लिए उपयुक्त नहीं हो सकता है, लेकिन पायथन के सभी एन्कोडिंग तरीके वास्तव में बेस-256 नंबर अनुक्रमों पर काम कर रहे हैं। बाइट्स वास्तव में बेस- 256 "स्ट्रिंग्स" एन्कोडेड हैं। पायथन 2.x स्ट्रिंग्स को बाइट्स के अनुक्रम के रूप में मानता है, जबकि पायथन 3.x (जो सही काम करता है) स्ट्रिंग्स को यूनिकोड मानता है। तो b'foobar 'वास्तव में [102, 111, 111, 98, 97, 114] या [0x66,0x6f, 0x6f, 0x62,0x61,0x72] या b' x66 \ x6f \ x6f \ _ लिखने का एक फैंसी तरीका है x62 \ x61 \ x72 'जो अनिश्चित रूप से बेस-256 प्रतिनिधित्व है। बाइट्स तार या अक्षर नहीं हैं। बाइट्स बाइट्स हैं। =)
यसदीप

@yesudeep: तो, बाइट्स बाइट्स हैं ... और वास्तव में आपकी बात क्या है?

3

इसके लिए अब एक अजगर पुस्तकालय है।

मैं इसके लिए एक पाइप पैकेज बनाने पर काम कर रहा हूं।

मैं आपको अपने bases.py https://github.com/kamijoutouma/bases.py का उपयोग करने की सलाह देता हूं, जो bases.Ds से प्रेरित था

from bases import Bases
bases = Bases()

bases.toBase16(200)                // => 'c8'
bases.toBase(200, 16)              // => 'c8'
bases.toBase62(99999)              // => 'q0T'
bases.toBase(200, 62)              // => 'q0T'
bases.toAlphabet(300, 'aAbBcC')    // => 'Abba'

bases.fromBase16('c8')               // => 200
bases.fromBase('c8', 16)             // => 200
bases.fromBase62('q0T')              // => 99999
bases.fromBase('q0T', 62)            // => 99999
bases.fromAlphabet('Abba', 'aAbBcC') // => 300

आधारभूत क्या हैं, इसके लिए https://github.com/kamijoutouma/bases.py# परिचित-basesalphabets का संदर्भ लें


2

आप pypi से zbase62 मॉड्यूल डाउनलोड कर सकते हैं

जैसे

>>> import zbase62
>>> zbase62.b2a("abcd")
'1mZPsa'

2
हाँ, मैंने उस पर पहले देखा था, लेकिन यह स्ट्रिंग्स को परिवर्तित करता है, नंबरों को नहीं :)
mikl

2

मुझे यहां दूसरों के पदों से बहुत लाभ हुआ है। मुझे मूल रूप से एक Django परियोजना के लिए अजगर कोड की आवश्यकता थी, लेकिन तब से मैंने नोड.जेएस की ओर रुख किया है, इसलिए यहां कोड का एक जावास्क्रिप्ट संस्करण (एन्कोडिंग भाग) है जिसे बैशम्पायन घोष ने प्रदान किया है।

var ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

function base62_encode(n, alpha) {
  var num = n || 0;
  var alphabet = alpha || ALPHABET;

  if (num == 0) return alphabet[0];
  var arr = [];
  var base = alphabet.length;

  while(num) {
    rem = num % base;
    num = (num - rem)/base;
    arr.push(alphabet.substring(rem,rem+1));
  }

  return arr.reverse().join('');
}

console.log(base62_encode(2390687438976, "123456789ABCDEFGHIJKLMNPQRSTUVWXYZ"));

मैंने इस कोड को अपडेट किया है और इसे किसी भी ओपन सोर्स प्रोजेक्ट में बनाया है, जो github.com/sbussard/encode-the-things
स्टीफन

2

मुझे आशा है कि निम्नलिखित स्निपेट मदद कर सकता है।

def num2sym(num, sym, join_symbol=''):
    if num == 0:
        return sym[0]
    if num < 0 or type(num) not in (int, long):
        raise ValueError('num must be positive integer')

    l = len(sym)  # target number base
    r = []
    div = num
    while div != 0: # base conversion
        div, mod = divmod(div, l)
        r.append(sym[mod])

    return join_symbol.join([x for x in reversed(r)])

आपके मामले के लिए उपयोग:

number = 367891
alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
print num2sym(number, alphabet)  # will print '1xHJ'

जाहिर है, आप किसी अन्य वर्णमाला को निर्दिष्ट कर सकते हैं, जिसमें कम या अधिक संख्या में प्रतीक शामिल हैं, फिर यह आपके नंबर को कम या अधिक संख्या आधार में बदल देगा। उदाहरण के लिए, एक वर्णमाला के रूप में '01' प्रदान करना स्ट्रिंग को बाइनरी के रूप में इनपुट संख्या का प्रतिनिधित्व करेगा।

आप संख्याओं के अपने अनूठे प्रतिनिधित्व के लिए शुरुआत में वर्णमाला को फेरबदल कर सकते हैं। यदि आप URL शॉर्टनर सेवा बना रहे हैं तो यह उपयोगी हो सकता है।


1
बुरा नहीं। आप उपयोग करना चाह सकते हैं if num < 0 or type(num) not in (int, long):
मार्टीन्यू

यह बेहतर है, लेकिन यह थोड़ा अधिक जटिल है क्योंकि longPy 3.x में मौजूद नहीं है - इसलिए कोई भी इस उत्तर का उपयोग कर सकता है
मार्टीन्यू

1
या मेरे अपने पोर्टेबल संस्करण का उपयोग करें isinstance(x, (type(1), type(2**32))):।
मार्टीन्यू

2

यहाँ मेरा समाधान है:

def base62(a):
    baseit = (lambda a=a, b=62: (not a) and '0' or
        baseit(a-a%b, b*62) + '0123456789abcdefghijklmnopqrstuvwxyz'
                              'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[a%b%61 or -1*bool(a%b)])
    return baseit()

व्याख्या

किसी भी आधार में हर संख्या समान है a1+a2*base**2+a3*base**3... इसलिए लक्ष्य सभी as को खोजना है ।

प्रत्येक N=1,2,3...कोड के लिए aN*base**N"moduloing" द्वारा अलग-थलग कर दिया जाता है b, b=base**(N+1)जिसके लिए स्लाइस सभी की aतुलना में बड़े होते हैं N, और सभी एस को स्लाइस करते हैं aताकि उनके धारावाहिक को हर बार Nघटने से छोटा किया जाए a, जिसे फ़ंक्शन वर्तमान द्वारा पुनरावृत्ति कहा जाता है aN*base**N

Base%(base-1)==1इसलिए base**p%(base-1)==1और इसलिए q*base^p%(base-1)==qकेवल एक अपवाद के साथ, जब q==base-1वह लौटता है 0। उस मामले को ठीक करने के लिए यह वापस आ जाता है 0। फ़ंक्शन 0शुरुआत से जांचता है ।


फायदे

इस नमूने में केवल एक गुणा (एक विभाजन के बजाय) और कुछ मापांक संचालन हैं, जो सभी अपेक्षाकृत तेज़ हैं।


1

व्यक्तिगत रूप से मुझे बैशम्पायन से समाधान पसंद है, ज्यादातर भ्रमित चरित्रों को अलग करने के कारण।

पूर्णता, और बेहतर प्रदर्शन के साथ समाधान के लिए, यह पोस्ट पायथन बेस 64 मॉड्यूल का उपयोग करने का एक तरीका दिखाता है।


1
जैसा कि विलीहैम टोटलैंड के लिए मेरी टिप्पणी में उल्लेख किया गया है, पायथन बेस 64 एन्कोडिंग संख्याओं के लिए उप-रूपी है, क्योंकि यह तार के लिए अनुकूलित है।
mikl

1

मैंने इसे कुछ समय पहले लिखा था और इसने बहुत अच्छा काम किया (नकारात्मक और सभी शामिल)

def code(number,base):
    try:
        int(number),int(base)
    except ValueError:
        raise ValueError('code(number,base): number and base must be in base10')
    else:
        number,base = int(number),int(base)
    if base < 2:
        base = 2
    if base > 62:
        base = 62
    numbers = [0,1,2,3,4,5,6,7,8,9,"a","b","c","d","e","f","g","h","i","j",
               "k","l","m","n","o","p","q","r","s","t","u","v","w","x","y",
               "z","A","B","C","D","E","F","G","H","I","J","K","L","M","N",
               "O","P","Q","R","S","T","U","V","W","X","Y","Z"]
    final = ""
    loc = 0
    if number < 0:
        final = "-"
        number = abs(number)
    while base**loc <= number:
        loc = loc + 1
    for x in range(loc-1,-1,-1):
        for y in range(base-1,-1,-1):
            if y*(base**x) <= number:
                final = "{}{}".format(final,numbers[y])
                number = number - y*(base**x)
                break
    return final

def decode(number,base):
    try:
        int(base)
    except ValueError:
        raise ValueError('decode(value,base): base must be in base10')
    else:
        base = int(base)
    number = str(number)
    if base < 2:
        base = 2
    if base > 62:
        base = 62
    numbers = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f",
               "g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v",
               "w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L",
               "M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
    final = 0
    if number.startswith("-"):
        neg = True
        number = list(number)
        del(number[0])
        temp = number
        number = ""
        for x in temp:
            number = "{}{}".format(number,x)
    else:
        neg = False
    loc = len(number)-1
    number = str(number)
    for x in number:
        if numbers.index(x) > base:
            raise ValueError('{} is out of base{} range'.format(x,str(base)))
        final = final+(numbers.index(x)*(base**loc))
        loc = loc - 1
    if neg:
        return -final
    else:
        return final

यह सब की लंबाई के बारे में खेद है


1
BASE_LIST = tuple("23456789ABCDEFGHJKLMNOPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz")
BASE_DICT = dict((c, v) for v, c in enumerate(BASE_LIST))
BASE_LEN = len(BASE_LIST)

def nice_decode(str):
    num = 0
    for char in str[::-1]:
        num = num * BASE_LEN + BASE_DICT[char]
    return num

def nice_encode(num):
    if not num:
        return BASE_LIST[0]

    encoding = ""
    while num:
        num, rem = divmod(num, BASE_LEN)
        encoding += BASE_LIST[rem]
    return encoding

1
यह BASE_LIST के नाम को ठीक करता है और स्ट्रिंग को डिकोडिंग पर भी उलटता है जो
स्पेरो

1

यहाँ ऐसा करने के लिए एक पुनरावृत्ति और पुनरावृत्ति तरीका है। निष्पादन की गिनती के आधार पर पुनरावृत्ति थोड़ी तेज है।

def base62_encode_r(dec):
    s = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    return s[dec] if dec < 62 else base62_encode_r(dec / 62) + s[dec % 62]
print base62_encode_r(2347878234)

def base62_encode_i(dec):
    s = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    ret = ''
    while dec > 0:
        ret = s[dec % 62] + ret
        dec /= 62
    return ret
print base62_encode_i(2347878234)

def base62_decode_r(b62):
    s = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    if len(b62) == 1:
        return s.index(b62)
    x = base62_decode_r(b62[:-1]) * 62 + s.index(b62[-1:]) % 62
    return x
print base62_decode_r("2yTsnM")

def base62_decode_i(b62):
    s = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    ret = 0
    for i in xrange(len(b62)-1,-1,-1):
        ret = ret + s.index(b62[i]) * (62**(len(b62)-i-1))
    return ret
print base62_decode_i("2yTsnM")

if __name__ == '__main__':
    import timeit
    print(timeit.timeit(stmt="base62_encode_r(2347878234)", setup="from __main__ import base62_encode_r", number=100000))
    print(timeit.timeit(stmt="base62_encode_i(2347878234)", setup="from __main__ import base62_encode_i", number=100000))
    print(timeit.timeit(stmt="base62_decode_r('2yTsnM')", setup="from __main__ import base62_decode_r", number=100000))
    print(timeit.timeit(stmt="base62_decode_i('2yTsnM')", setup="from __main__ import base62_decode_i", number=100000))

0.270266867033
0.260915645986
0.344734796766
0.311662500262

मुझे आपका पुनरावर्ती दृष्टिकोण बहुत पसंद आया। मेरी बेटी, जो एपी कॉम्प साइंस ले रही थी, ने C ++ में एक "बेस 25" ('ABCDEFHJKMMPPRRWUVWXY34789 का उपयोग करके) को लागू करने के लिए मेरे लिए यही समाधान निकाला था। मैं इसे पायथन में परिवर्तित करने के लिए गया और उस भाषा के साथ कुल न्यूब होने के कारण कुछ ठोकरें लगीं - जिसे आपने कोड की एक पंक्ति में शान्ति से हल किया था! आप 0 से एक सामान्य समस्या से भी बचते हैं, 0-9 से शुरू नहीं होने वाले वर्णमाला में एक खाली स्ट्रिंग में अनुवाद करना। अच्छा कार्य! (मुझे नकारात्मक संख्याओं की आवश्यकता नहीं है, लेकिन आपका दृष्टिकोण इतना अच्छा था कि भविष्य के ब्राउज़रों के लिए इसे जोड़ना अच्छा हो सकता है)
SMGreenfield

1

अजगर 3.7.x

मुझे कुछ एल्गोरिदम के लिए एक पीएचडी की गिटब मिली जब एक मौजूदा बेस 62 स्क्रिप्ट की तलाश थी । यह इस समय पायथन 3 के वर्तमान अधिकतम संस्करण के लिए काम नहीं कर रहा था, इसलिए मैं आगे बढ़ा और तय किया कि जहां जरूरत हो और थोड़ा रिफैक्टिंग किया। मैं आमतौर पर पायथन के साथ काम नहीं करता हूं और हमेशा इसका इस्तेमाल किया है इसलिए YMMV का उपयोग करें। सारा श्रेय डॉ। झिहुआ लाई को जाता है । मैंने अभी-अभी पायथन के इस संस्करण के लिए काम किया है।

फ़ाइल base62.py

#modified from Dr. Zhihua Lai's original on GitHub
from math import floor
base = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
b = 62;
def toBase10(b62: str) -> int:
    limit = len(b62)
    res = 0
    for i in range(limit):
        res = b * res + base.find(b62[i])
    return res
def toBase62(b10: int) -> str:
    if b <= 0 or b > 62:
        return 0
    r = b10 % b
    res = base[r];
    q = floor(b10 / b)
    while q:
        r = q % b
        q = floor(q / b)
        res = base[int(r)] + res
    return res

फ़ाइल try_base62.py

import base62
print("Base10 ==> Base62")
for i in range(999):
    print(f'{i} => {base62.toBase62(i)}')
base62_samples = ["gud", "GA", "mE", "lo", "lz", "OMFGWTFLMFAOENCODING"]
print("Base62 ==> Base10")
for i in range(len(base62_samples)):
    print(f'{base62_samples[i]} => {base62.toBase10(base62_samples[i])}')

का उत्पादन try_base62.py

Base10 ==> Base62
0 => 0
[...]
998 => g6
Base62 ==> Base10
gud => 63377
GA => 2640
mE => 1404
lo => 1326
lz => 1337
OMFGWTFLMFAOENCODING => 577002768656147353068189971419611424

चूंकि रेपो में कोई लाइसेंसिंग जानकारी नहीं थी, इसलिए मैंने एक पीआर सबमिट किया था ताकि मूल लेखक कम से कम यह जान सके कि अन्य लोग उनके कोड का उपयोग और संशोधन कर रहे हैं।


0

क्षमा करें, मैं यहां लाइब्रेरी के साथ आपकी मदद नहीं कर सकता। मैं बेस 64 का उपयोग करना पसंद करूंगा और यदि संभव हो तो अतिरिक्त पात्रों को जोड़ सकता हूं - यदि संभव हो तो!

फिर आप बेस 64 मॉड्यूल का उपयोग कर सकते हैं।

यदि यह वास्तव में है, तो वास्तव में संभव नहीं है:

आप इसे स्वयं इस तरह से कर सकते हैं (यह छद्म कोड है):

base62vals = []
myBase = 62
while num > 0:
   reminder = num % myBase
   num = num / myBase
   base62vals.insert(0, reminder)

0

सरल पुनरावृत्ति के साथ

"""
This module contains functions to transform a number to string and vice-versa
"""
BASE = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
LEN_BASE = len(BASE)


def encode(num):
    """
    This function encodes the given number into alpha numeric string
    """

    if num < LEN_BASE:
        return BASE[num]

    return BASE[num % LEN_BASE] + encode(num//LEN_BASE)


def decode_recursive(string, index):
    """
    recursive util function for decode
    """

    if not string or index >= len(string):
        return 0

    return (BASE.index(string[index]) * LEN_BASE ** index) + decode_recursive(string, index + 1)


def decode(string):
    """
    This function decodes given string to number
    """

    return decode_recursive(string, 0)


0

सबसे सरल कभी।

BASE62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
def encode_base62(num):
    s = ""
    while num>0:
      num,r = divmod(num,62)
      s = BASE62[r]+s
    return s


def decode_base62(num):
   x,s = 1,0
   for i in range(len(num)-1,-1,-1):
      s = int(BASE62.index(num[i])) *x + s
      x*=62
   return s

print(encode_base62(123))
print(decode_base62("1Z"))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.