Codificar / descodificar Base62

Converta um número ou uma cadeia de bytes com Base62: 62 caracteres formados por dígitos, letras maiúsculas e letras minúsculas, nenhum dos quais precisa de escape numa query de URL ou no texto HTML. É por isso que os URL curtos e os IDs de incremento automático se escrevem assim. Dois modos: um número decimal (um ID torna-se um código curto) e bytes (entrada de texto ou hexadecimal). Ver também: Base64 | Base32 / Base58 | Base91.
Todo o processamento acontece localmente no seu navegador — os seus dados nunca são enviados para nenhum servidor.

Nunca ouviu falar do Base62? O que é o Base62 — explicado em linguagem simples (com exemplos resolvidos, os três alfabetos e as armadilhas).
Alfabeto:
Preencher o resultado até uma largura fixa: 0 = sem preenchimento. O preenchimento repete o carácter zero do alfabeto selecionado, por isso o mesmo número é preenchido de forma diferente no alfabeto de letras-primeiro.
Como funciona:
A entrada é:
Como funciona:
Saída como:
Ctrl+Enter na entrada executa o modo ativo.
Escolha Codificar ou Descodificar e clique no botão de ação. O botão Autoteste executa todos os exemplos documentados, todos os comprimentos de 0 a 64 bytes e uma distribuição de números decimais pelos três alfabetos, e indica aqui a contagem.
Os três alfabetos, impressos por completo: o Base62 não tem nenhum organismo de normalização por trás, por isso o alfabeto não é garantido entre implementações. Estas são as três ordens que de facto aparecem no terreno; cada uma é impressa carácter a carácter com o seu valor, para que qualquer resultado possa ser rastreado até ao alfabeto exato que o produziu. A célula sombreada é o carácter que significa zero, que não é o mesmo carácter nas três.
O Base62 é sensível a maiúsculas e minúsculas nas três ordens: uma letra maiúscula e a sua forma minúscula quase sempre indicam valores diferentes, pelo que um código que passou por uma conversão para minúsculas é outro número, não um erro.
O Base62 distingue maiúsculas em todas as três ordens: uma letra maiúscula e a sua forma minúscula quase sempre nomeiam valores diferentes, por isso um código que passou por um passo de conversão a minúsculas é outro número, não um erro.
Comprimento dos mesmos bytes em cada codificação:
Quão grande é a entrada que esta página aceita, e porquê: todos os modos aqui convertem através de um único inteiro grande, e a conversão de inteiros grandes custa tempo proporcional ao quadrado do comprimento. Isso é uma propriedade do próprio formato, não desta página: qualquer ferramenta que implemente o Base62 real tem a mesma forma de limite. Os números abaixo vêm de um cronómetro que executa as rotinas da própria página, e não de um separador em execução; por isso estão deliberadamente do lado pessimista: um navegador de computador costuma acabar várias vezes mais depressa, e essa margem é a que cobre um telemóvel lento. Os limites foram definidos para que até o caso lento acabe em vez de congelar o separador.
Acima do limite suave, o primeiro clique explica o custo e pede um segundo clique antes de executar; acima do limite rígido, a página recusa em vez de bloquear o separador durante vários segundos sem forma de mostrar o progresso. O modo de bytes é contado em bytes ao codificar e em caracteres ao descodificar, e a contagem de caracteres é sempre a maior: 2 048 bytes imprimem cerca de 2 751 caracteres, que ultrapassam o limite de caracteres; por isso, uma carga de cerca de 1 520 bytes ou menos é o que sobrevive a um ciclo completo nesta página. Para dados binários simples de qualquer dimensão real, Base64 e Base91 são lineares e não têm esse limite.
O que é o Base62?

O Base62 é uma forma de escrever um número usando apenas os caracteres que sobrevivem a ser colados em qualquer lado: os dez dígitos, as 26 letras maiúsculas e as 26 minúsculas. Sem pontuação, sem espaços, sem carácter de preenchimento, nada que tenha de ser escapado antes de entrar num URL, num nome de ficheiro, num cookie ou numa chave de base de dados. Dez mais 26 mais 26 é 62, e é daí que vem o nome.

A versão de 30 segundos: o número 12345 escreve-se 3D7, e 1234567890 escreve-se 1LY7VK. O caminho inverso é a mesma operação ao contrário, e precisa do alfabeto exato que produziu o código — um alfabeto diferente transforma os mesmos seis caracteres noutro número, sem mensagem de erro nenhuma.

Esta página faz duas tarefas relacionadas, e a diferença entre elas importa mais do que qualquer outra coisa nesta página:

  • Modo inteiro trata a entrada como um número. Um ID decimal como 1234567890 torna-se 1LY7VK, e os zeros iniciais da entrada não fazem parte do valor, por isso não voltam.
  • Modo de bytes trata a entrada como uma cadeia de bytes. Os bytes são lidos como um único inteiro enorme big-endian e depois divididos por 62, que é a mesma aritmética sobre outra quantidade. Aqui o número de bytes zero iniciais sobrevive, um byte zero por cada carácter zero.
De onde vem o 62, e quanto custa

62 não é uma potência de dois, e esse único facto molda tudo o resto. As codificações familiares são construídas cortando a entrada em grupos fixos de bits: 4 bits imprimem-se como um carácter hexadecimal, 6 bits como um carácter Base64, 5 bits como um carácter Base32. O Base62 não consegue fazer isso, porque nenhum número inteiro de bits cabe num carácter de 62 valores — 5 bits só nomeiam 32 valores, 6 bits nomeiam 64. Por isso o Base62 passa pela aritmética: lê a entrada inteira como um inteiro e imprime-o em base 62.

Um carácter transporta então log2(62) = 5,954 bits, muito perto dos 6 do Base64, e no modo decimal um carácter substitui log62(10) = 1,792 dígitos decimais. Algumas consequências a conhecer antes de escolher um comprimento:

Comprimento do códigoValores que consegue nomearNa prática
4 caracteres624 = 14 776 336Chega para um contador que fica abaixo de oito algarismos, e cabe no espaço de um número de telefone.
6 caracteres626 = 56 800 235 584A forma habitual de um código de ID. Um ID decimal de dez dígitos cabe em seis caracteres.
7 caracteres627 = 3 521 614 606 208Passa de longe a gama de um contador de 32 bits, na largura de um slug de URL curto.
11 caracteres6211 = 52 036 560 683 837 093 888Mais do que 264 = 18 446 744 073 709 551 616, por isso um número completo de 64 bits cabe em onze caracteres.

Ao contrário, 1000 dígitos decimais precisam de cerca de 558 caracteres, e 4096 dígitos decimais precisam de 2285. A poupança é real, mas limitada: o Base62 encurta um número decimal em cerca de 44%, e nunca supera as codificações imprimíveis mais densas, porque 5,954 bits por carácter é simplesmente menos do que 6,4 ou 6,5.

Modo inteiro: o que acontece aos zeros iniciais

Um inteiro tem uma forma escrita canónica e começa pelo carácter zero do alfabeto, que é 0 nas duas ordens dígitos-primeiro e A na ordem letras-primeiro. Tudo o que está à esquerda do primeiro carácter significativo é preenchimento, e o preenchimento não faz parte de um valor: 00012345 e 12345 tornam-se ambos 3D7. Se se quiser uma largura fixa — por exemplo, um código de sete caracteres que tenha de se alinhar numa coluna — a caixa Preencher o resultado até uma largura fixa desta página repete caracteres zero até atingir a largura, por isso 12345 com largura 7 imprime 00003D7 no alfabeto dígitos-primeiro e AAAADNH no de letras-primeiro. O preenchimento é cosmético: esses caracteres iniciais não acrescentam nada ao valor, e descodificar qualquer das duas cadeias devolve 12345, porque 0 × 626 e 0 × 625 são ambos zero, seja qual for o carácter que escreve o zero.

Descodificar uma cadeia preenchida também funciona, e a página indica quantos dos caracteres iniciais eram caracteres zero, para que a diferença entre « o código tem sete caracteres » e « o valor precisava de três caracteres » nunca seja um mistério.

Modo de bytes: a mesma aritmética sobre uma cadeia de bytes

O modo de bytes lê os bytes de entrada como um inteiro big-endian — a cadeia de bytes inteira é tratada como um único número, por mais longa que seja — e imprime esse número em base 62. Como um byte contém 8 bits e um carácter representa 5,954 deles, o modo de bytes não é compressão: precisa de cerca de 134% do tamanho da entrada, ligeiramente pior do que os 133% do Base64. Na amostra de 92 bytes usada na tabela de tamanhos acima, 92 bytes imprimem-se como 124 caracteres Base62, e o Base64 também imprime 124 (123 antes do seu preenchimento =). O Base62 perde para o Base64 em densidade e ganha em segurança de caracteres, que é o compromisso que cada código curto e cada convite assume de propósito.

Os bytes zero iniciais são preservados, e isto é fácil de errar nos dois sentidos. Dois bytes zero iniciais seguidos de 0x01 imprimem-se como 001 na ordem dígitos-primeiro e como AAB na de letras-primeiro, porque os caracteres iniciais escrevem o zero e são um por cada byte zero. Uma cadeia de bytes com um único 0x00 imprime-se como o carácter único 0, e uma cadeia com um único 0x01 imprime-se como 1. Este é o único ponto em que o modo de bytes e o modo inteiro parecem diferentes, embora executem o mesmo algoritmo.

O custo de tudo isto é que o modo de bytes herda a temporização quadrática da aritmética: 1024 bytes estimam-se em cerca de um terço de segundo e 2048 bytes em cerca de 1,3 segundos, os mesmos valores que a tabela de limites mais acima indica. É por isso que o modo de bytes aqui está limitado a 2048 bytes na saída e a 2048 caracteres no regresso — 2048 bytes imprimem-se em cerca de 2751 caracteres, por isso cerca de 1520 bytes é a maior carga útil que sobrevive a um ida e volta nesta página — e é por isso que o modo de bytes desta página é uma referência para valores pequenos, e não um substituto de Base64 ou Base91 em ficheiros reais.

Os três alfabetos, e porque o alfabeto é toda a história

Os caracteres de um alfabeto são uma sequência fixa, e o valor de um carácter é a sua posição nessa sequência. Mudar a sequência muda o que cada carácter significa. Três ordens estão em uso generalizado, e este é o mesmo número escrito de três formas em cada uma delas:

Decimal0-9 depois A-Z depois a-z0-9 depois a-z depois A-ZA-Z depois a-z depois 0-9
000A
61zZ9
621010BA
12 3453D73d7DNH
1 234 567 8901LY7VK1ly7vkBViHfU

Lidas as três últimas colunas como um só alfabeto, é um esquema único e coerente. Lidas como intermutáveis, desmoronam-se, porque a descodificação é cega ao alfabeto da pior maneira possível: qualquer carácter da entrada está nos três alfabetos, por isso um alfabeto errado não produz erro nenhum, só um número diferente.

Um códigoLido como 0-9 A-Z a-zLido como 0-9 a-z A-ZLido como A-Z a-z 0-9
3D712 34513 957211 665
1LY7VK1 234 567 8901 624 950 79248 723 527 772

As maiúsculas são uma segunda versão, mais afiada, da mesma armadilha. O Base62 distingue maiúsculas em todas as ordens, por isso passar um código a minúsculas reescreve-o em silêncio: 1LY7VK é 1 234 567 890 no alfabeto dígitos-primeiro, enquanto 1ly7vk é 1 624 950 792 nesse mesmo alfabeto — e acontece ser 1 234 567 890 no alfabeto dígitos-depois-minúsculas, porque essa ordem é precisamente a dígitos-primeiro com as duas maiúsculas trocadas. O carácter zero também não é partilhado: as duas ordens dígitos-primeiro escrevem o zero como 0, enquanto a ordem letras-primeiro o escreve como A, por isso esse alfabeto nem começa por um dígito.

Base62 ao lado das outras codificações
CodificaçãoBits por carácterTamanho face à entradaNotas
Base16 (hex)4200%Dois caracteres por byte, trivialmente legível, sem alfabeto para consultar.
Base325160%Não distingue maiúsculas e é seguro para ditado, o mais desperdiçador do grupo.
Base36 (0-9 a-z)~5,17~155%Só dígitos e letras minúsculas, por isso sobrevive a um circuito que passa tudo a minúsculas. 12345 é 9ix.
Base58~5,86~137%Escolhido para endereços, não para densidade: quatro caracteres parecidos são excluídos em vez de ordenados. Ver Base32 / Base58.
Base62~5,95~134%Cada carácter é um dígito ou uma letra, por isso nada é escapado nunca. A densidade fica entre o Base58 e o Base64.
Base646133%O predefinido em todo o lado, ao custo de +, / e =, os três caracteres que obrigam a escape. Ver conversor Base64.
Ascii85 / Base856,4125%5 caracteres por 4 bytes, mas divide por 85 e o seu alfabeto precisa de aspas. Ver Ascii85.
Base91~6,5~123%O mais denso destes, e aquele cuja saída é menos segura para colar sem escape. Ver Base91.

As percentagens são custos assintóticos, arredondados; as contagens de caracteres medidas para uma entrada real de 92 bytes estão na tabela de tamanhos mais acima nesta página. No modo inteiro a comparação funciona ao contrário, porque a entrada é texto decimal e não bytes: aí o Base62 é cerca de 44% mais curto do que os dígitos que substitui, e o Base36 cerca de 36% mais curto, e é por isso que um código de ID é normalmente Base62 ou Base36 e não Base58.

O que o Base62 não é
  • Não é uma norma. Não existe RFC nem especificação. Nenhum organismo de normalização definiu alguma vez o Base62, e por isso o alfabeto não é garantido, e é por isso que esta página mostra as três ordens em vez de escolher uma em silêncio.
  • Não é encriptação. É uma mudança de base, nada mais. Quem conhecer o alfabeto reverte-a numa só passagem, e não há chave, nem sal, nem segredo de nenhum tipo.
  • Não é compressão. O modo de bytes aumenta os dados cerca de um terço. O modo inteiro só parece compressão porque o texto decimal é, à partida, uma forma ineficiente de escrever um número.
  • Não é insensível a maiúsculas. O Base32 pode ser passado a minúsculas e lido de volta; o Base62 não pode. Um código que passa por um sistema que normaliza maiúsculas é um código corrompido.
  • Não se autoverifica. Não há soma de verificação nem carácter de controlo, por isso um único carácter errado dá um resultado com aspeto válido mas com outro valor. Se isso importar, a ordem Bitcoin vem com soma de verificação — ver a secção Base58Check de Base32 / Base58.
  • Não tem comprimento fixo. O número de caracteres cresce com o valor, por isso um contador que começa em 1 e chega a 627 passa de um carácter para oito. Preencha até uma largura fixa quando for precisa uma coluna estável.
Armadilhas que de facto mordem
  • O alfabeto responde a nove em cada dez mistérios. Se outra ferramenta der um código diferente para o mesmo número, compare os dois alfabetos carácter a carácter antes de suspeitar de um erro. A tabela acima mostra o mesmo valor em três alfabetos, e os três estão corretos.
  • Um alfabeto errado falha em silêncio. Não há caminho de erro para isso: 3D7 descodifica para 12 345, 13 957 ou 211 665 conforme apenas a ordem assumida. Verifique o primeiro carácter, que é o mais provável de ser um zero de preenchimento, e verifique se o alfabeto tem dígitos ou letras à frente.
  • Os zeros iniciais significam duas coisas diferentes. No modo inteiro, 00012345 e 12345 são o mesmo número e imprimem-se de forma idêntica. No modo de bytes, um byte zero inicial é dado, e imprime-se como um carácter zero extra. Remover um desses caracteres altera a cadeia de bytes.
  • A normalização de maiúsculas destrói um código. Um endereço de email, um nome de anfitrião ou um caminho do Windows podem ser passados a minúsculas em trânsito. Um código Base62 não sobrevive a isso, e é por isso que o Base36 ainda existe.
  • Entradas longas são lentas, não apenas grandes. A conversão é aritmética sobre a entrada inteira de uma vez, por isso duplicar o comprimento da entrada quadruplica o tempo. Esta página recusa entradas acima dos seus limites medidos em vez de bloquear; a tabela de tamanhos mais acima dá os números medidos.
  • Uma cadeia Base62 não prova nada. Como quase qualquer cadeia de dígitos e letras se descodifica sem queixa, um slug de URL arbitrário descodifica para algum número. Um código só significa algo se o sistema que o emitiu também guardar o mapeamento.
Respostas rápidas

« Porque é que outra ferramenta Base62 dá um código diferente para o mesmo número? »

Porque o alfabeto é diferente. O Base62 não tem especificação com que discordar, por isso as implementações escolhem uma ordem: dígitos e maiúsculas primeiro, dígitos e minúsculas primeiro, ou letras antes dos dígitos. Mude o seletor de alfabeto no topo desta página para ver as três respostas lado a lado.

« O Base62 é seguro num URL? »

Sim, nas três ordens. Os 62 caracteres são todos letras e dígitos sem escape, por isso nenhum se expande num trio percentual numa query string, e nenhum termina um URL, um segmento de caminho ou um atributo HTML. Essa é toda a razão pela qual os URL curtos são Base62 e não Base64.

« Qual é menor, Base62 ou Base64? »

Para bytes, o Base64 é um pouco mais pequeno: cerca de 133% da entrada contra cerca de 134%. Na amostra de 92 bytes acima os dois empatam em 124 caracteres. Para números decimais, o Base62 encurta o texto em cerca de 44%, e é aí que está o ganho prático.

« Posso descodificar uma cadeia Base64 com esta página? »

Não, e não avisa que falhou. Os dois alfabetos sobrepõem-se nos 62 caracteres, por isso uma cadeia Base64 costuma ser entrada « válida » também aqui e simplesmente descodifica para outro número. Use o Base64 para Base64.

« Um código Base62 tem comprimento máximo? »

Não, em teoria o algoritmo não tem limite. Na prática esta página para em 4096 dígitos decimais, ou 2048 bytes, porque a aritmética por trás é quadrática e o separador congelaria sem nada no ecrã a explicar porquê. A tabela de limites mais acima indica os números medidos.

« Como sei que o resultado desta página está certo? »

Prima Autoteste. Corre todos os exemplos documentados, todos os comprimentos de bytes de 0 a 64 e uma distribuição de números decimais pelos três alfabetos, comparando os valores devolvidos com os que entraram, e volta a verificar que os 62 caracteres de cada alfabeto são seguros num URL. O botão Exemplo compara ainda os seus três resultados com os valores registados no ficheiro de dados desta página, que foram verificados contra uma segunda implementação independente de inteiros grandes, guardada nas ferramentas de teste deste site.

Normas e créditos

Não há norma para implementar aqui: o Base62 é uma convenção, não uma especificação, e os três alfabetos impressos acima são os que aparecem no software real. Esta página implementa-o com as rotinas de inteiros grandes do próprio site, escritas em aritmética simples sobre vetores de dígitos, para que nenhum tamanho seja limitado pelo tipo de número do JavaScript.

O texto desta página foi escrito para este site. Todos os exemplos resolvidos nesta página foram produzidos pelo código da própria página e depois verificados contra uma segunda implementação independente, que usa inteiros grandes nativos e está guardada nas ferramentas de teste deste site; a mesma implementação verificou as tabelas de exemplos e de tamanhos no ficheiro de dados.