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.

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

Imagine a cena: uma string pousa no seu projeto Visual Basic. Ela parece um baralho embaralhado de letras e dígitos, de vez em quando com um sinal de mais, uma barra ou um sinal de igual misturado, e a pessoa que a enviou jura que ela já foi uma frase perfeitamente comum, um JPEG ou um blob de configuração. Essa string é Base64, e esta página é o seu guia de campo para transformá-la de volta no que ela era. A boa notícia já de cara: o Visual Basic carrega um decodificador Base64 de primeira classe desde os primórdios do .NET Framework, ele vem dentro do runtime, e você não precisa instalar um único pacote para usá-lo.

Uma revisão rápida, porque a página inicial deste site explica o formato em toda a profundidade: o Base64 escreve três bytes como quatro caracteres tirados de um alfabeto de 64 símbolos, e um ou dois caracteres = no final marcam onde os dados de verdade terminaram. Então o texto codificado fica um pouco inchado em comparação com o original: quatro caracteres para cada três bytes de entrada, mais ou menos um terço a mais. Decodificar é simplesmente rodar essa troca ao contrário. Com a forma do problema em mente, vamos abrir alguns envelopes.

A família de decodificadores: um runtime, quatro eras

Tudo o que você precisa para decodificar mora no runtime do .NET. Nas últimas duas décadas ele cresceu em quatro ondas, e as ondas mais velhas continuam funcionando exatamente como sempre funcionaram, então você vai ver todas elas no mundo real:

API Disponível desde Para que serve
System.Convert.FromBase64String .NET Framework 1.1 (2003) O clássico. Uma string entra, um array Byte() novo sai. Lança exceção em entrada ruim.
System.Convert.FromBase64CharArray .NET Framework 1.1 (2003) A mesma decodificação, lendo de um trecho de um array de caracteres que você já tem.
System.Convert.TryFromBase64String, TryFromBase64Chars .NET Core 2.1 (2018) Boolean em vez de exceções, escrevendo num buffer que você fornece. O guarda amigável para entrada não confiável.
System.Buffers.Text.Base64 .NET Core 2.1 (2018) Decodificação de baixo nível, baseada em spans: códigos de status em vez de exceções, descompactação in-place e pré-cheques IsValid.
System.Buffers.Text.Base64Url .NET 9 (2024) O alfabeto seguro para URL (- e _ no lugar de + e /), com padding opcional. Em runtimes mais antigos ele vem dentro do pacote NuGet Microsoft.Bcl.Memory.
FromBase64Transform + CryptoStream .NET Framework 1.1 (2003) Decodificação em stream: de arquivo para arquivo, da rede para o disco, pedaço por pedaço, sem segurar o payload inteiro na memória.

Um esclarecimento sobre o Visual Basic antes de irmos mais longe. Num projeto VB, o nome solto Convert resolve para System.Convert, porque os modelos de projeto padrão importam o namespace System para você, e nada no runtime do Visual Basic ofusca esse nome. Ainda assim, este artigo escreve na maioria das vezes a forma completa System.Convert: ela não custa nada e deixa a intenção inequívoca para qualquer um que leia o código.

Sobre versões: o .NET 10 é a release atual de suporte de longo prazo (novembro de 2025, suportada até novembro de 2028), e o .NET 8 e o .NET 9 continuam suportados até novembro de 2026, enquanto o .NET 11 está em preview e adiciona um lote de novos métodos de conveniência Base64. As APIs de decodificação são estáveis em todas elas. A única trava de versão é o Base64Url: ele é embutido a partir do .NET 9, e no .NET Framework 4.6.2 ou mais novo você pode trazê-lo com o pacote Microsoft.Bcl.Memory. Nada mais neste artigo precisa de pacote.

Se você está montando do zero, o .NET SDK inclui o Visual Basic de fábrica, então esta é a cerimônia inteira:

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

Isso te dá um pequeno Program.vb com Imports System no topo, e você está pronto para decodificar.

O one-liner: FromBase64String

Noventa por cento da vida de decodificação no Visual Basic é uma única chamada. Você passa uma string, e ela devolve os bytes exatos que estavam embalados dentro:

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

Três coisas valem a pena serem memorizadas. Primeira, o resultado são bytes, não texto: o decodificador é orientado a bytes de ponta a ponta, que é exatamente o que você quer, porque o payload pode ser uma frase, um JPEG, um certificado ou um hash, e nenhum deles deve ser tratado de modo especial. Transformar esses bytes numa string legível é um passo separado e deliberado através de um objeto Encoding, e é nesse passo que mora a sua decisão de conjunto de caracteres (mais sobre isso abaixo). Segunda, o FromBase64String aloca um array novo dimensionado exatamente para o comprimento decodificado, então você nunca carrega capacidade excedente junto. Terceira, "TWFu" decodifica para a palavra "Man", três bytes, zero surpresas, o que faz dele o teste de fumaça perfeito para qualquer código de decodificação que você escrever.

O que o decodificador perdoa, o que ele recusa

Aqui é onde o decodificador do .NET tem personalidade, e uma marcante: ele é generoso com uma coisa e impiedoso com tudo o mais. A coisa generosa é o espaço em branco. O decodificador pula exatamente quatro caracteres, não importa onde apareçam: o espaço (U+0020), a tabulação (U+0009), o line feed (U+000A) e o carriage return (U+000D). Essa política é um aceno deliberado ao e-mail, onde payloads Base64 chegam embrulhados em linhas curtas, e significa que um anexo embrulhado em MIME decodifica com zero pré-processamento. Um fato curioso: essa tolerância é compartilhada por toda a família embutida, incluindo a classe baseada em spans System.Buffers.Text.Base64 e a classe segura para URL Base64Url, então você recebe o mesmo comportamento permissivo não importar qual API você escolher. Qualquer coisa fora do alfabeto de 64 símbolos, qualquer regra de comprimento quebrada ou qualquer padding mal colocado ganha uma exceção. Aqui está o mesmo decodificador encontrando algumas entradas diferentes:

Entrada Resultado
"TWFu" Decodifica para Man (3 bytes).
"TWF" + CRLF + "u" Decodifica para Man. Quebras de linha no meio são invisíveis para o decodificador.
"TWFu" + espaço não separável FormatException. Apenas os quatro caracteres de espaço em branco acima são pulados; um espaço não separável não é um deles.
"TWE" FormatException. Ignorando espaços em branco, o comprimento deve ser um múltiplo de 4.
"TWFu=" FormatException. Padding depois que os dados acabaram não é permitido.
"====" FormatException. Mais de dois caracteres de padding é inválido.
"" ou apenas espaços em branco Um array de bytes vazio. Um sucesso silencioso e válido.
"TW=u" FormatException. Padding no meio é inválido.

Então o contrato honesto é pequeno e memorizável: uma referência Nothing lança ArgumentNullException, uma entrada vazia ou apenas com espaços em branco decodifica para um array vazio, uma entrada válida decodifica para bytes, e qualquer outra coisa inválida lança uma exceção bem específica, FormatException.

De bytes a texto: escolhendo o conjunto de caracteres

No momento em que você decide que os bytes decodificados são na verdade texto, você precisa nomear um conjunto de caracteres, porque bytes não são texto até você dizer como lê-los. Strings do Visual Basic são internamente UTF-16, mas os bytes saindo do decodificador foram feitos por alguém mais, provavelmente sob um esquema diferente, então você tem que bater com a escolha deles. O menu prático:

  • Encoding.UTF8: o padrão seguro para qualquer coisa que viajou pela web ou por uma API. Em caso de dúvida, comece aqui.
  • Encoding.Unicode: UTF-16 little-endian, o sabor nativo do .NET. Razoável quando os dois lados da troca são programas .NET que explicitamente escolheram UTF-16.
  • Encoding.ASCII: apenas 7 bits. Bytes não-ASCII são substituídos por um ponto de interrogação, então esta é uma escolha com perda que destrói acentos em silêncio.
  • 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 Encoding.UTF8.
Imports System
Imports System.Text
Module CharsetDemo
    Sub Main()
        ' A palavra "Café" armazenada como bytes UTF-8
        Dim bytes() As Byte = System.Convert.FromBase64String("Q2Fmw6k=")
        Dim correct As String = Encoding.UTF8.GetString(bytes)
        Console.WriteLine(correct)
        ' Café
    End Sub
End Module

Leia os mesmos cinco bytes com Encoding.Unicode no lugar e você ganha uma curta string de balburdia - alguns caracteres estranhos da faixa CJK mais um sinal de substituição - porque o decodificador casa os bytes dois a dois. Leia os bytes UTF-8 de "Café" com Encoding.ASCII e o acento vira ??, um par de pontos de interrogação, porque o acento é dois bytes em UTF-8. Nenhuma dessas escolhas lança exceção; elas apenas produzem em silêncio o texto errado, que é por isso que o conjunto de caracteres é uma decisão que você toma de propósito, não um padrão que você herda.

O alfabeto seguro para URL: Base64Url

O Base64 padrão usa + e /, e ambos esses caracteres carregam seus próprios significados dentro de URLs, então um alfabeto padrão pode quebrar um link no momento em que pousa numa query string. A correção, padronizada na seção 5 do RFC 4648, é a variante segura para URL e nome de arquivo: o mesmo esquema de 64 caracteres com - ocupando o lugar de + e _ ocupando o lugar de /, e com o padding no final tipicamente descartado porque ele é implícito pelo comprimento. Você vai encontrar esse alfabeto em JWTs, tokens de API e em qualquer lugar onde o Base64 viaje dentro de uma URL. O .NET 9 adicionou uma classe dedicada para ele, System.Buffers.Text.Base64Url, e ela é um prazer de usar:

Imports System.Buffers.Text
Imports System.Text
Module UrlSafeOpener
    Sub Main()
        ' Entrada segura para URL, sem padding no final
        Dim packed As String = "SGVsbG8gd29ybGQ"
        Dim bytes() As Byte = Base64Url.DecodeFromChars(packed)
        Dim text As String = Encoding.UTF8.GetString(bytes)
        Console.WriteLine(text)
        ' Hello world
    End Sub
End Module

Dois comportamentos valem a pena conhecer. O codificador Base64Url produz saída sem padding por design, mas o decodificador dele aceita tanto entrada com padding quanto sem, então ele é amigável com dados de outros ecossistemas. E o Base64Url.IsValid deixa você pré-checar uma string candidata antes de decodificar, o que é útil quando os dados vêm do mundo exterior. Se você está preso num runtime mais antigo sem a classe, a conversão é duas trocas de caracteres e um reforço de padding, exatamente o inverso do que o codificador fez:

Imports System
Module CompatOpener
    Function FromUrlSafe(ByVal packed As String) As Byte()
        Dim standard As String = packed.Replace("-"c, "+"c).Replace("_"c, "/"c)
        Select Case standard.Length Mod 4
            Case 2
                standard &= "=="
            Case 3
                standard &= "="
        End Select
        Return System.Convert.FromBase64String(standard)
    End Function
End Module

No .NET Framework 4.6.2 ou mais novo, em vez disso, você pode instalar o pacote NuGet Microsoft.Bcl.Memory e usar a classe de verdade Base64Url. De qualquer jeito, a regra é simples: reconheça o alfabeto pelo contexto (URL, JWT, token de API) e depois escolha o decodificador correspondente.

Abrindo arquivos

Um dos usos mais antigos do Base64 é contrabandear binário por arquivos de texto: um arquivo .b64 ou .txt que contém bytes codificados. No Visual Basic, a ida e volta são duas chamadas de arquivo e uma decodificação. Leia o texto, decodifique, escreva os bytes:

Imports System.IO
Module FileOpener
    Sub Main()
        Dim packed As String = File.ReadAllText("payload.b64")
        Dim bytes() As Byte = System.Convert.FromBase64String(packed)
        File.WriteAllBytes("payload.bin", bytes)
    End Sub
End Module

A tolerância a espaços em branco torna isso robusto de um jeito satisfatório: o arquivo não se importa se o payload foi escrito como uma linha longa, embrulhado a 76 caracteres ou embrulhado a 64, porque o decodificador pula as quebras de linha de qualquer jeito. Guarde um fato de dimensionamento no bolso: o arquivo de texto é cerca de um terço maior que o binário que ele esconde, então um arquivo de 10 megabytes chega como uns 13,3 megabytes de caracteres. Nada dramático, mas é o número para lembrar quando um arquivo de texto "pequeno" parece grande.

Imagens e data URIs

O esquema data URI (RFC 2397) deixa uma URL carregar o próprio conteúdo: data: seguido do media type, do marcador literal ;base64, de uma vírgula e então dos bytes codificados. Você já o viu em toda parte na web, em HTML e CSS, onde ele embute imagens e fontes pequenas diretamente no markup em vez de apontar para um arquivo separado. No Visual Basic, desembalar uma é apenas dividir uma string e decodificar. O exemplo abaixo tira um PNG de uma data URI e constrói uma imagem WPF a partir dele:

Imports System.IO
Imports System.Windows.Media.Imaging
Module DataUriOpener
    Function ImageFromDataUri(ByVal dataUri As String) As BitmapImage
        Dim comma As Integer = dataUri.IndexOf(","c)
        Dim header As String = dataUri.Substring(0, comma)
        If Not header.EndsWith(";base64") Then
            Throw New FormatException("Not a base64 data URI")
        End If
        Dim packed As String = dataUri.Substring(comma + 1)
        Dim bytes() As Byte = System.Convert.FromBase64String(packed)
        Dim image As New BitmapImage()
        image.BeginInit()
        image.CacheOption = BitmapCacheOption.OnLoad
        image.StreamSource = New MemoryStream(bytes)
        image.EndInit()
        Return image
    End Function
End Module

Note a verificação defensiva no header: uma data URI sem o marcador ;base64 contém em vez disso dados URL-escaped, e decodificá-los como Base64 vai ou falhar ou produzir lixo. O próprio RFC avisa que data URIs só são úteis para valores curtos, e o HTML tem seus próprios limites de comprimento de atributo, então trate isso como a ferramenta certa para ícones, avatares e miniaturas, em vez de despachar sua biblioteca inteira de fotos num único atributo.

HTTP, APIs e Basic Auth

O Base64 está em toda parte nas APIs web, e as duas aparições mais comuns são o header de autenticação Basic HTTP e campos JSON que carregam dados binários ou pré-codificados. Basic auth é o caso mais simples: o cliente envia Authorization: Basic seguido do Base64 de username:password. Decodificá-lo no Visual Basic é uma verificação de prefixo e uma chamada:

Imports System
Imports System.Text
Module BasicAuthOpener
    Function ReadCredentials(ByVal header As String) As String
        If Not header.StartsWith("Basic ", StringComparison.OrdinalIgnoreCase) Then
            Throw New FormatException("Not a Basic auth header")
        End If
        Dim packed As String = header.Substring(6)
        Dim bytes() As Byte = System.Convert.FromBase64String(packed)
        Return Encoding.UTF8.GetString(bytes)
    End Function
End Module

A função devolve username:password como uma única string, que você depois divide no dois-pontos. O outro caso do dia a dia é uma resposta JSON onde algum campo é um blob pré-codificado, como uma imagem ou um certificado. Com HttpClient e System.Text.Json (System.Text.Json está na caixa desde o .NET Core 3.0, e o HttpClient bem antes disso), o padrão é direto:

Imports System.Net.Http
Imports System.Text.Json
Module ApiOpener
    Async Function ReadImageAsync() As Task(Of Byte())
        Using client As New HttpClient()
            Dim json As String = Await client.GetStringAsync("https://httpbin.org/get?attachment=TWFuIGlzIGhlcmU%3D&name=man.txt")
            Dim doc As JsonDocument = JsonDocument.Parse(json)
            Dim packed As String = doc.RootElement.GetProperty("args").GetProperty("attachment").GetString()
            Return System.Convert.FromBase64String(packed)
        End Using
    End Function
End Module

Duas notas de boa ordem. Nunca imprima uma credencial decodificada num log ou numa UI só porque você pode, e nunca confie em Basic auth sobre HTTP puro, porque aí você simplesmente escreveu a senha num alfabeto mais interessante.

JWTs: lendo as três peças

Um JSON Web Token em sua forma compacta é três peças de Base64Url separadas por pontos: o header, o payload e a assinatura. As duas primeiras são JSON puro que você pode ler com os olhos (ou com uma chamada de decodificação), enquanto a terceira é uma assinatura criptográfica que deve ser verificada com a chave certa, não decodificada. Um token de exemplo de uma demo comum é assim: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.W-5gI_FdnMBdpgG4twX96rptvh13gmXQ75kKLRXVaGs. Ler o payload dele no Visual Basic significa dividir nos pontos, converter o alfabeto seguro para URL de volta ao padrão e decodificar:

Imports System
Imports System.Text
Module JwtOpener
    Function ReadPayload(ByVal token As String) As String
        Dim parts() As String = token.Split("."c)
        If parts.Length <> 3 Then
            Throw New FormatException("Not a compact JWT")
        End If
        ' Converta o alfabeto seguro para URL de volta ao padrão
        Dim packed As String = parts(1).Replace("-"c, "+"c).Replace("_"c, "/"c)
        Select Case packed.Length Mod 4
            Case 2
                packed &= "=="
            Case 3
                packed &= "="
        End Select
        Dim bytes() As Byte = System.Convert.FromBase64String(packed)
        Return Encoding.UTF8.GetString(bytes)
    End Function
End Module

Rode isso contra o token de exemplo e você ganha o JSON {"sub":"1234567890","name":"John Doe"}. Leia o header do mesmo jeito e você ganha {"alg":"HS256","typ":"JWT"}. O aviso que importa aqui: ler um JWT não é verificá-lo. Qualquer um pode fabricar um token, então antes de confiar em qualquer claim dentro de um, valide a assinatura com a chave do emissor. Para esse trabalho, o pacote NuGet System.IdentityModel.Tokens.Jwt (a suíte IdentityModel da equipe Microsoft Entra) cuida dos detalhes Base64Url, da verificação de assinatura e da análise de claims para você, que é exatamente a camada onde você não quer estar fazendo tudo na mão.

Anexos de e-mail, embrulhados a 76 caracteres

O e-mail é onde o Base64 fez sua reputação. O SMTP foi desenhado 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) escolheu o Base64 com um limite de linha de 76 caracteres, um parente próximo das linhas ainda mais antigas de 64 caracteres do PEM. Se você já recebeu um e-mail cru, você viu o resultado: um bloco de Base64 denso, quebrado em linhas curtas e arrumadas, sob um header Content-Transfer-Encoding: base64. A parte bonita para um decodificador é que você não precisa desembrulhar nada. O decodificador do .NET pula quebras de linha e espaços onde quer que apareçam, então o bloco embrulhado decodifica como está:

Imports System
Imports System.Text
Module MimeOpener
    Sub Main()
        ' Uma frase de 59 bytes, embrulhada em MIME a 76 caracteres com CRLF
        Dim wrapped As String = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZywgYW5kIHRoZW4gc29t" & vbCr & vbLf & "ZS4="
        Dim bytes() As Byte = System.Convert.FromBase64String(wrapped)
        Console.WriteLine(Encoding.UTF8.GetString(bytes))
        ' The quick brown fox jumps over the lazy dog, and then some.
    End Sub
End Module

Se você está trabalhando com as classes System.Net.Mail, a decodificação é ainda mais invisível: um Attachment que você adiciona a um MailMessage carrega um ContentEncoding de TransferEncoding.Base64, e a biblioteca de e-mail embrulha, envia e desembrulha o ritual inteiro por você. Você só precisa da decodificação manual quando está lendo MIME cru de um stream, de um fixture de teste ou de um arquivo de caixa postal legado.

Bancos de dados, 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. Todos eles querem caracteres puros, então o binário é codificado antes de ser armazenado e decodificado quando volta. O lado da decodificação é sempre o mesmo one-liner, e a parte interessante é a matemática de tamanho. Uma coluna NVARCHAR comum no SQL Server tem teto de 8.000 caracteres, o que significa uns 6.000 bytes de binário antes que o imposto de 33 por cento te empurre para cima; além disso você recorre às variantes 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 "guardar o blob inteiro de licença numa variável de ambiente" tem um teto duro. Aqui está um padrão de decodificação que vale guardar num canto da cabeça: conferir uma impressão digital armazenada contra um arquivo, com uma comparação em tempo constante para que uma divergência não vaze informação de timing:

Imports System.Security.Cryptography
Module FingerprintCheck
    Function FingerprintsMatch(ByVal expectedPacked As String, ByVal fileBytes() As Byte) As Boolean
        Dim expected() As Byte = System.Convert.FromBase64String(expectedPacked)
        Dim actual() As Byte = SHA256.HashData(fileBytes)
        Return CryptographicOperations.FixedTimeEquals(expected, actual)
    End Function
End Module

A mesma forma funciona para qualquer hash armazenado: decodifique o valor guardado, compute o hash fresco e compare em tempo fixo. Arquivos de configuração seguem o padrão idêntico, não importa se o valor veio de uma entrada XML app.config, de um arquivo de configuração JSON ou de uma string do registro.

Big data: decodificando um stream sem carregá-lo

Todos os exemplos até agora leram o payload inteiro para a memória, o que é bom para anexos e valores de configuração, mas errado para um arquivo de dois gigabytes que alguém codificou num arquivo de texto. Para essa escala, o .NET tem um par de streaming que existe desde o .NET Framework 1.1 (2003): o transform criptográfico FromBase64Transform embrulhado num CryptoStream. Você lê pedaços de texto codificado, o transform os decodifica na hora, e você escreve os bytes para fora, então a memória fica plana não importar o quão grande o arquivo seja:

Imports System.IO
Imports System.Security.Cryptography
Module StreamOpener
    Sub DecodeFile(ByVal packedPath As String, ByVal outputPath As String)
        Using packedStream As New FileStream(packedPath, FileMode.Open, FileAccess.Read)
            Using decodedStream As New CryptoStream(packedStream, New FromBase64Transform(), CryptoStreamMode.Read)
                Using outputStream As New FileStream(outputPath, FileMode.Create)
                    Dim buffer(65535) As Byte
                    While True
                        Dim read As Integer = decodedStream.Read(buffer, 0, buffer.Length)
                        If read = 0 Then Exit While
                        outputStream.Write(buffer, 0, read)
                    End While
                End Using
            End Using
        End Using
    End Sub
End Module

Como o arquivo codificado é texto ASCII puro, lê-lo como um stream de bytes é perfeitamente seguro, e o transform cuida do embrulho de linhas sem você fazer nada. O arquivo de saída sai com mais ou menos três quartos do tamanho da entrada, que é o mesmo imposto de 33 por cento pago na ida e cobrado na volta.

Armadilhas que mordem especificamente o Visual Basic

A maioria das armadilhas desta seção é compartilhada com outras linguagens .NET, mas algumas usam um chapéu inequivocamente VB, então aqui estão elas reunidas:

  • Byte versus Byte(). No Visual Basic, um byte único é Byte e um array de bytes é Byte(), com os parênteses vazios fazendo todo o trabalho. Escrever Dim b As Byte quando você quis dizer Byte() é o erro clássico do primeiro dia, e é exatamente o tipo de coisa que o Option Strict On pega em tempo de compilação. Se o seu projeto ainda não o tem ligado, ligue: o modelo dotnet new console -lang VB deixa a decisão com você, enquanto os modelos de projeto do Visual Studio o definem.
  • O muro dos spans. As APIs modernas baseadas em spans podem ser chamadas do VB, mas apenas no ponto de chamada: você pode passar um array Byte() ou Char() direto para um método que aceita um span, e o compilador converte para você. O que você não pode fazer é nomear um span no seu próprio código. Declare uma variável, um campo ou um parâmetro do tipo Span ou ReadOnlySpan e o compilador responde com "Types with embedded references are not supported in this version of your compiler". Então o idioma do VB é: chame as APIs de span com arrays comuns e nunca tente guardar um span numa variável.
  • BitConverter não é Base64. BitConverter.ToString(bytes) renderiza bytes como hex, separados por traços, o que faz dele uma resposta errada tentadora para qualquer um que já ouviu "converta bytes em string". Ele vai te entregar 4D-61-6E com toda a boa vontade quando a API espera TWFu. Em caso de dúvida, recorra ao System.Convert.
  • MidB é um fantasma. O Visual Basic clássico tinha funções de string em nível de byte, MidB, LeftB e RightB, voltadas para conjuntos de caracteres de dois bytes. Toda string .NET é Unicode agora, e a documentação do runtime é direta: elas não são mais suportadas. Se um trecho legado as usa, reescreva-o com arrays de bytes e as APIs deste artigo.
  • Encoding.Default segue a máquina. A história da divergência de locale é do .NET Framework: no .NET moderno, Default é sempre UTF-8, então os mesmos bytes decodificam do mesmo jeito em toda parte. Para dados que você compartilha, nomeie a codificação explicitamente, geralmente Encoding.UTF8 - o conselho vale nos dois casos.
  • Ida e volta não são identidade. Se você decodifica uma string e depois codifica o resultado, a nova string não é garantida para bater com a original: espaços em branco desaparecem, e o padding é normalizado. Um payload com quebras de linha volta como uma linha limpa. Bom para dados, perigoso se a sua lógica compara o texto codificado em vez dos bytes decodificados.
  • Entrada apenas com espaços em branco é um sucesso silencioso. Uma string de apenas espaços e quebras de linha decodifica para um array de bytes vazio sem nenhum erro, o que significa que "o usuário colou só quebras de linha" parece exatamente "o usuário colou um payload vazio". Se a distinção importa, cheque o comprimento da entrada antes de decodificar.

Boas práticas para decodificação

Destilado de tudo acima, os hábitos que mantêm o código de decodificação chato (no melhor sentido):

  • Trate o Base64 como transporte, não como proteção. Ele é uma codificação, não criptografia: qualquer um lê o original com uma chamada de função, e o RFC 4648 nem deixa de anotar que um manuseio descuidado do alfabeto pode abrir canais ocultos. Crie primeiro e depois codifique, se você precisar esconder conteúdo.
  • Para entrada não confiável, prefira os métodos Try ou uma pré-checagem IsValid em vez de deixar o FormatException voar. Um boolean é mais fácil de transformar numa mensagem de erro amigável do que uma exceção de engolir.
  • Escolha o conjunto de caracteres deliberadamente, e padrão em UTF-8 a menos que você tenha um motivo documentado para outro esquema.
  • Bata o alfabeto com a origem: Base64 padrão para MIME, e-mail e configuração; Base64Url para JWTs e qualquer coisa dentro de uma URL.
  • Envie qualquer coisa grande em stream através de FromBase64Transform e CryptoStream em vez de carregá-la numa string.
  • Compare impressões digitais e hashes com CryptographicOperations.FixedTimeEquals, não =, para que o timing não vaze quanta parte do valor bateu.
  • Mantenha Option Strict On para que a família de escorregões Byte/Byte() seja um erro de compilação em vez de um mistério de produção.

Como o Visual Basic ganhou o decodificador

A história começa numa era em que o Visual Basic não tinha Base64 de jeito nenhum. No mundo do Visual Basic 6 e do VBA (a linguagem de macros que ainda roda dentro do Excel e do Office hoje), desenvolvedores que precisavam de Base64 o pegavam emprestado dos componentes COM que já estavam na máquina. O truque famoso usava um elemento XML DOM: o parser MSXML deixa um nó declarar seu DataType como bin.base64, então atribuir uma string Base64 à propriedade text do nó e ler de volta o nodeTypedValue dele entrega os bytes crus, 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", que é por isso que o truque recorre ao MSXML em vez disso). A codificação rodava a mesma ideia ao contrário, escrevendo bytes no nodeTypedValue e lendo a string codificada de volta do text:

' O truque clássico de decodificação VB6 / VBA, para contexto
Dim node As Object
Set node = CreateObject("MSXML2.DOMDocument").createElement("b64")
node.DataType = "bin.base64"
node.text = packed            ' a string Base64
Dim bytes() As Byte
bytes = node.nodeTypedValue

Funcionava, era esperto, e é a razão pela qual "base64 VBA" ainda acende motores de busca três décadas depois. Então 2002 mudou tudo: o Visual Basic 7.0 (a primeira versão .NET da linguagem, na época chamado Visual Basic .NET) entrou no novo Common Language Runtime, e o .NET Framework trouxe System.Convert com FromBase64String e seus amigos de fábrica. Desde o .NET Framework 1.1 em 2003, todo programa VB tinha um decodificador de primeira classe sem componentes a registrar. A onda moderna chegou em 2018 com o .NET Core 2.1, que adicionou os métodos Try sem exceções e a classe rápida baseada em spans System.Buffers.Text.Base64, e em 2024 com o .NET 9, que finalmente padronizou o alfabeto seguro para URL como Base64Url. Em 2026, o .NET 10 - lançado em novembro de 2025 - é a release de suporte de longo prazo, e as bibliotecas de preview do .NET 11 estão adicionando uma nova geração de métodos de conveniência Base64, então o decodificador continua ficando melhor mesmo com o one-liner original de 2003 seguindo sem mudanças.

Fatos curiosos do mundo VB

  • O compilador oficial do Visual Basic é ele mesmo escrito em Visual Basic. Como parte do projeto open source Roslyn, a linguagem se compila a si mesma.
  • O primeiro Visual Basic foi lançado em 1991, antes da era da web ter pegado. O grande momento do Base64 chegou com o MIME em 1993, e o próprio VB ganhou capacidade de 32 bits dois anos depois, quando o Visual Basic 4, em 1995, tornou possível programas de 32 bits pela primeira vez. O VB 5, em 1997, foi até o fim: apenas 32 bits, nenhum 16 bits ficou na caixa.
  • As funções em nível de byte MidB, LeftB e RightB do VB clássico são oficialmente "não mais suportadas" no .NET, porque toda string VB é Unicode desde o primeiro dia do framework. Uma família inteira de APIs, aposentada por uma escolha de codificação.
  • A maquinaria Base64 do runtime não é uma consulta fofa a uma tabela: a implementação moderna roda caminhos de código vetorizados em hardware (variantes AVX-512, AVX2 e SSE) quando a máquina os suporta, então "codec de texto lento" não é o que está acontecendo por baixo do capô.
  • O truque bin.base64 do MSXML da era VB6 ainda roda em macros Excel de produção hoje, o que significa que um workaround do fim dos anos 1990 e uma chamada Convert de 2003 convivem tranquilamente na base de código da mesma organização.

Antes de ir

Este artigo cobriu o lado da decodificação do Base64 no Visual Basic, do one-liner ao streaming, dos JWTs às armadilhas que usam chapéu VB. A outra metade da moeda, transformar seus bytes e texto em Base64 em primeiro lugar, tem seu próprio conjunto de decisões sobre padding, quebras de linha e o imposto de tamanho, e ela é coberta em todos os detalhes no artigo companheiro de codificaçã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 conferir um payload pequeno na mão.

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

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