Основывайте 62 преобразования

Скомпилированный язык всегда собирается потребовать большей начальной буквы наверху, чем интерпретируемый язык. Кроме того, возможно, Вы не структурировали свой код C++ очень хорошо. Например:

#include "BigClass.h"

class SmallClass
{
   BigClass m_bigClass;
}

Компиляции намного медленнее, чем:

class BigClass;

class SmallClass
{
   BigClass* m_bigClass;
}
77
задан martineau 16 June 2016 в 19:20
поделиться

7 ответов

There is no standard module for this, but I have written my own functions to achieve that.

BASE62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

def encode(num, alphabet=BASE62):
    """Encode a positive number in Base X

    Arguments:
    - `num`: The number to encode
    - `alphabet`: The alphabet to use for encoding
    """
    if num == 0:
        return alphabet[0]
    arr = []
    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 encoding
    """
    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

Notice the fact that you can give it any alphabet to use for encoding and decoding. If you leave the alphabet argument out, you are going to get the 62 character alphabet defined on the first line of code, and hence encoding/decoding to/from 62 base.

Hope this helps.

PS - For URL shorteners, I have found that it's better to leave out a few confusing characters like 0Ol1oI etc. Thus I use this alphabet for my URL shortening needs - "23456789abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"

Have fun.

148
ответ дан 24 November 2019 в 10:46
поделиться

You probably want base64, not base62. There's an URL-compatible version of it floating around, so the extra two filler characters shouldn't be a problem.

The process is fairly simple; consider that base64 represents 6 bits and a regular byte represents 8. Assign a value from 000000 to 111111 to each of the 64 characters chosen, and put the 4 values together to match a set of 3 base256 bytes. Repeat for each set of 3 bytes, padding at the end with your choice of padding character (0 is generally useful).

4
ответ дан 24 November 2019 в 10:46
поделиться

Sorry, I can't help you with a library here. I would prefer using base64 and just adding to extra characters to your choice -- if possible!

Then you can use the base64 module.

If this is really, really not possible:

You can do it yourself this way (this is pseudo-code):

base62vals = []
myBase = 62
while num > 0:
   reminder = num % myBase
   num = num / myBase
   base62vals.insert(0, reminder)
0
ответ дан 24 November 2019 в 10:46
поделиться

you can download zbase62 module from pypi

eg

>>> import zbase62
>>> zbase62.b2a("abcd")
'1mZPsa'
2
ответ дан 24 November 2019 в 10:46
поделиться

Лично мне нравится решение от Baishampayan, в основном из-за удаления сбивающих с толку символов.

Для полноты и решения с лучшей производительностью, этот пост показывает способ использования модуля Python base64.

1
ответ дан 24 November 2019 в 10:46
поделиться

Следующий декодер -maker работает с любой разумной базой, имеет гораздо более аккуратный цикл и выдает явное сообщение об ошибке, когда встречает недопустимый символ.

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)
9
ответ дан 24 November 2019 в 10:46
поделиться

Однажды я написал сценарий для этого, я думаю, что это довольно элегантно :)

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)
45
ответ дан 24 November 2019 в 10:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: