¿Tiene que ocuparse del formato Base64? Entonces esta página es perfecta para Ud. Utilice nuestra práctica herramienta en línea para codificar o decodificar sus datos.

Decodificación Base64 en Visual Basic: una guía completa

Imagina la escena: una cadena aterriza en tu proyecto de Visual Basic. Tiene pinta de una baraja barajada de letras y dígitos, con el ocasional signo más, barra o signo de igual mezclado entre ellos, y la persona que te la envió jura que en su día fue una frase perfectamente corriente, un JPEG o un montón de datos de configuración. Esa cadena es Base64, y esta página es tu guía de campo para convertirla de nuevo en lo que era. La buena noticia de entrada: Visual Basic lleva un decodificador Base64 de primera clase desde los orígenes del .NET Framework, viaja dentro del runtime, y no necesitas instalar ni un solo paquete para usarlo.

Un repaso rápido, porque la página de inicio de este sitio explica el formato a fondo: Base64 escribe tres bytes como cuatro caracteres tomados de un alfabeto de 64 símbolos, y uno o dos caracteres = al final marcan dónde acabó el dato real. Así que el texto codificado va un poco hinchado respecto al original: cuatro caracteres por cada tres bytes de entrada, aproximadamente un tercio más. Decodificar es simplemente hacer ese intercambio al revés. Con la forma del problema en la cabeza, abramos algunos sobres.

La familia de decodificadores: un runtime, cuatro eras

Todo lo que necesitas para decodificar vive en el runtime de .NET. En las últimas dos décadas ha crecido en cuatro oleadas, y las oleadas antiguas siguen funcionando exactamente como siempre, así que las verás a todas por ahí:

API Disponible desde Para qué sirve
System.Convert.FromBase64String .NET Framework 1.1 (2003) El clásico. Entra una cadena, sale un array Byte() nuevo. Lanza excepción con entrada mala.
System.Convert.FromBase64CharArray .NET Framework 1.1 (2003) La misma decodificación, leyendo de una porción de un array de caracteres que ya es tuyo.
System.Convert.TryFromBase64String, TryFromBase64Chars .NET Core 2.1 (2018) Booleano en vez de excepciones, escribiendo en un buffer que tú proporcionas. La guardia amable para la entrada no confiable.
System.Buffers.Text.Base64 .NET Core 2.1 (2018) Decodificación de bajo nivel, basada en spans: códigos de estado en vez de excepciones, desinflado in-place y comprobaciones previas con IsValid.
System.Buffers.Text.Base64Url .NET 9 (2024) El alfabeto URL-safe (- y _ en vez de + y /), con padding opcional. En runtimes más antiguos viaja en el paquete NuGet Microsoft.Bcl.Memory.
FromBase64Transform + CryptoStream .NET Framework 1.1 (2003) Decodificación por streaming: de archivo a archivo, de la red al disco, trozo a trozo, sin mantener el paquete completo en memoria.

Una aclaración de Visual Basic antes de seguir. En un proyecto VB el nombre suelto Convert se resuelve a System.Convert, porque las plantillas de proyecto estándar importan el espacio de nombres System por ti, y nada en el runtime de Visual Basic eclipsa ese nombre. Aun así, este artículo escribe sobre todo la forma completa System.Convert: no cuesta nada, y deja la intención sin lugar a dudas para cualquiera que lea el código.

Sobre versiones: .NET 10 es la release actual de soporte a largo plazo (noviembre de 2025, soportada hasta noviembre de 2028), y tanto .NET 8 como .NET 9 siguen soportadas hasta noviembre de 2026, mientras que .NET 11 está en vista previa y añade un lote de nuevos métodos cómodos de Base64. Las APIs de decodificación son estables en todas ellas. La única puerta de versión es Base64Url: viene integrada desde .NET 9 en adelante, y en .NET Framework 4.6.2 o superior puedes incorporarla con el paquete Microsoft.Bcl.Memory. Nada más de este artículo necesita un paquete.

Si empiezas de cero, el SDK de .NET incluye Visual Basic en la caja, así que esta es toda la ceremonia:

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

Con eso tienes un pequeño Program.vb con Imports System arriba, y ya estás listo para decodificar.

La línea mágica: FromBase64String

El noventa por ciento de la vida de decodificación en Visual Basic es una única llamada. Lésele una cadena, y te devuelve los bytes exactos que iban empaquetados 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

Tres cosas valen la pena grabar en la memoria. Primero, el resultado son bytes, no texto: el decodificador trabaja con bytes de principio a fin, que es exactamente lo que quieres, porque el paquete puede ser una frase, un JPEG, un certificado o un hash, y ninguno de ellos debería tratarse de forma especial. Convertir esos bytes en una cadena legible es un paso aparte y deliberado a través de un objeto Encoding, y ese paso es donde vive tu decisión del charset (más abajo se habla de ello). Segundo, FromBase64String asigna un array nuevo del tamaño exacto de la longitud decodificada, así que nunca arrastras capacidad sobrante. Tercero, "TWFu" decodifica a la palabra "Man", tres bytes, cero sorpresas, lo que la convierte en la prueba de humo perfecta para cualquier código de decodificación que escribas.

Lo que el decodificador perdona, y lo que se niega

Aquí es donde el decodificador de .NET tiene personalidad, y de las que se notan: es generoso con una cosa y sin piedad con todo lo demás. La cosa generosa es el espacio en blanco. El decodificador salta exactamente cuatro caracteres, estén donde estén: el espacio (U+0020), la tabulación (U+0009), el salto de línea (U+000A) y el retorno de carro (U+000D). Esa política es un guiño deliberado al email, donde los paquetes Base64 llegan envueltos en líneas cortas, y significa que un adjunto envuelto en MIME se decodifica sin ningún preprocesamiento. Dato curioso: esta tolerancia la comparte toda la familia integrada, incluidas la clase basada en spans System.Buffers.Text.Base64 y la URL-safe Base64Url, así que obtienes el mismo comportamiento tolerante da igual qué API agarres. Cualquier cosa fuera del alfabeto de 64 símbolos, cualquier regla de longitud rota o cualquier padding mal colocado se lleva una excepción. Aquí tienes al mismo decodificador conociendo unas cuantas entradas distintas:

Entrada Resultado
"TWFu" Decodifica a Man (3 bytes).
"TWF" + CRLF + "u" Decodifica a Man. Los saltos de línea en medio son invisibles para el decodificador.
"TWFu" + espacio no separable FormatException. Solo se saltan los cuatro caracteres de espacio en blanco de arriba; un espacio no separable no es uno de ellos.
"TWE" FormatException. Ignorando los espacios en blanco, la longitud debe ser múltiplo de 4.
"TWFu=" FormatException. El padding después de que los datos han acabado no está permitido.
"====" FormatException. Más de dos caracteres de padding es inválido.
"" o solo espacios en blanco Un array de bytes vacío. Un éxito callado y válido.
"TW=u" FormatException. El padding en medio es inválido.

Así que el contrato honesto es pequeño y memorable: una referencia Nothing lanza ArgumentNullException, una entrada vacía o de solo espacios en blanco decodifica a un array vacío, la entrada válida decodifica a bytes, y todo lo demás inválido lanza una excepción muy concreta, FormatException.

De bytes a texto: eligiendo el charset

En el momento en que decides que los bytes decodificados son en realidad texto, tienes que nombrar un charset, porque los bytes no son texto hasta que dices cómo leerlos. Las cadenas de Visual Basic son UTF-16 por dentro, pero los bytes que salen del decodificador los hizo alguien más, probablemente bajo otro esquema, así que tienes que ajustar tu lectura a su elección. El menú práctico:

  • Encoding.UTF8: el valor seguro por defecto para todo lo que ha viajado por la web o a través de una API. Si dudas, empieza aquí.
  • Encoding.Unicode: UTF-16 little-endian, el sabor nativo de .NET. Sensato cuando ambos lados del intercambio son programas .NET que eligieron UTF-16 a propósito.
  • Encoding.ASCII: solo de 7 bits. Los bytes no ASCII se sustituyen por un signo de interrogación, así que es una elección con pérdida que destruye acentos en silencio.
  • Encoding.Default: en .NET Framework era la página de códigos ANSI de la máquina, pero en .NET (Core) es siempre UTF-8 sin importar la localización. Evítalo igualmente para datos que intercambias - nombra la codificación explícitamente, normalmente Encoding.UTF8.
Imports System
Imports System.Text
Module CharsetDemo
    Sub Main()
        ' La palabra "Café" guardada 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

Lee esos mismos cinco bytes con Encoding.Unicode y obtienes una cadena corta de disparates - un par de caracteres extraños del rango CJK más un signo de sustitución - porque el decodificador empareja los bytes de dos en dos. Lee los bytes UTF-8 de "Café" con Encoding.ASCII y el acento se convierte en ??, un par de signos de interrogación, porque el acento son dos bytes en UTF-8. Ninguna de estas opciones lanza excepción; simplemente producen el texto equivocado en silencio, y por eso el charset es una decisión que tomas a propósito, no un valor por defecto que heredas.

El alfabeto URL-safe: Base64Url

El Base64 estándar usa + y /, y ambos caracteres tienen sus propios significados dentro de las URLs, así que el alfabeto estándar puede romper un enlace en el momento en que cae en una query string. La solución, estandarizada en la sección 5 del RFC 4648, es la variante segura para URLs y nombres de archivo: el mismo esquema de 64 caracteres con - tomando el lugar de + y _ tomando el lugar de /, y con el padding final típicamente omitido porque se sobreentiende por la longitud. Te encontrarás con este alfabeto en JWTs, tokens de API y en cualquier sitio donde el Base64 viaje dentro de una URL. .NET 9 añadió una clase dedicada para ello, System.Buffers.Text.Base64Url, y da un gusto enorme usarla:

Imports System.Buffers.Text
Imports System.Text
Module UrlSafeOpener
    Sub Main()
        ' Entrada URL-safe, sin padding al 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

Dos comportamientos valen la pena conocerlos. El codificador Base64Url produce salida sin padding por diseño, pero su decodificador acepta entradas con y sin padding, así que es amable con los datos de otros ecosistemas. Y Base64Url.IsValid te deja precomprobar una cadena candidata antes de decodificar, lo que viene bien cuando los datos vienen del mundo exterior. Si te atascas en un runtime más antiguo sin la clase, la conversión es un intercambio de dos caracteres y un relleno de padding, exactamente al revés de lo que hizo el codificador:

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

En .NET Framework 4.6.2 o superior puedes en su lugar instalar el paquete NuGet Microsoft.Bcl.Memory y usar la clase Base64Url de verdad. En cualquier caso, la regla es simple: reconoce el alfabeto por el contexto (URL, JWT, token de API) y elige el decodificador que corresponda.

Abriendo archivos

Uno de los usos más antiguos del Base64 es colar binarios por archivos de texto: un archivo .b64 o .txt que contiene bytes codificados. En Visual Basic el recorrido completo son dos llamadas de archivo y una decodificación. Lee el texto, decodifícalo, escribe los 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

La tolerancia con los espacios en blanco lo hace robusto de una forma satisfactoria: al archivo no le importa si el paquete se escribió como una sola línea larga, envuelto a los 76 caracteres o envuelto a los 64, porque el decodificador salta los saltos de línea en cualquier caso. Guarda un dato de tamaño en la manga: el archivo de texto es aproximadamente un tercio más grande que el binario que esconde, así que un archivo de 10 megabytes llega como unos 13,3 megabytes de caracteres. Nada dramático, pero es el número que recordarás cuando un archivo de texto "pequeño" se sienta grande.

Imágenes y data URIs

El esquema data URI (RFC 2397) permite que una URL lleve su propio contenido: data: seguido del tipo de medio, el marcador literal ;base64, una coma, y luego los bytes codificados. Lo has visto por toda la web, en HTML y CSS, donde incrusta imágenes pequeñas y fuentes directamente en el marcado en vez de apuntar a un archivo separado. En Visual Basic, desembalar uno es solo un corte de cadena y una decodificación. El ejemplo de abajo saca un PNG de un data URI y construye una imagen WPF a partir de él:

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

Fíjate en la comprobación defensiva de la cabecera: un data URI sin el marcador ;base64 contiene en su lugar datos escapados en URL, y decodificarlos como Base64 fallaría o produciría basura. El propio RFC avisa de que los data URIs solo son útiles para valores cortos, y el HTML tiene sus propios límites de longitud de atributo, así que trátalo como la herramienta correcta para iconos, avatares y miniaturas, no para enviar toda tu biblioteca de fotos en un solo atributo.

HTTP, APIs y Basic Auth

El Base64 está por todas partes en las APIs web, y las dos apariciones más comunes son la cabecera HTTP de Basic auth y los campos JSON que llevan datos binarios o precodificados. La Basic auth es el caso más simple: el cliente envía Authorization: Basic seguido del Base64 de username:password. Decodificarlo en Visual Basic es una comprobación de prefijo y una llamada:

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

La función devuelve username:password como una cadena única, que luego cortas por la dos puntos. El otro caso cotidiano es una respuesta JSON donde algún campo es un blob precodificado, como una imagen o un certificado. Con HttpClient y System.Text.Json (System.Text.Json está en la caja desde .NET Core 3.0, y HttpClient mucho antes) el patrón es directo:

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

Dos notas de buena casa. Nunca imprimas una credencial decodificada en un log o en una UI solo porque puedas, y nunca confíes en la Basic auth sobre HTTP plano, porque entonces simplemente has escrito la contraseña con un alfabeto más interesante.

JWTs: leyendo las tres piezas

Un JSON Web Token en su forma compacta son tres piezas de Base64Url separadas por puntos: la cabecera, el payload y la firma. Las dos primeras son JSON plano que puedes leer con los ojos (o con una llamada de decodificación), mientras que la tercera es una firma criptográfica que hay que comprobar con la clave correcta, no decodificar. Un token de muestra de una demo común se ve así: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.W-5gI_FdnMBdpgG4twX96rptvh13gmXQ75kKLRXVaGs. Leer su payload en Visual Basic significa cortar por los puntos, convertir el alfabeto URL-safe de vuelta al estándar y 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
        ' Convertir el alfabeto URL-safe de vuelta al estándar
        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

Ejecuta eso contra el token de muestra y obtienes el JSON {"sub":"1234567890","name":"John Doe"}. Lee la cabecera de la misma forma y obtienes {"alg":"HS256","typ":"JWT"}. El aviso que importa aquí: leer un JWT no es verificarlo. Cualquiera puede fabricar un token, así que antes de confiar en cualquier claim dentro de uno, valida la firma con la clave del emisor. Para ese trabajo, el paquete NuGet System.IdentityModel.Tokens.Jwt (el conjunto IdentityModel del equipo Microsoft Entra) se encarga por ti de los detalles de Base64Url, la comprobación de la firma y el análisis de los claims, que es exactamente la capa donde no quieres estar rodando tu propia solución.

Adjuntos de email, envueltos a 76 caracteres

El email es donde el Base64 ganó su reputación. SMTP se diseñó para ASCII de 7 bits, así que un adjunto binario tiene que convertirse en texto antes de poder volar, y el estándar MIME (RFC 2045) eligió Base64 con un límite de línea de 76 caracteres, un pariente cercano de las líneas de 64 caracteres, aún más antiguas, de PEM. Si alguna vez has recibido un email crudo, has visto el resultado: un bloque de Base64 denso, roto en líneas cortas ordenadas, bajo una cabecera Content-Transfer-Encoding: base64. La parte hermosa para un decodificador es que no tienes que desenrollar nada. El decodificador de .NET salta saltos de línea y espacios dondequiera que aparezcan, así que el bloque envuelto se decodifica tal cual:

Imports System
Imports System.Text
Module MimeOpener
    Sub Main()
        ' Una frase de 59 bytes, envuelta en MIME a 76 caracteres con 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

Si trabajas con las clases System.Net.Mail, la decodificación es aún más invisible: un Attachment que añades a un MailMessage lleva una ContentEncoding de TransferEncoding.Base64, y la librería de correo envuelve, envía y desenrolla el ritual entero por ti. Solo necesitas la decodificación manual cuando lees MIME crudo de un stream, de un fixture de pruebas o de un archivo de buzón legado.

Bases de datos, configuración y variables de entorno

El almacenamiento solo de texto no deja de pedir Base64: una columna de base de datos de tipo texto, un valor de configuración en XML, una variable de entorno. Todos quieren caracteres planos, así que el binario se codifica antes de guardarse y se decodifica cuando vuelve. El lado de decodificación es siempre la misma línea mágica, y la parte interesante es la matemática del tamaño. Una columna NVARCHAR normal en SQL Server llega a un tope de 8.000 caracteres, lo que significa unos 6.000 bytes de binario antes de que el impuesto del 33 por ciento te empuje por encima; más allá de ahí recurres a las variantes MAX o, con más honestidad, a una columna binaria de verdad. En Windows, una variable de entorno definida por el usuario está limitada a 32.767 caracteres (y en sistemas de la época de XP el bloque de entorno entero también estaba limitado a ese tamaño), así que "guardar el blob entero de la licencia en una variable de entorno" tiene un techo duro. Aquí tienes un patrón de decodificación que vale la pena guardar en un rincón de la cabeza: comprobar una huella guardada contra un archivo, con una comparación en tiempo constante para que un descarte no filtre información de temporización:

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

La misma forma funciona para cualquier hash guardado: decodifica el valor guardado, calcula el hash nuevo y compara en tiempo fijo. Los archivos de configuración siguen el patrón idéntico, ya venga el valor de una entrada XML de app.config, de un archivo de ajustes JSON o de una cadena del registro.

Datos grandes: decodifica un stream sin cargarlo

Todos los ejemplos hasta ahora han leído el paquete entero en memoria, lo cual está bien para adjuntos y valores de configuración, pero es incorrecto para un archivo de dos gigabytes que alguien codificó en un archivo de texto. Para esa escala, .NET tiene un par de streaming que existe desde .NET Framework 1.1 (2003): la transformación criptográfica FromBase64Transform envuelta en un CryptoStream. Lees trozos de texto codificado, la transformación los decodifica al vuelo, y escribes los bytes, así que la memoria se mantiene plana por grande que sea el archivo:

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 el archivo codificado es texto ASCII plano, leerlo como un stream de bytes es perfectamente seguro, y la transformación se las arregla con los saltos de línea sin que hagas nada. El archivo de salida sale aproximadamente de tres cuartas partes del tamaño de la entrada, que es el mismo impuesto del 33 por ciento pagado en la ida, cobrado en la vuelta.

Trampas que muerden a Visual Basic específicamente

La mayoría de las trampas de esta sección se comparten con otros lenguajes .NET, pero unas pocas llevan un sombrero claramente de VB, así que aquí las tienes juntas:

  • Byte frente a Byte(). En Visual Basic un byte suelto es Byte y un array de bytes es Byte(), con los paréntesis vacíos haciendo todo el trabajo. Escribir Dim b As Byte cuando querías Byte() es el error clásico del primer día, y es exactamente el tipo de cosa que Option Strict On caza en tiempo de compilación. Si tu proyecto no lo tiene activado ya, actívalo: la plantilla dotnet new console -lang VB deja la decisión en tus manos, mientras que las plantillas de proyecto de Visual Studio lo activan por defecto.
  • El muro de los spans. Las APIs modernas basadas en spans se pueden llamar desde VB, pero solo en el punto de llamada: puedes pasar un array Byte() o Char() directamente a un método que recibe un span, y el compilador lo convierte por ti. Lo que no puedes hacer es nombrar un span en tu propio código. Declara una variable, un campo o un parámetro de tipo Span o ReadOnlySpan y el compilador responde con "Types with embedded references are not supported in this version of your compiler". Así que el idiom de VB es: llama a las APIs de span con arrays planos, y no intentes nunca guardar un span en una variable.
  • BitConverter no es Base64. BitConverter.ToString(bytes) renderiza bytes como hexadecimal, separado por guiones, lo que lo convierte en una respuesta equivocada tentadora para cualquiera que haya oído "convertir bytes a cadena". Te entregará gustosamente 4D-61-6E cuando la API espera TWFu. Si dudas, acude a System.Convert.
  • MidB es un fantasma. El Visual Basic clásico tenía funciones de cadena a nivel de byte, MidB, LeftB y RightB, orientadas a juegos de caracteres de doble byte. Toda cadena .NET es Unicode ahora, y la documentación del runtime es directa: ya no se soportan. Si un fragmento legado los usa, reescríbelo con arrays de bytes y las APIs de este artículo.
  • Encoding.Default sigue a la máquina. La historia de la divergencia por localización es de .NET Framework: en .NET moderno, Default es siempre UTF-8, así que los mismos bytes se decodifican igual en todas partes. Para datos que compartes, nombra la codificación explícitamente, normalmente Encoding.UTF8 - el consejo vale en cualquier caso.
  • Los recorridos de ida y vuelta no son identidad. Si decodificas una cadena y luego codificas el resultado, la cadena nueva no está garantizada para coincidir con la original: los espacios en blanco desaparecen y el padding se normaliza. Un paquete con saltos de línea vuelve como una sola línea limpia. Bien para datos, peligroso si tu lógica compara el texto codificado en vez de los bytes decodificados.
  • La entrada de solo espacios en blanco es un éxito callado. Una cadena de solo espacios y saltos de línea se decodifica a un array de bytes vacío sin ningún error, lo que significa que "el usuario pegó nada más que saltos de línea" se ve exactamente como "el usuario pegó un paquete vacío". Si la distinción importa, comprueba la longitud de la entrada antes de decodificar.

Prácticas recomendadas para decodificar

Destiladas de todo lo anterior, los hábitos que mantienen el código de decodificación aburrido (en el mejor sentido):

  • Trata el Base64 como transporte, no como protección. Es una codificación, no un cifrado: cualquiera puede leer el original con una llamada a una función, y el RFC 4648 ni siquiera deja de apuntar que un manejo descuidado del alfabeto puede abrir canales ocultos. Cifra primero, y codifica después si necesitas ocultar contenido.
  • Para entrada no confiable, prefiere los métodos Try o una precomprobación con IsValid antes que dejar volar FormatException. Un booleano es más fácil de convertir en un mensaje de error amable que una excepción de tragar.
  • Elige el charset a propósito, y usa UTF-8 por defecto a menos que tengas una razón documentada para otro esquema.
  • Ajusta el alfabeto a la fuente: Base64 estándar para MIME, email y configuración; Base64Url para JWTs y todo lo que viaja dentro de una URL.
  • Pasa todo lo grande por streaming a través de FromBase64Transform y CryptoStream en vez de cargarlo en una cadena.
  • Compara huellas y hashes con CryptographicOperations.FixedTimeEquals, no con =, para que la temporización no filtre cuánto del valor coincidía.
  • Mantén Option Strict On para que la familia de tropiezos Byte/Byte() sea un error de compilación en vez de un misterio de producción.

Cómo consiguió su decodificador Visual Basic

La historia empieza en una época en la que Visual Basic no tenía Base64 en absoluto. En el mundo de Visual Basic 6 y VBA (el lenguaje de macros que sigue funcionando dentro de Excel y Office hoy en día), los desarrolladores que necesitaban Base64 lo pedían prestado a los componentes COM que ya estaban en la máquina. El truco famoso usaba un elemento XML DOM: el parser de MSXML deja que un nodo declare su DataType como bin.base64, así que asignar una cadena Base64 a la propiedad text del nodo y leer de vuelta su nodeTypedValue te entrega los bytes crudos, con el DOM haciendo la matemática Base64 de verdad (la propiedad Charset del propio objeto Stream de ADO solo entiende nombres de charset reales como "utf-8" o "iso-8859-1", no "base64", por eso el truco recurre a MSXML). La codificación corría la misma idea al revés, escribiendo bytes en nodeTypedValue y leyendo la cadena codificada de vuelta de text:

' El clásico truco de decodificación VB6 / VBA, para contexto
Dim node As Object
Set node = CreateObject("MSXML2.DOMDocument").createElement("b64")
node.DataType = "bin.base64"
node.text = packed            ' la cadena Base64
Dim bytes() As Byte
bytes = node.nodeTypedValue

Funcionaba, era ingenioso, y es la razón por la que "base64 VBA" sigue encendiendo motores de búsqueda tres décadas después. Luego 2002 lo cambió todo: Visual Basic 7.0 (la primera versión .NET del lenguaje, entonces llamada Visual Basic .NET) se unió al nuevo Common Language Runtime, y el .NET Framework trajo System.Convert con FromBase64String y sus amigos en la caja. Desde .NET Framework 1.1 en 2003, cada programa VB tenía un decodificador de primera clase sin componentes que registrar. La ola moderna llegó en 2018 con .NET Core 2.1, que añadió los métodos Try sin excepciones y la rápida clase basada en spans System.Buffers.Text.Base64, y en 2024 con .NET 9, que por fin estandarizó el alfabeto URL-safe como Base64Url. A fecha de 2026, .NET 10 - lanzado en noviembre de 2025 - es la release de soporte a largo plazo, y las librerías en vista previa de .NET 11 están añadiendo una nueva generación de métodos cómodos de Base64, así que el decodificador sigue mejorando incluso mientras la línea original de 2003 sigue adelante sin cambios.

Datos curiosos del mundo VB

  • El compilador oficial de Visual Basic está escrito él mismo en Visual Basic. Como parte del proyecto open-source Roslyn, el lenguaje se compila a sí mismo.
  • El primer Visual Basic salió en 1991, antes de que la era web hubiera cogido carrera. El gran momento del Base64 llegó con MIME en 1993, y el propio VB creció una capacidad de 32 bits dos años después, cuando Visual Basic 4 en 1995 hizo posibles los programas de 32 bits por primera vez. VB 5 en 1997 se fue hasta el fondo: solo 32 bits, nada de 16 bits en la caja.
  • Las funciones a nivel de byte MidB, LeftB y RightB del VB clásico son oficialmente "ya no compatibles" en .NET, porque cada cadena VB es Unicode desde el primer día del framework. Una familia entera de APIs, retirada por una elección de codificación.
  • El mecanismo Base64 del runtime no es una consultita de tabla encantadora: la implementación moderna corre rutas de código vectorizadas por hardware (variantes AVX-512, AVX2 y SSE) cuando la máquina las soporta, así que "codificador de texto lento" no es lo que pasa por dentro.
  • El truco de MSXML bin.base64 de la era VB6 sigue corriendo hoy en macros de Excel de producción, lo que significa que un pallativo de finales de los 90 y una llamada a Convert de 2003 coexisten felices en la base de código de la misma organización.

Antes de irte

Este artículo ha cubierto el lado de decodificación del Base64 en Visual Basic, desde la línea mágica hasta el streaming, desde JWTs hasta las trampas que llevan sombrero de VB. La otra mitad de la moneda, convertir tus bytes y texto en Base64 en primer lugar, tiene su propio conjunto de decisiones sobre padding, saltos de línea e impuesto de tamaño, y está cubierta en todo detalle en el artículo de codificación compañero del sitio hermano. El enlace a ella está justo debajo de esta línea, y la herramienta de la página de inicio sigue siendo la forma más rápida de comprobar un paquete pequeño a mano.

Última actualización: 2026-09-08

Artículo relacionado: Codificación Base64 en Visual Basic: una guía completa