Como você converteria um número inteiro em base 62 (como hexadecimal, mas com estes dígitos: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ').
Tenho tentado encontrar uma boa biblioteca Python para ele, mas todos parecem estar ocupados com a conversão de strings. O módulo Python base64 aceita apenas strings e transforma um único dígito em quatro caracteres. Eu estava procurando por algo semelhante ao que os encurtadores de URL usam.
Respostas:
Não existe um módulo padrão para isso, mas escrevi minhas próprias funções para fazer isso.
Observe o fato de que você pode fornecer qualquer alfabeto para usar na codificação e decodificação. Se você deixar o
alphabet
argumento de fora, obterá o alfabeto de 62 caracteres definido na primeira linha do código e, portanto, a codificação / decodificação de / para a base 62.Espero que isto ajude.
PS - Para encurtadores de URL, descobri que é melhor deixar alguns caracteres confusos como 0Ol1oI etc. Portanto, uso este alfabeto para minhas necessidades de encurtamento de URL -
"23456789abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"
Diverta-se.
fonte
$-_.+!*'(),;/?:@&=
Você provavelmente pode usar alguns outros personagens também, como[]~
etc.Uma vez escrevi um script para fazer isso também, acho que é bastante elegante :)
Exemplo de uso:
fonte
reversed(string)
mais rápido do que fatiarstring[::-1]
na função base_decode.integer /= length
parainteger //=length
para obter o resto corretoO fabricante de decodificadores a seguir funciona com qualquer base razoável, tem um loop muito mais organizado e fornece uma mensagem de erro explícita quando encontra um caractere inválido.
fonte
**
operador no loop.Se você está procurando a mais alta eficiência (como django), você vai querer algo como o seguinte. Este código é uma combinação de métodos eficientes de Baishampayan Ghose e WoLpH e John Machin.
Você também pode calcular o seu dicionário com antecedência. (Observação: a codificação com uma string mostra mais eficiência do que com uma lista, mesmo com números muito longos.)
Codificou e decodificou 1 milhão de números em menos de 2,5 segundos. (2,2 Ghz i7-2670QM)
fonte
tuple()
redorBASE_ALPH
no início. Em Python, cada String é iterável. Esse recurso é explorado porenumerate()
. Então o código fica ainda mais enxuto :)Se você usar o framework django, você pode usar o módulo django.utils.baseconv.
Além de base62, o baseconv também definiu base2 / base16 / base36 / base56 / base64.
fonte
Você provavelmente deseja base64, não base62. Há uma versão compatível com URL dele circulando, então os dois caracteres de preenchimento extras não devem ser um problema.
O processo é bastante simples; considere que base64 representa 6 bits e um byte regular representa 8. Atribua um valor de 000000 a 111111 a cada um dos 64 caracteres escolhidos e coloque os 4 valores juntos para corresponder a um conjunto de 3 bytes base256. Repita para cada conjunto de 3 bytes, preenchendo no final com sua escolha de caractere de preenchimento (0 geralmente é útil).
fonte
Se tudo o que você precisa é gerar um ID curto (já que você mencionou encurtadores de URL) em vez de codificar / decodificar algo, este módulo pode ajudar:
https://github.com/stochastic-technologies/shortuuid/
fonte
você pode baixar o módulo zbase62 de pypi
por exemplo
fonte
Eu me beneficiei muito das postagens de outros aqui. Eu precisava do código python originalmente para um projeto Django, mas desde então eu mudei para node.js, então aqui está uma versão javascript do código (a parte de codificação) que Baishampayan Ghose forneceu.
fonte
Espero que o seguinte snippet possa ajudar.
Uso para o seu caso:
Obviamente, você pode especificar outro alfabeto, consistindo em um número maior ou menor de símbolos, então ele converterá seu número para a base numérica menor ou maior. Por exemplo, fornecer '01' como um alfabeto produzirá uma string que representa o número de entrada como binário.
Você pode embaralhar o alfabeto inicialmente para ter uma representação única dos números. Pode ser útil se você estiver fazendo um serviço de encurtador de URL.
fonte
if num < 0 or type(num) not in (int, long):
.long
não existe no Py 3.x - então, pode-se querer usar esta resposta .isinstance(x, (type(1), type(2**32)))
.Agora existe uma biblioteca python para isso.
Estou trabalhando em fazer um pacote pip para isso.
Eu recomendo que você use meu bases.py https://github.com/kamijoutouma/bases.py que foi inspirado em bases.js
consulte https://github.com/kamijoutouma/bases.py#known-basesalphabets para saber quais bases são utilizáveis
fonte
Esta é minha solução:
explicação
Em qualquer base, cada número é igual a
a1+a2*base**2+a3*base**3...
Portanto, o objetivo é encontrar todos osa
s.Para cada
N=1,2,3...
código isola oaN*base**N
por "moduloing" porb
parab=base**(N+1)
que corta todoa
é maior do queN
, e cortando todo oa
é de modo que sua série é menor do queN
diminuindoa
cada vez que a função é chamada de forma recursiva pela correnteaN*base**N
.Base%(base-1)==1
portantobase**p%(base-1)==1
e, portanto,q*base^p%(base-1)==q
com apenas uma exceção, quandoq==base-1
que retorna0
. Para consertar esse caso, ele retorna0
. A função verifica0
desde o início.vantagens
Neste exemplo, há apenas uma multiplicação (em vez de uma divisão) e algumas operações de módulo, que são todas relativamente rápidas.
fonte
Pessoalmente, gosto da solução de Baishampayan, principalmente por despir os personagens confusos.
Para integridade e solução com melhor desempenho, este post mostra uma forma de usar o módulo Python base64.
fonte
Escrevi isso há um tempo e funcionou muito bem (negativos e todos incluídos)
desculpe pela duração de tudo
fonte
fonte
Aqui está uma maneira recorrente e iterativa de fazer isso. O iterativo é um pouco mais rápido dependendo da contagem de execução.
fonte
Pitão
3.7.x
Encontrei um github de PhD para alguns algoritmos ao procurar um script base62 existente . Não funcionou para a versão max atual do Python 3 neste momento, então fui em frente e consertei onde necessário e fiz uma pequena refatoração. Eu normalmente não trabalho com Python e sempre usei ad-hoc, então YMMV. Todo o crédito vai para o Dr. Zhihua Lai . Acabei de resolver os problemas desta versão do Python.
Arquivo
base62.py
Arquivo
try_base62.py
saída de
try_base62.py
Como não havia informações de licenciamento no repo, eu enviei um PR para que o autor original pelo menos saiba que outras pessoas estão usando e modificando seu código.
fonte
Não posso ajudá-lo com uma biblioteca aqui. Eu preferiria usar base64 e apenas adicionar caracteres extras à sua escolha - se possível!
Então você pode usar o módulo base64.
Se isso for realmente impossível:
Você pode fazer isso sozinho (este é um pseudocódigo):
fonte
com recursão simples
fonte
Mais simples de todos.
fonte