Você tem que lidar com o formato Base64? Então esse site é perfeito para você! Use o nosso ferramenta online super útil para codificar ou decodificar os seus dados.

Codificação Base64 em Visual Basic: um guia completo

Aqui está um problema que desenvolvedores Visual Basic enfrentam há vinte e cinco anos: você tem um JPEG, um blob binário, um arquivo de licença ou uma frase perfeitamente comum, e o canal à sua frente só aceita texto. Um campo JSON, uma variável de ambiente, um anexo de e-mail, uma URL, um arquivo de configuração, uma coluna de banco de dados tipada como texto e todas as outras portas do prédio têm uma regra em comum: apenas caracteres imprimíveis. O Base64 é o segurança que deixa o binário entrar. Ele reescreve seus bytes como um stream de letras, dígitos, mais, barra e iguais, então qualquer coisa que viaje como texto pode carregá-los. E a boa notícia: toda a parte do codificador que você possa precisar já está dentro do runtime do .NET. Sem pacotes, sem componentes, sem cerimônia.

Num fôlego, porque a página inicial deste site vai fundo no formato em si: o Base64 pega três bytes de entrada e os escreve como quatro caracteres de um alfabeto de 64 símbolos, adicionando um ou dois caracteres = no final quando a contagem de bytes não divide certinho. Essa troca de quatro por três é porque os dados codificados rodam cerca de um terço maiores que o original, o famoso imposto de tamanho que você paga uma vez por codificação. Tudo o mais neste artigo é sobre fazer a codificação que você produz fazer exatamente o que o próximo sistema espera: o alfabeto certo, o padding certo, as quebras de linha certas e o conjunto de caracteres certo.

A caixa de ferramentas do codificador: tudo é embutido

O lado da codificação do runtime cresceu nas mesmas quatro ondas que o lado da decodificação, então a caixa de ferramentas tem uma longa cauda de opções ainda suportadas. Aqui está a família completa e o trabalho para o qual cada uma é feita:

API Disponível desde Para que serve
System.Convert.ToBase64String .NET Framework 1.1 (2003) O clássico. Um array entra, uma string sai, com overloads para subconjuntos de array, spans e quebras de linha estilo MIME opcionais.
System.Convert.ToBase64CharArray .NET Framework 1.1 (2003) Escreve os caracteres codificados num buffer de caracteres que você já alocou, e devolve quantos caracteres ele usou.
System.Convert.TryToBase64Chars .NET Core 2.1 (2018) Baseada em spans, codificação leve em alocação num span de caracteres que você fornece, com uma resposta Boolean em vez de exceção.
System.Buffers.Text.Base64 .NET Core 2.1 (2018) Codificação de baixo nível, baseada em spans: escreva no seu próprio buffer UTF-8, expanda in-place e dimensione buffers com GetMaxEncodedToUtf8Length.
System.Buffers.Text.Base64Url .NET 9 (2024) O alfabeto seguro para URL (- e _ no lugar de + e /) sem padding. Em runtimes mais antigos ele vem dentro do pacote NuGet Microsoft.Bcl.Memory.
ToBase64Transform + CryptoStream .NET Framework 1.1 (2003) Codificação em stream: leia um arquivo em pedaços, escreva texto codificado para fora, mantenha a memória plana em entradas gigantes.

Para o cenário de versões: o .NET 10 é a release atual de suporte de longo prazo (novembro de 2025, suportada até novembro de 2028), o .NET 8 e o .NET 9 são suportados até novembro de 2026, e o .NET 11 está em preview com um lote fresco de métodos de conveniência Base64 a caminho. Tudo na tabela acima é estável em todos eles. A única trava de versão é o Base64Url: embutido a partir do .NET 9, disponível no .NET Framework 4.6.2 e mais novos através do pacote Microsoft.Bcl.Memory, e este é o único pacote que este artigo alguma vez pede para você instalar. Para colocar um projeto rascunho para rodar, o .NET SDK traz o Visual Basic na caixa:

dotnet new console -lang VB -o Packer
cd Packer
dotnet run

Sua primeira codificação: bytes entram, texto sai

Noventa por cento da vida de codificação no Visual Basic é duas chamadas, e a ordem importa: o codificador aceita bytes, não texto, então se você começa com uma string você primeiro escolhe uma codificação para transformá-la em bytes, e só depois faz o passo Base64. Aqui está a dança inteira:

Imports System
Imports System.Text
Module Encoder
    Sub Main()
        Dim text As String = "Man"
        Dim bytes() As Byte = Encoding.UTF8.GetBytes(text)
        Dim packed As String = System.Convert.ToBase64String(bytes)
        Console.WriteLine(packed)
        ' TWFu
    End Sub
End Module

Aquele meio de três linhas é o ofício inteiro, e a string "TWFu" é o teste de fumaça perfeito para qualquer codificador que você escrever. Os overloads te dão controle quando você precisa. As formas de subconjunto codificam um trecho de um array sem copiá-lo para fora primeiro, o que é útil quando o payload de verdade está dentro de um buffer maior:

Imports System
Module SlicePacker
    Sub Main()
        Dim data() As Byte = {1, 2, 3, 4, 5, 6, 7, 8}
        Dim packed As String = System.Convert.ToBase64String(data, 2, 4)
        Console.WriteLine(packed)
        ' AwQFBg==  (apenas os bytes 3 a 6 foram codificados)
    End Sub
End Module

E a forma de array para char, ToBase64CharArray, escreve num buffer de caracteres que você aloca e te diz quantos caracteres ele preencheu, que é a ferramenta certa quando o destino faz parte de uma estrutura de texto maior que você está construindo à mão. Note a regra da casa para sintaxe do Visual Basic: um array de bytes é escrito como Byte() com os parênteses vazios. Jogue-os fora e você tem um byte único, e o Option Strict On (desligado por padrão nos modelos - vale a pena ligar em todo projeto) pega a confusão em tempo de compilação.

Moldando a saída: padding, quebras de linha e tamanhos exatos

Codificar os mesmos bytes duas vezes pode legitimamente produzir duas strings diferentes, e as diferenças todas se resumem a moldagem de saída. Primeira, padding: quando o comprimento da entrada não é um múltiplo de três, o codificador completa o grupo final com um ou dois caracteres =. O RFC diz para incluí-los a menos que a especificação que você está seguindo diga o contrário, e o ToBase64String os inclui por padrão. Segunda, quebras de linha: o segundo parâmetro dos overloads de formatação, Base64FormattingOptions.InsertLineBreaks, faz o codificador emitir linhas de 76 caracteres separadas por CRLF, que é exatamente a regra MIME. O próprio MIME usa um limite de 76 caracteres, um parente próximo das linhas antigas de 64 caracteres do PEM, e ambos os limites remontam a restrições dentro do SMTP. Se o seu consumidor é um pipeline de e-mail, ligue as quebras de linha; se é uma URL, um campo JSON ou uma coluna de banco de dados, deixe-as desligadas, porque um CRLF invisível dentro dos seus dados vai encontrar um jeito de te surpreender depois:

Imports System
Module MimePacker
    Sub Main()
        Dim data(113) As Byte
        For i As Integer = 0 To 113
            data(i) = CByte(i)
        Next
        Dim wrapped As String = System.Convert.ToBase64String(data, Base64FormattingOptions.InsertLineBreaks)
        Console.WriteLine(wrapped.Length)
        ' 154: duas linhas de 76 caracteres mais um CRLF entre elas
    End Sub
End Module

Terceira, tamanhos exatos, porque você vai querer pré-alocar buffers e larguras de coluna. A regra é quatro caracteres para cada três bytes de entrada, arredondando para cima: 1000 bytes vira 1336 caracteres. Em vez de fazer a aritmética na mão, o runtime tem um helper que devolve o comprimento máximo codificado para um determinado tamanho de entrada, que é o que você passa para a alocação de buffer:

Imports System.Buffers.Text
Module Sizing
    Sub Main()
        Dim dataLength As Integer = 1000
        Dim textNeeded As Integer = Base64.GetMaxEncodedToUtf8Length(dataLength)
        Console.WriteLine(textNeeded)
        ' 1336
    End Sub
End Module

A mesma proporção de quatro por três é o imposto de tamanho na sua forma mais pura: todo valor codificado é mais ou menos 33 por cento maior que os bytes que carrega, então planeje seus tamanhos de armazenamento e transferência com essa margem em mente. E um comportamento que vale conhecer antes de te morder: se você decodifica uma string e depois re-codifica o resultado, a nova string não é garantida para bater com a original, porque espaços em branco desaparecem e o padding é normalizado. Compare bytes decodificados quando precisar comparar valores, não o texto codificado.

Escolhendo o conjunto de caracteres antes de codificar

Como o primeiro passo da codificação de texto é "string para bytes", o conjunto de caracteres que você escolhe decide o que o receptor vê quando decodifica. Strings do Visual Basic são UTF-16 dentro do runtime, mas os bytes que você emite devem bater com o que o outro lado espera ler, e o menu de escolhas é curto:

  • Encoding.UTF8: o padrão certo para web, APIs e qualquer coisa moderna. Ele dá ida e volta para todo caractere Unicode que a linguagem consegue guardar.
  • Encoding.Unicode: UTF-16 little-endian. Uma escolha razoável quando as duas pontas do cano são programas .NET que explicitamente combinaram UTF-16, e nada mais.
  • Encoding.ASCII: apenas 7 bits, e ele substitui em silêncio qualquer outra coisa por um ponto de interrogação. Codificar "Café" como ASCII te dá os bytes de "Caf?", que vão decodificar de volta exatamente para aquilo, ponto de interrogação e tudo.
  • Encoding.Default: no .NET Framework isso era a página de código ANSI da máquina, mas no .NET (Core) é sempre UTF-8 independente do locale. Ainda assim, evite para dados que você troca - nomeie a codificação explicitamente, geralmente UTF-8.
Imports System
Imports System.Text
Module CharsetPacker
    Sub Main()
        Dim text As String = "Café"
        Dim utf8() As Byte = Encoding.UTF8.GetBytes(text)
        Dim ascii() As Byte = Encoding.ASCII.GetBytes(text)
        Console.WriteLine(System.Convert.ToBase64String(utf8))
        ' Q2Fmw6k=
        Console.WriteLine(System.Convert.ToBase64String(ascii))
        ' Q2FmPw==  (o acento virou um ponto de interrogação)
    End Sub
End Module

Duas strings Base64 diferentes, uma palavra, e apenas uma delas sobrevive à viagem. A regra prática: a menos que o protocolo que você está seguindo nomeie outro esquema, codifique texto como UTF-8 e diga isso.

Base64Url: o alfabeto que sobrevive a URLs

O alfabeto padrão contém + e /, e ambos os caracteres têm empregos próprios dentro de URLs, então o Base64 construído sobre aquele alfabeto quebra no momento em que pousa numa query string ou num segmento de caminho. A correção, padronizada na seção 5 do RFC 4648, troca os dois infratores por - e _, que são seguros para URL, e tipicamente descarta o padding no final porque o comprimento dos dados já diz ao decodificador onde eles terminam. Essa variante, conhecida como base64url, é o alfabeto dos JWTs, dos tokens de API e de um número crescente de APIs. O .NET 9 adicionou uma classe dedicada para ela, e ela foi construída com uma opinião que vale conhecer: ela omite o padding por design:

Imports System.Buffers.Text
Module UrlSafePacker
    Sub Main()
        Dim data() As Byte = {219, 255, 0, 63, 16}
        Dim packed As String = Base64Url.EncodeToString(data)
        Console.WriteLine(packed)
        ' 2_8APxA  (underbar, sem padding no final)
    End Sub
End Module

O exemplo acima é um bom: os bytes escolhidos fazem um dos caracteres especiais aparecer - o sublinhado, onde o alfabeto padrão tem uma barra - então você consegue ver a troca acontecer. Quando você está num runtime mais antigo, o mesmo alfabeto é duas substituições de caracteres mais um trim, e você ganha um resultado compatível drop-in:

Imports System
Module CompatPacker
    Function ToUrlSafe(ByVal packed As String) As String
        Return packed.Replace("+"c, "-"c).Replace("/"c, "_"c).TrimEnd("="c)
    End Function
End Module

No .NET Framework 4.6.2 ou mais novo, o pacote Microsoft.Bcl.Memory te dá a classe de verdade Base64Url em vez disso. De qualquer jeito, fique de olho na linha na areia do padding: a saída do Base64Url do .NET não tem padding, enquanto algumas bibliotecas de outros ecossistemas o adicionam (e alguns decodificadores estritos insistem nele). O JWT, por exemplo, exige a forma sem padding, então o padrão do .NET é exatamente certo ali. Quando você cruza uma fronteira de ecossistema, cheque a expectativa do outro lado antes de despachar a string.

Empacotando arquivos

Arquivos são o caso de uso original: transformar um arquivo binário num arquivo de texto que e-mail, FTP e sistemas de configuração vão carregar com prazer. No Visual Basic, o trabalho inteiro são três chamadas, uma das quais lê e uma das quais escreve:

Imports System.IO
Module FilePacker
    Sub Main()
        Dim bytes() As Byte = File.ReadAllBytes("photo.png")
        Dim packed As String = System.Convert.ToBase64String(bytes)
        File.WriteAllText("photo.b64", packed)
    End Sub
End Module

Guarde a proporção de tamanho no bolso: uma foto de 10 megabytes vira um arquivo de texto de mais ou menos 13,4 megabytes. A operação é rápida em hardware moderno (mais sobre isso abaixo), então o custo é quase sempre armazenamento e largura de banda em vez de CPU, que é a conta usual de um imposto de 33 por cento. Quando o arquivo só vai viver do lado do texto que o referencia, esse padrão é perfeitamente bom; quando o arquivo é grande e de vida longa, pergunte se o canal de verdade precisa da forma de texto.

Imagens: construindo data URIs à mão

O esquema data URI (RFC 2397) embute o conteúdo de arquivos diretamente numa URL: data:, o media type, o marcador literal ;base64, uma vírgula e os bytes codificados. Navegadores os usam para embutir imagens e fontes pequenas. O WPF não consome uma data URI diretamente - o BitmapImage não tem handler para o esquema data: - então a jogada idiomaticamente certa é tirar o prefixo e passar os bytes para um MemoryStream. Construir a URI no Visual Basic é uma concatenação de strings, e consumi-la é um pequeno bloco de init:

Imports System.IO
Imports System.Windows.Media.Imaging
Module DataUriPacker
    Sub Main()
        Dim bytes() As Byte = File.ReadAllBytes("logo.png")
        Dim dataUri As String = "data:image/png;base64," & System.Convert.ToBase64String(bytes)
        Dim image As New BitmapImage()
        image.BeginInit()
        image.StreamSource = New MemoryStream(System.Convert.FromBase64String(dataUri.Substring(dataUri.IndexOf(","c) + 1)))
        image.EndInit()
        ' agora a imagem pode ser atribuída a um controle Image
    End Sub
End Module

O próprio RFC avisa que data URIs só são úteis para valores curtos, e documentos HTML impõem seus próprios limites de comprimento de atributo, então o alcance sensato é ícones, avatares, miniaturas e padrões de fundo minúsculos. O media type tem que bater com os bytes que você realmente codificou, porque nada a jusante vai re-derivá-lo do conteúdo.

HTTP: headers de autenticação e payloads JSON

No fio, os dois lugares onde você vai codificar na mão são o header de autenticação Basic HTTP e os campos JSON que carregam dados binários ou pré-codificados. Basic auth é o mais visível: o header é a palavra Basic, um espaço e o Base64 de username:password unido com um dois-pontos. Construí-lo é uma chamada de codificação:

Imports System
Imports System.Text
Module AuthPacker
    Function MakeBasicHeader(ByVal user As String, ByVal password As String) As String
        Dim raw() As Byte = Encoding.UTF8.GetBytes(user & ":" & password)
        Return "Basic " & System.Convert.ToBase64String(raw)
    End Function
End Module

O caso JSON é igualmente rotineiro. Se uma API quer uma imagem ou um certificado dentro de um corpo de requisição, você codifica os bytes e joga a string no payload, e o System.Text.Json (na caixa desde o .NET Core 3.0) cuida da serialização ao redor:

Imports System.Text.Json
Module ApiPacker
    Function WidgetPayload(ByVal name As String, ByVal imageBytes() As Byte) As String
        Dim payload = New With {
            .name = name,
            .image = System.Convert.ToBase64String(imageBytes)
        }
        Return JsonSerializer.Serialize(payload)
    End Function
End Module

Duas regras da casa: envie credenciais apenas sobre HTTPS, porque sobre HTTP puro o Base64 é um disfarce, não uma trava, e nunca registre num log o header de autenticação cru ou as credenciais para as quais ele decodifica.

Anexos de e-mail e embrulho MIME

O e-mail é onde o Base64 ganha a vida. O SMTP foi construído para ASCII de 7 bits, então um anexo binário tem que virar texto antes de poder voar, e o padrão MIME (RFC 2045) fez a escolha: Base64, embrulhado a 76 caracteres por linha, declarado com um header Content-Transfer-Encoding: base64. Se você trabalha com as classes System.Net.Mail, o ritual inteiro são duas linhas de setup, porque a biblioteca de e-mail faz o embrulho por você na hora do envio:

Imports System.IO
Imports System.Net.Mail
Imports System.Net.Mime
Module MailPacker
    Sub Main()
        Using message As New MailMessage("me@example.com", "you@example.com")
            message.Subject = "Quarterly report"
            message.Body = "Please find the report attached."
            Using stream As New FileStream("report.bin", FileMode.Open, FileAccess.Read)
                Dim attachment As New Attachment(stream, "report.bin")
                attachment.TransferEncoding = TransferEncoding.Base64
                message.Attachments.Add(attachment)
            End Using
        End Using
    End Sub
End Module

Você só precisa produzir a forma embrulhada na mão, com Base64FormattingOptions.InsertLineBreaks, quando está escrevendo texto MIME cru à mão: um fixture de teste de mailer, um gateway legado ou uma ferramenta que cospe arquivos .eml. A regra de 76 caracteres não é uma preferência de estilo; alguns sistemas receptores truncam linhas mais longas, que é por isso que o limite sobreviveu no padrão por décadas.

Armazenando valores codificados: bancos, arquivos de configuração e variáveis de ambiente

Armazenamento apenas de texto não para de pedir Base64: uma coluna de banco de dados tipada como texto, um valor de configuração XML, uma variável de ambiente. Você codifica os bytes, armazena a string e decodifica na saída. O lado da codificação é sempre o mesmo one-liner, mas o lado do armazenamento tem limites que tornam o imposto de tamanho concreto. Uma coluna VARCHAR comum no SQL Server para em 8.000 caracteres (uma coluna NVARCHAR para na metade, 4.000 caracteres, já que cada caractere Unicode custa dois bytes) - 8.000 caracteres são espaço para uns 6.000 bytes de binário antes que o overhead de 33 por cento te empurre para cima, além do que você recorre aos tipos MAX ou, com mais honestidade, a uma coluna binária de verdade. No Windows, uma única variável de ambiente definida pelo usuário tem teto de 32.767 caracteres (e em sistemas da era do XP o bloco de ambiente inteiro também tinha teto naquele tamanho), então "manter o blob inteiro de licença numa variável de ambiente" tem um teto duro:

Imports System
Module EnvPacker
    Sub Main()
        Dim blob() As Byte = {1, 2, 3, 4, 5}
        Dim packed As String = System.Convert.ToBase64String(blob)
        Environment.SetEnvironmentVariable("APP_BLOB", packed)
        Console.WriteLine(packed)
        ' AQIDBAU=
    End Sub
End Module

Arquivos de configuração seguem a mesma forma, com o valor morando em texto XML ou JSON e a decodificação acontecendo no seu código de startup. Uma nota de legado para o canto corporativo: o WCF e os contratos de dados XML serializam um array de bytes como o tipo de esquema XML base64Binary, então um grande volume de serviços .NET mais antigos armazena binário exatamente assim, e o valor que você encontra naquele XML é saída pura de ToBase64String.

JWTs: construindo a forma compacta

Um JSON Web Token em forma compacta é três peças de base64url separadas por pontos: o header, o payload e uma assinatura. As duas primeiras são JSON puro, e a terceira é uma prova criptográfica de que um portador da chave certa construiu este token. Construir a forma sem assinatura na mão são duas codificações e um join de strings, mas um JWT de verdade precisa do passo de assinatura, e um pequeno exemplo HMAC-SHA256 torna a coisa toda concreta:

Imports System
Imports System.Buffers.Text
Imports System.Security.Cryptography
Imports System.Text
Module JwtPacker
    Function BuildHs256Jwt(ByVal headerJson As String, ByVal payloadJson As String, ByVal secret() As Byte) As String
        Dim header As String = Base64Url.EncodeToString(Encoding.UTF8.GetBytes(headerJson))
        Dim body As String = Base64Url.EncodeToString(Encoding.UTF8.GetBytes(payloadJson))
        Dim signingInput As String = header & "." & body
        Using hmac As New HMACSHA256(secret)
            Dim signature() As Byte = hmac.ComputeHash(Encoding.UTF8.GetBytes(signingInput))
            Return signingInput & "." & Base64Url.EncodeToString(signature)
        End Using
    End Function
End Module

Rode com o header {"alg":"HS256","typ":"JWT"} e um payload da sua escolha, e o resultado é um JWT compacto genuíno: sem padding em lugar nenhum, caracteres seguros para URL nas três partes. Note que a assinatura é base64url também, porque o token inteiro tem que sobreviver a uma URL ou a um header HTTP. Para sistemas de produção, o pacote System.IdentityModel.Tokens.Jwt (a suíte IdentityModel da equipe Microsoft Entra) constrói, assina e verifica esses tokens para você, que é a camada onde gestão de chaves, fixação de algoritmo e cheques de expiração pertencem. Fazer a codificação na mão é bom para entender e para ferramentas pequenas; para qualquer coisa que guarde acesso, deixe a biblioteca carregar o peso.

Armadilhas: onde codificadores VB escorregam

As armadilhas aqui são uma mistura de hábitos de linguagem e surpresas de moldagem de saída, e a maioria delas custa uma sessão de debug em vez de um crash:

  • Byte versus Byte(). O codificador quer um array. No Visual Basic, um byte único é Byte e um array é Byte(), e a diferença é um par de parênteses. Sob Option Strict On, um palpite errado é um erro de compilação; com ele desligado, você pode ganhar uma surpresa de runtime em vez disso. Mantenha a estriteza ligada e os parênteses visíveis.
  • A armadilha do Encoding.Default, ao contrário. A história da divergência de locale é do .NET Framework: no .NET moderno, Default é sempre UTF-8, então a mesma string codifica do mesmo jeito em toda máquina. Para qualquer coisa que cruze máquinas, nomeie a codificação explicitamente, geralmente UTF-8 - o conselho vale nos dois casos.
  • CRLF tem um jeito de entrar. InsertLineBreaks é maravilhoso para MIME e terrível para URLs, JSON e colunas de texto de banco de dados, onde ele insere um carriage return e um line feed que ninguém pediu. Use só quando o consumidor espera linhas embrulhadas, e em caso de dúvida, use o padrão None.
  • Descombates de padding na fronteira. O Base64Url do .NET não emite padding, enquanto algumas bibliotecas de outros ecossistemas o adicionam (e alguns decodificadores estritos o exigem). Quando o seu valor codificado cruza um ecossistema, confirme a expectativa do outro lado antes de despachar a string; o JWT quer a forma sem padding, que é o padrão do .NET.
  • Ida e volta não são identidade. Decodifique uma string embrulhada e com padding e re-codifique-a, e você ganha uma linha única limpa com padding fresco, não o texto original. Se a sua lógica compara valores codificados por igualdade, compare os bytes decodificados em vez disso.
  • O teto de tamanho é real. A fórmula de comprimento de saída, quatro caracteres por três bytes arredondando para cima, estoura uma contagem de 32 bits em mais ou menos 1,5 gigabytes de entrada, e o codificador responde com uma OutOfMemoryException em vez de uma string parcial. Para entradas perto dessa escala, use stream em vez disso (abaixo).
  • O muro dos spans. Os codificadores baseados em spans podem ser chamados do VB no ponto de chamada: passe seus arrays Byte() ou Char() direto e o compilador os converte. Mas você não pode declarar uma variável, campo ou parâmetro do tipo Span ou ReadOnlySpan; o compilador se recusa com "Types with embedded references are not supported in this version of your compiler". O idioma do VB é chamar as APIs de span com arrays comuns e nunca guardar um span.
  • BitConverter não é Base64. BitConverter.ToString(bytes) renderiza hex com traços entre os pares, então é uma resposta errada tentadora que produz 4D-61-6E onde o outro sistema espera TWFu. Para Base64, a classe é System.Convert, toda vez.

Velocidade e tamanho: notas de desempenho

A reputação de "codec de texto lento" do Base64 não sobrevive ao contato com o runtime moderno. O codificador dentro do .NET roda código vetorizado em hardware quando a máquina suporta, com caminhos rápidos dedicados para os conjuntos de instruções AVX-512, AVX2 e SSE, e o caminho AVX-512 devora 48 bytes por passo. Para payloads comuns, a chamada clássica ToBase64String é rápida o bastante para que o algoritmo raramente seja o gargalo; os custos que você sente são o imposto de tamanho de 33 por cento e, em caminhos quentes, as alocações intermediárias. Se você está codificando milhões de valores pequenos, as APIs baseadas em spans são o refinamento: TryToBase64Chars escreve num span de caracteres que você controla e reporta sucesso com um Boolean, e o System.Buffers.Text.Base64 vai mais longe, codificando direto em buffers UTF-8 que você aloca e até expandindo dados in-place:

Imports System
Imports System.Buffers
Imports System.Buffers.Text
Imports System.Text
Module BufferPacker
    Sub Main()
        Dim data() As Byte = {1, 2, 3, 4, 5}
        Dim textLength As Integer = Base64.GetMaxEncodedToUtf8Length(data.Length)
        Dim buffer(textLength) As Byte
        Dim written As Integer
        Dim consumed As Integer
        Dim status As OperationStatus = Base64.EncodeToUtf8(data, buffer, consumed, written)
        Dim packed As String = Encoding.ASCII.GetString(buffer, 0, written)
        Console.WriteLine(packed)
        ' AQIDBAU=
    End Sub
End Module

O padrão a notar é que você dimensiona o buffer com o helper, codifica nele e converte apenas o prefixo usado para string, o que mantém a superfície intermediária tão pequena quanto possível. E para arquivos grandes o bastante para deixar strings desconfortáveis, o par de streaming mantém a memória plana: o transform ToBase64Transform embrulhado num CryptoStream lê a sua entrada em pedaços e escreve texto codificado para fora, então um arquivo de dois gigabytes nunca precisa virar uma string de 2,7 gigabytes num pedaço só:

Imports System.IO
Imports System.Security.Cryptography
Module StreamPacker
    Sub EncodeFile(ByVal inputPath As String, ByVal packedPath As String)
        Using inputStream As New FileStream(inputPath, FileMode.Open, FileAccess.Read)
            Using packedStream As New CryptoStream(New FileStream(packedPath, FileMode.Create), New ToBase64Transform(), CryptoStreamMode.Write)
                Dim buffer(65535) As Byte
                While True
                    Dim read As Integer = inputStream.Read(buffer, 0, buffer.Length)
                    If read = 0 Then Exit While
                    packedStream.Write(buffer, 0, read)
                End While
            End Using
        End Using
    End Sub
End Module

Uma nota para frente: as bibliotecas de preview do .NET 11 adicionam novos overloads de conveniência e span aos tipos Base64 existentes, então se o seu projeto consegue acompanhar previews, a caixa de ferramentas continua crescendo; se não consegue, tudo acima é estável em toda release suportada.

Uma breve história: do MSXML aos spans

Muito antes do .NET, programas Visual Basic que precisavam de Base64 o pegavam emprestado do mundo COM. O truque clássico de VB6 e VBA (a linguagem de macros que ainda roda dentro do Excel e do Office) usava em vez disso um elemento XML DOM: o parser MSXML deixa um nó declarar seu DataType como bin.base64, então escrever seus bytes no nodeTypedValue do nó e ler de volta a propriedade text dele entrega a string codificada, com o DOM fazendo a matemática Base64 de verdade (a propriedade Charset do próprio objeto Stream ADO só entende nomes reais de conjunto de caracteres como "utf-8" ou "iso-8859-1", não "base64", então ele não tem papel na conversão em si). Era esperto, estava em toda parte, e é por isso que "base64 VBA" ainda acende motores de busca décadas depois. A era terminou em 2002, quando a primeira versão .NET da linguagem, o Visual Basic 7.0, entrou no novo Common Language Runtime, e o .NET Framework trouxe System.Convert com ToBase64String de fábrica. Desde o .NET Framework 1.1 em 2003, todo programa VB podia codificar Base64 com uma chamada e sem componentes a registrar.

Os capítulos modernos são curtos. Em 2018, o .NET Core 2.1 adicionou o método TryToBase64Chars leve em alocação e a classe de baixo nível baseada em spans System.Buffers.Text.Base64. Em 2024, o .NET 9 padronizou o alfabeto seguro para URL como Base64Url, encerrando uma década de chamadas Replace feitas na mão. Em 2026, o .NET 10 - lançado em novembro de 2025 - é a release de suporte de longo prazo carregando tudo isso, e as bibliotecas de preview do .NET 11 estão adicionando uma nova geração de métodos de conveniência, então o codificador, do one-liner de 2003 à era dos spans, é a história da mesma classe ficando mais rápida e mais precisa, nunca de recomeçar do zero.

Fatos curiosos, edição VB

  • InsertLineBreaks reproduz a regra MIME de 76 caracteres exatamente, CRLF incluído, o que significa que as quebras de linha que o seu codificador escreve em 2026 têm a mesma forma byte a byte das que um padrão de e-mail definiu nos anos 1990.
  • O operador IsNot, adicionado com o Visual Basic 2005, já fez notícia como assunto de um pedido de patente da Microsoft. Pouquíssimos operadores de linguagem podem reivindicar essa distinção.
  • O primeiro Visual Basic foi lançado em 1991, antes de a World Wide Web existir. Quando o esquema data URI apareceu em 1998, o Base64 já carregava anexos de e-mail há cinco anos, e o VB tinha crescido para uma linguagem de 32 bits três anos antes disso, com o Visual Basic 4 em 1995.
  • Em hardware com AVX-512, o codificador do runtime processa 48 bytes por passo de vetor, que é a diferença entre uma consulta a uma tabela num museu e uma esteira transportadora numa fábrica.
  • O namespace My, a famosa camada de açúcar do Visual Basic de 2005, nunca precisou adicionar um helper Base64. O System.Convert estava sempre a um import de namespace de distância, um caso raro em que o runtime VB não adicionou nada a uma história que o framework já contava.

O outro lado

Este artigo cobriu o lado da codificação do Base64 no Visual Basic: a caixa de ferramentas, as decisões de moldagem de saída, o alfabeto seguro para URL e os casos de uso de arquivos a JWTs. A direção inversa, pegar uma string recebida e transformá-la de volta nos bytes que ela esconde, tem seu próprio conjunto de comportamentos, regras de tolerância e armadilhas, e ela é coberta em todos os detalhes no artigo companheiro de decodificação no site irmão. O link para ele fica logo abaixo desta linha, e a ferramenta na página inicial continua sendo a maneira mais rápida de codificar um payload pequeno na mão.

Última atualização: 2026-09-08

Artigo relacionado: Decodificação Base64 em Visual Basic: um guia completo