Base64: Qual é o pior aumento possível no uso de espaço?

166

Se um servidor recebeu uma string base64 e quis verificar seu comprimento antes da conversão, diga que sempre desejava permitir que a matriz de bytes final tivesse 16 KB. Qual o tamanho possível de uma matriz de 16 KB de bytes quando convertida em uma string Base64 (assumindo um byte por caractere)?

Bryan Field
fonte

Respostas:

242

Base64 codifica cada conjunto de três bytes em quatro bytes. Além disso, a saída é preenchida para ser sempre um múltiplo de quatro.

Isso significa que o tamanho da representação base-64 de uma cadeia de tamanho n é:

ceil(n / 3) * 4

Portanto, para uma matriz de 16kB, a representação da base 64 será o teto (16 * 1024/3) * 4 = 21848 bytes de comprimento ~ = 21,8kB.

Uma aproximação aproximada seria que o tamanho dos dados é aumentado para 4/3 do original.

R. Martinho Fernandes
fonte
Precisamos adicionar 2 ao comprimento ou não?
vIceBerg 26/11
@vIceBerg, Depende se você estiver usando ceilcom floatnúmeros ou apenas intnúmeros. (e não ceil)
Bryan Field
7
Acho que a maneira mais simples de colocar isso é adicionar 1/3 do tamanho original.
Mvmn 31/10/16
1
No exemplo que você propôs, mostrar o resultado na mesma ordem de medida aumentaria um pouco a qualidade da resposta (21,3 KB em vez de 21848 bytes).
Ivan De Paz Centeno
36

Da Wikipedia

Observe que, dada uma entrada de n bytes, a saída terá (n + 2 - ((n + 2)% 3)) / 3 * 4 bytes de comprimento, de modo que o número de bytes de saída por byte de entrada converja para 4/3 ou 1,33333 para n grande.

Portanto, 16kb * 4/3 fornece muito pouco mais de 21,3 'kb, ou 21848 bytes, para ser exato.

Espero que isto ajude

Preocupação binária
fonte
11

16kb é 131.072 bits. O Base64 empacota buffers de 24 bits em quatro caracteres de 6 bits cada, para que você tenha 5.462 * 4 = 21.848 bytes.

Chris Heald
fonte
5

Como a pergunta foi sobre o pior aumento possível, devo acrescentar que geralmente há quebras de linha em torno de cada 80 caracteres. Isso significa que, se você estiver salvando dados codificados em base64 em um arquivo de texto no Windows, ele adicionará 2 bytes, no Linux, 1 byte para cada linha.

O aumento da codificação real foi descrito acima.

Zsolt Sky
fonte
3
Não é o caso extremo de 1 byte de origem se tornar 4 bytes de base64, para um aumento de 4x? Qualquer material de origem já recebe uma melhor relação, até que, como já foi dito, é assintoticamente aproxima 1.333 ...
Olie
1

Esta é uma referência futura para mim. Desde que a pergunta está no pior caso, devemos levar em consideração quebras de linha. Enquanto o RFC 1421 define o comprimento máximo da linha como 64 caracteres, o RFC 2045 (MIME) afirma que haveria 76 caracteres em uma linha, no máximo.

O último é o que a biblioteca C # implementou. Portanto, no ambiente Windows em que uma quebra de linha é de 2 caracteres (\ r \ n), obtemos o seguinte:Length = Floor(Ceiling(N/3) * 4 * 78 / 76)

Nota: O revestimento é porque, durante o meu teste com C #, se a última linha terminar com exatamente 76 caracteres, não haverá quebra de linha.

Eu posso provar isso executando o seguinte código:

byte[] bytes = new byte[16 * 1024];
Console.WriteLine(Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks).Length);

A resposta para 16 kBytes codificados na base64 com linhas de 76 caracteres: 22422 caracteres

Suponha que seria no Linux, Length = Floor(Ceiling(N/3) * 4 * 77 / 76)mas ainda não testei no meu núcleo .NET.

Lionet Chen
fonte