বেস 62 রূপান্তর


92

আপনি কীভাবে একটি পূর্ণসংখ্যাকে 62 এর বেসে রূপান্তর করবেন (হেক্সাডেসিমালের মতো তবে এই সংখ্যাগুলির সাথে: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')।

আমি এটির জন্য একটি ভাল পাইথন গ্রন্থাগার সন্ধান করার চেষ্টা করেছি, তবে তারা সমস্তগুলি রূপান্তরকারী স্ট্রিংয়ের সাথে দখল করা বলে মনে হচ্ছে। পাইথন বেস 64 মডিউলটি কেবল স্ট্রিং গ্রহণ করে এবং একক অঙ্ককে চারটি অক্ষরে রূপান্তরিত করে। আমি ইউআরএল সংক্ষিপ্তকারীরা কী ব্যবহার করে তার অনুরূপ কিছু খুঁজছিলাম।


কেউ সবেমাত্র একটি ওপেন সোর্স প্রকল্পের ধারণা পেয়েছে বলে মনে হচ্ছে :) আপনি যদি কিছু খুঁজে পান বা আপনার নিজের তৈরি করার সিদ্ধান্ত নেন তবে আমাকে জানান ...
সামজ

আপনি যদি সংক্ষিপ্ত ইউআরএল তৈরি করতে চান তবে আপনি পুরো অক্ষরগুলির গোছাতে ব্যবহার করতে পারেন যা এনকোড করার দরকার নেই: en.wikedia.org/wiki/Percent-encoding#Types_of_URI_characters । এটি characters 66 টি অক্ষর।
l0b0

আমি মনে করি কেবল ব্যবহারকারীর বিভ্রান্তি এড়াতে আমি বিন্দু এবং টিলডে পাশ করব, তবে ড্যাশ এবং আন্ডারস্কোরগুলি যথাযথ সংযোজন হওয়া উচিত, ধন্যবাদ।
মিক্ল

বেস 64 সম্পর্কে কী? আপনার জন্য আরও ভাল ভাগ্যবান গ্রন্থাগার সন্ধান করতে পারে।
মাইক কুপার

এই প্রশ্নের বেশ কয়েকটি প্রযোজ্য উত্তর রয়েছে: স্ট্যাকওভারফ্লো.com
মাইলস

উত্তর:


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 টি অক্ষরের বর্ণমালা কোডের প্রথম লাইনে সংজ্ঞায়িত করতে যাচ্ছেন এবং অতএব এনকোডিং / dec২ বেস থেকে ডিকোডিং করছেন।

আশাকরি এটা সাহায্য করবে.

পিএস - ইউআরএল সংক্ষিপ্তকারীদের জন্য, আমি খুঁজে পেয়েছি যে 0Ol1oI ইত্যাদির মতো কয়েকটি বিভ্রান্তিকর অক্ষর ছেড়ে দেওয়া ভাল Thus "23456789abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"

আনন্দ কর.


4
+1: দুর্দান্ত! এখানে এবং সেখানে একটি অক্ষর সম্ভবত সংরক্ষণ করতে আরও URL- বান্ধব অক্ষরগুলির সাথে এটি বাড়ানো যেতে পারে। আমার জানা অক্ষরগুলি নিরাপদ: $-_.+!*'(),;/?:@&= আপনি সম্ভবত অন্যান্য কিছু অক্ষর []~ইত্যাদি ব্যবহার করতে পারেন
Blixt

24
নামকরণ বাগ: বর্ণমালাটি অনুকূলিতকরণযোগ্য হওয়ায় এটি 62 ভিত্তিতে নয়।
বিনোদন

4
ডিকোডের জন্য, শক্তিগুলি গণনা না করাই একটি ভাল অভ্যাস (সময় সাশ্রয় করা, লেখার চেয়ে খাটো, তবে আরও গুরুত্বপূর্ণভাবে একের পর এক ত্রুটিগুলি এড়ানো যায়), এভাবে: num = 0; স্ট্রিংয়ে চরের জন্য: সংখ্যা = সংখ্যা * বেস + বর্ণমালা.ইন্ডেক্স (চর)
শ্রীভাতসার

4
@ শ্রীভাতসার: ডিকশনারি দেখার পরিবর্তে str.index () ব্যবহারের কোনও বিশেষ কারণ? আমার উত্তর দেখুন ...
জন মাচিন

4
>>> 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 পুনরাবৃত্তি): সংস্করণ-ওওএলপিএইচ: .403 .399 .399 .398 .398 | সংস্করণ-বৈশম্পায়ন: 1.783 1.785 1.782 1.788 1.784। এই সংস্করণটি প্রায় 4x হিসাবে দ্রুত।
জর্ডান

যদি বেস_ডেকোড ফাংশনে reversed(string)স্লাইসিংয়ের চেয়ে আরও দ্রুত ব্যবহার করা string[::-1]হয়।
ENDOH টাকানাও

4
এই প্রশ্নটি খুঁজতে আমাকে দীর্ঘ সময় নিয়েছে। কখনই জানত না এটাকে বেস 62 রূপান্তর বলা হয়। চমৎকার উত্তর.

4
সঠিক integer /= lengthinteger //=length
বাকীটি

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)

যদিও আমি সম্ভবত এটি ব্যবহার করব না, আমি আপনাকে সৃজনশীলতার জন্য থাম্বসও দিয়েছিলাম। এই কোডটি আমাকে একটি হাসি দিয়েছে। :)
সেপিরো

@ সেপিরো: এত মজার কী? এটি মারাত্মক শক্তিশালী শিল্প-শক্তি সফ্টওয়্যার। কোনও মিকি-মাউস লুপটিতে কোনও **অপারেটরের সাথে বিপরীত হয় না।
জন মাচিন

নিজেকে শান্ত করুন বন্ধু। তুমি ঠিক বলছো. প্রশ্নের সাথে সম্পর্কিত নয় এমন জিনিসগুলির মধ্যে এটি সমাহিত হওয়ার কারণে আমি আপনার অভ্যন্তরীণ লুপটির সত্যিকারের সদ্ব্যবহার মিস করেছি (মোড়ানো, ত্রুটি পরীক্ষা করা, ইউনিট পরীক্ষা করা)।
সেপেরো

দেখতে দেখতে দুর্দান্ত, তবে আপনি কি কোনও "শিল্প-শক্তি" এনকোডারটি ভুলে যাননি যা একটি স্ট্রিং তৈরি করতে পূর্ণসংখ্যার বর্ণমালা লাগে?
মার্টিনো

4
সর্বশেষ মানটির কিউটি মান উত্থাপনের মানটি ইচ্ছাকৃত হয়েছিল?
থমাস ভ্যান্ডার স্টিচেল

8

আপনি যদি সর্বোচ্চ দক্ষতা (জ্যাঙ্গোর মতো) সন্ধান করেন, আপনি নীচের মতো কিছু চাইবেন want এই কোডটি বৈশম্পায়ন ঘোস এবং ওওএলপিএইচ এবং জন মাচিনের দক্ষ পদ্ধতির সংমিশ্রণ।

# 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 মিলিয়ন সেকেন্ডের মধ্যে 10 মিলিয়ন সংখ্যা এনকোডড এবং ডিকোড করা হয়েছে। (2.2Ghz i7-2670QM)


শুরুতে tuple()আশেপাশের প্রয়োজন হয় না BASE_ALPH। পাইথনে প্রতিটি স্ট্রিং পুনরাবৃত্ত হয়। এই বৈশিষ্ট্য অবশ্যই দ্বারা শোষণ করা হয় enumerate()। কোডটি আরও ঝোঁক হয়ে যায় :)
লুইস নেল

7
ওহে অরিজিনেল, আপনি ঠিক বলেছেন যে টিপল () দরকার নেই, তবে আমার সিস্টেমে এটি কোডটি প্রায় 20% দ্রুত চালিত করে। টিউপল () ছাড়াই এটি পরীক্ষা করে দেখুন এবং দেখুন আপনার জন্য কী সবচেয়ে ভাল কাজ করে। চিয়ার্স :)
সেপিরো

4
আকর্ষণীয় বিষয়। টিপলগুলি স্ট্রিংয়ের চেয়ে বেশি লাইটওয়েট হওয়ায় মোটামুটি বোঝায়। আলোকিত করার জন্য ধন্যবাদ :)!
লুইস নেল

@ সেপিরো আমি ফর্ম্যাটিং, নামকরণ, পরীক্ষা এবং কার্যকারিতা (নেতিবাচক সংখ্যাগুলি সমর্থিত) এর ক্ষেত্রে আপনার সংস্করণে আরও উন্নতি করেছি: পেস্টবিন.
com

@ জোছুয়া - আপনার ইউআরএলে আপনার কোড আমার পক্ষে কাজ করে নি। বেস_কেনড () দেখে মনে হয়েছিল যে আমি পরীক্ষিত নম্বরগুলির জন্য কেবল একটি এনকোডড অঙ্ক তৈরি করেছি।
এসএমগ্রিনফিল্ড

4

আপনার যদি প্রয়োজন হয় তবে কোনও কিছু এনকোড / ডিকোড করার পরিবর্তে একটি সংক্ষিপ্ত আইডি তৈরি করা (যেহেতু আপনি ইউআরএল সংক্ষিপ্ত উল্লেখ করেছেন), এই মডিউলটি সহায়তা করতে পারে:

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


আমি নিশ্চিত নই যে এটি সংক্ষিপ্ত ইউআরএলগুলির জন্য উপযুক্ত। একটি ইউইউডি সাধারণত একটি খুব বড় সংখ্যক হয়, সুতরাং এমনকি বেস57 এটিকে এনকোডিং করা যেমন একটি ছোট URL এর চেয়ে দীর্ঘতর হতে বাধ্য rather
মিক্ল

আপনি যতটা চান কাটতে পারেন, সংঘর্ষগুলি এখনও নিখুঁতভাবে এলোমেলো হওয়ার মতোই অসম্ভব, তবে আর কোনও অনন্য আইডি হবে না।
স্ট্যাভ্রোস করোকিঠাকিস

4

আপনি যদি জাঙ্গো কাঠামো ব্যবহার করেন, আপনি django.utils.baseconv মডিউলটি ব্যবহার করতে পারেন।

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

বেস 62 ছাড়াও, বেসকনভ বেস 2 / বেস 16 / বেস 36 / বেস56 / বেস 64 সংজ্ঞায়িত করে।


3

আপনি সম্ভবত বেস 62 চান না, বেস 62 চান। এটির একটি ইউআরএল-সামঞ্জস্যপূর্ণ সংস্করণ চারপাশে ভাসছে, সুতরাং অতিরিক্ত দুটি ফিলার অক্ষর একটি সমস্যা হওয়া উচিত নয়।

প্রক্রিয়া মোটামুটি সহজ; বিবেচনা করুন যে বেস 64 6 টি বিট প্রতিনিধিত্ব করে এবং একটি নিয়মিত বাইট 8 টি প্রতিনিধিত্ব করে 8 টি নির্বাচিত প্রতিটি 64 টি অক্ষরের জন্য 000000 থেকে 111111 পর্যন্ত একটি মান নির্ধারণ করুন এবং 3 বেস 256 বাইটের একটি সেট মেলে 4 মানকে এক সাথে রাখুন। প্রতিটি বাইটের প্রতিটি সেটের জন্য পুনরাবৃত্তি করুন, আপনার প্যাডিং চরিত্রের পছন্দ অনুসারে প্যাডিং (0 সাধারণত দরকারী)।


4
স্ট্যান্ডার্ড পাইথন বেস 64 এনকোডিং পদ্ধতিগুলি সংক্ষিপ্ত ইউআরএলগুলির জন্য সত্যই উপযুক্ত নয়, যেহেতু এটি এনকোডিং বাইটের (যেমন স্ট্রিংস / অক্ষরগুলি) জন্য অনুকূলিত, এবং কেবলমাত্র সংখ্যার মানকে বেস-শিফটিংয়ের চেয়ে দীর্ঘতর আউটপুট তৈরি করে।
মিক্ল

@ মিক্ল অবশ্যই, পাইথনের বেস 64 মডিউলটি সংক্ষিপ্ত ইউআরএল তৈরির জন্য উপযুক্ত নাও হতে পারে তবে পাইথনের সমস্ত এনকোডিং পদ্ধতি সত্যিই বেস -২ number 25 নম্বর সিকোয়েন্সগুলিতে কাজ করছে। বাইটগুলি হ'ল বেস -২66 এনকোডেড "স্ট্রিংস"। পাইথন ২.x স্ট্রিংকে বাইটের ক্রম হিসাবে গণ্য করে, যেখানে পাইথন ৩.x (যা সঠিক কাজ করে) স্ট্রিংগুলি ইউনিকোড হিসাবে বিবেচনা করে। সুতরাং বিফুবারটি সত্যিই কেবল লেখার এক অভিনব উপায় [102, 111, 111, 98, 97, 114] বা [0x66,0x6f, 0x6f, 0x62,0x61,0x72] বা বি '\ x66 \ x6f \ x6f \ x62 \ x61 \ x72 'যা আশ্চর্যজনকভাবে বেজ -২6 represent উপস্থাপনা। বাইটস স্ট্রিং বা অক্ষর নয়। বাইটস বাইট হয়। =)
হুদ্দীপ

@ আইসুদীপ: তো, বাইটস বাইটস… এবং আপনার বক্তব্য ঠিক কী?
মার্টিনিউ

3

এর জন্য এখন একটি অজগর গ্রন্থাগার রয়েছে।

আমি এটির জন্য একটি পাইপ প্যাকেজ তৈরির জন্য কাজ করছি।

আমি আপনাকে আমার বেস.পিটি https://github.com/kamijoutouma/bases.py ব্যবহার করার পরামর্শ দিচ্ছি যা বেসেস.জেএস দ্বারা অনুপ্রাণিত হয়েছিল

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#known-basesalphabets কি ঘাঁটি ব্যবহারযোগ্য জন্য


2

আপনি পিপিআই থেকে zbase62 মডিউলটি ডাউনলোড করতে পারেন

যেমন

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

4
হ্যাঁ, আমি এটি আগে দেখেছি, তবে এটি স্ট্রিংকে রূপান্তর করে, সংখ্যা নয় :)
মিক্ল

2

আমি এখানে অন্যের পোস্ট থেকে প্রচুর উপকার পেয়েছি। আমার মূলত একটি জ্যাঙ্গো প্রকল্পের জন্য পাইথন কোডের প্রয়োজন ছিল, তবে তখন থেকে আমি নোড.জেএস এ ফিরেছি, সুতরাং বৈশাম্পান ঘোষ যে সরবরাহ করেছিলেন কোডটির একটি জাভাস্ক্রিপ্ট সংস্করণ (এনকোডিং অংশ) এখানে রয়েছে।

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-thethings
স্টিফেন

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' বর্ণমালা হিসাবে সরবরাহ করা ইনপুট সংখ্যাটিকে বাইনারি হিসাবে উপস্থাপন করে স্ট্রিং আউটপুট দেয়।

সংখ্যার অনন্য প্রতিনিধিত্ব রাখতে আপনি প্রথমে বর্ণমালা বদল করতে পারেন। আপনি যদি ইউআরএল সংক্ষিপ্ততর পরিষেবা তৈরি করেন তবে এটি সহায়ক হতে পারে।


4
খারাপ না. আপনি ব্যবহার করতে পারেন if num < 0 or type(num) not in (int, long):
মার্টিনো

এটি আরও ভাল তবে এটি কিছুটা জটিল কারণ longপাই 3..x এ বিদ্যমান নেই - সুতরাং কেউ এই উত্তরটি ব্যবহার করতে চাইতে পারে ।
মার্টিনো

4
অথবা আমার নিজের পোর্টেবল ভার্সন ব্যবহার করুন: 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...তাই লক্ষ্যটি সমস্ত aগুলি খুঁজে পাওয়া।

প্রতিটি N=1,2,3...কোডের জন্য aN*base**N"মডিউলিং" দ্বারা বিচ্ছিন্ন করা হয় যার bজন্য সমস্তগুলি এর চেয়ে বড় বড় করে কেটে যায় এবং b=base**(N+1)সমস্ত এসকে টুকরো করে দেয় যাতে তাদের সিরিয়ালটি প্রতিটি সময়কে হ্রাস করার চেয়ে ছোট করে বর্তমানকে পুনরাবৃত্তভাবে বলা হয় ।aNaNaaN*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 মডিউলটি ব্যবহার করার একটি উপায় দেখায়।


4
উইলিয়াম টটল্যান্ডের কাছে আমার মন্তব্যে যেমন উল্লেখ করা হয়েছে, পাইথনস বেস 64 এনকোডিং সংখ্যার জন্য সাবঅপটিমাল, যেহেতু এটি স্ট্রিংয়ের জন্য অনুকূলিত।
মিক্ল

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

4
এটি 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

আমি সত্যিই আপনার পুনরাবৃত্ত পদ্ধতির পছন্দ। আমার মেয়ে, যিনি এপি কম্প সায় নিচ্ছিলেন, সি ++ এ একটি "বেস 25" ('ABCDEFHJKMNPQRTUVWXY34789' ব্যবহার করে) বাস্তবায়নের জন্য আমার জন্য একই সমাধানটি আবিষ্কার করেছিলেন। আমি এটিকে পাইথনে রূপান্তর করতে গিয়েছিলাম এবং সেই ভাষার সাথে সম্পূর্ণ নতুন হয়ে কয়েকটা হোঁচট খেয়েছি - যা আপনি কোডের একক লাইনে মার্জিতভাবে সমাধান করেছেন! এমনকি আপনি 0-9 দিয়ে শুরু না হওয়া বর্ণমালার ফাঁকা স্ট্রিংয়ে 0 টি অনুবাদ করে একটি সাধারণ সমস্যা এড়াতে পারেন। মহান কাজ! (আমার নেতিবাচক সংখ্যার দরকার নেই, তবে আপনার দৃষ্টিভঙ্গি এত ভাল ছিল ভবিষ্যতের ব্রাউজারগুলির জন্য এটি যুক্ত করে ভাল লাগতে পারে)
এসএমগ্রিনফিল্ড

1

পাইথন 3.7.x

বিদ্যমান বেস 62 স্ক্রিপ্ট সন্ধান করার সময় আমি কিছু অ্যালগরিদমের জন্য পিএইচডি এর গিথব পেয়েছি । পাইথন 3 এর বর্তমান সর্বাধিক সংস্করণটির জন্য এটি কার্যকর হয়নি তাই আমি এগিয়ে গিয়ে যেখানে প্রয়োজন সেখানে স্থির হয়েছি এবং কিছুটা রিফ্যাক্টরিং করেছি। আমি পাইথনের সাথে সাধারণত কাজ করি না এবং সর্বদা এটি ওয়াইএমএমভি হিসাবে অ্যাড-হক ব্যবহার করি। সমস্ত কৃতিত্ব ডঃ জিহুয়া লাইকে । পাইথনের এই সংস্করণটির জন্য আমি কেবল কিঙ্কসকে কাজ করেছি।

ফাইল 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"))
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.