Base64-Dekodierung in Visual Basic: Ein vollständiger Leitfaden
Stellen Sie sich die Szene vor: Ein String landet in Ihrem Visual-Basic-Projekt. Er sieht aus wie ein gemischtes Blatt aus Buchstaben und Ziffern, hier und da mischt sich ein Pluszeichen, ein Schrägstrich oder ein Gleichheitszeichen darunter, und die Person, die ihn geschickt hat, schwört, dass er einmal ein völlig gewöhnlicher Satz, ein JPEG oder ein Konfigurations-Blob war. Dieser String ist Base64, und diese Seite ist Ihr Praxis-Leitfaden, um ihn wieder in das zu verwandeln, was er einmal war. Die gute Nachricht gleich vorweg: Visual Basic hat seit den allerersten .NET-Framework-Tagen einen erstklassigen Base64-Dekodierer, er steckt direkt in der Laufzeit, und Sie müssen kein einziges Paket installieren, um ihn zu nutzen.
Ein kurzer Wiederholer, denn die Startseite dieser Site erklärt das Format in voller Tiefe: Base64 schreibt drei Bytes als vier Zeichen aus einem Alphabet von 64 Symbolen, und ein oder zwei =-Zeichen am Ende markieren, wo die echten Daten zu Ende waren. Deshalb ist kodierter Text im Vergleich zum Original ein wenig gequollen: vier Zeichen für jeweils drei Eingabe-Bytes, rund ein Drittel mehr. Das Dekodieren läuft einfach diesen Tausch in umgekehrter Richtung ab. Mit dem Grundriss des Problems im Kopf öffnen wir ein paar Umschläge.
Die Dekodierer-Familie: Eine Laufzeit, vier Ären
Alles, was Sie zum Dekodieren brauchen, lebt in der .NET-Laufzeit. In den letzten zwei Jahrzehnten ist sie in vier Wellen gewachsen, und die älteren Wellen funktionieren genau so, wie sie es immer taten, deshalb laufen Ihnen alle davon in freier Wildbahn über den Weg:
| API | Verfügbar seit | Wofür sie da ist |
|---|---|---|
System.Convert.FromBase64String |
.NET Framework 1.1 (2003) | Der Klassiker. Ein String hinein, ein frisches Byte()-Array heraus. Wirft bei ungültiger Eingabe. |
System.Convert.FromBase64CharArray |
.NET Framework 1.1 (2003) | Dasselbe Dekodieren, liest dabei aus einem Ausschnitt eines Zeichen-Arrays, das Sie bereits besitzen. |
System.Convert.TryFromBase64String, TryFromBase64Chars |
.NET Core 2.1 (2018) | Boolesch statt Ausnahmen, schreibt in einen Puffer, den Sie bereitstellen. Der freundliche Wächter für unzuverlässige Eingaben. |
System.Buffers.Text.Base64 |
.NET Core 2.1 (2018) | Niedrigstufiges, spanbasiertes Dekodieren: Statuscodes statt Ausnahmen, In-Place-Dekompression und IsValid-Vorabchecks. |
System.Buffers.Text.Base64Url |
.NET 9 (2024) | Das URL-sichere Alphabet (- und _ statt + und /), mit optionalem Padding. Auf älteren Laufzeiten fährt es im Microsoft.Bcl.Memory-NuGet-Paket mit. |
FromBase64Transform + CryptoStream |
.NET Framework 1.1 (2003) | Streaming-Dekodierung: Datei zu Datei, Netzwerk zu Festplatte, Chunk für Chunk, ohne das ganze Payload im Speicher zu halten. |
Eine Visual-Basic-Präzisierung, bevor wir weitergehen. In einem VB-Projekt löst der nackte Name Convert zu System.Convert auf, denn die Standard-Projektvorlagen importieren den System-Namespace für Sie, und nichts in der Visual-Basic-Laufzeit überlagert diesen Namen. Trotzdem schreibt dieser Artikel meistens die volle System.Convert-Form: Sie kostet nichts, und sie macht die Absicht für jeden, der den Code liest, unmissverständlich.
Zu den Versionen: .NET 10 ist der aktuelle Langzeit-Support-Release (November 2025, unterstützt bis November 2028), und sowohl .NET 8 als auch .NET 9 bleiben bis November 2026 unterstützt, während .NET 11 in der Vorschau ist und eine Ladung neuer Base64-Komfortmethoden mitbringt. Die Dekodierungs-APIs sind über alle Releases hinweg stabil. Die einzige Versionsgrenze ist Base64Url: Es ist ab .NET 9 fest eingebaut, und auf .NET Framework 4.6.2 oder neuer können Sie es mit dem Microsoft.Bcl.Memory-Paket nachziehen. Nichts anderes in diesem Artikel braucht ein Paket.
Wenn Sie von Grund auf anfangen, enthält das .NET-SDK Visual Basic von Haus aus, deshalb ist das die ganze Zeremonie:
dotnet new console -lang VB -o EnvelopeOpener
cd EnvelopeOpener
dotnet run
Das ergibt ein kleines Program.vb mit Imports System oben, und Sie sind bereit zum Dekodieren.
Der Einzeiler: FromBase64String
Neunzig Prozent des Dekodier-Alltags in Visual Basic sind ein einziger Aufruf. Geben Sie ihm einen String, und er gibt Ihnen genau die Bytes zurück, die darin gepackt waren:
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
Drei Dinge lohnen es, sie im Gedächtnis zu verankern. Erstens ist das Ergebnis Bytes, kein Text: Der Dekodierer ist durchweg byteorientiert, was genau das ist, was Sie wollen, denn das Payload könnte ein Satz sein, ein JPEG, ein Zertifikat oder ein Hash, und keiner davon sollte besonders behandelt werden. Die Bytes in einen lesbaren String umzuwandeln, ist ein eigener, bewusster Schritt über ein Encoding-Objekt, und genau dort lebt Ihre Zeichensatz-Entscheidung (mehr dazu unten). Zweitens allokiert FromBase64String ein frisches Array, exakt so groß wie die dekodierten Bytes, damit Sie nie überflüssige Kapazität mit sich herumschleppen. Drittens dekodiert "TWFu" zum Wort "Man", drei Bytes, null Überraschungen, was es zum perfekten Smoke-Test für jeden Dekodier-Code macht, den Sie schreiben.
Was der Dekodierer verzeiht, was er ablehnt
Hier zeigt der .NET-Dekodierer seine Persönlichkeit, und eine charakterstarke noch dazu: Bei einer Sache ist er großzügig, bei allem anderen erbarmungslos. Die großzügige Sache ist der Weißraum. Der Dekodierer überspringt genau vier Zeichen, egal wo sie auftauchen: das Leerzeichen (U+0020), den Tabulator (U+0009), den Zeilenvorschub (U+000A) und den Wagenrücklauf (U+000D). Diese Politik ist eine bewusste Verbeugung vor der E-Mail, in der Base64-Payloads in kurzen Zeilen verpackt ankommen, und sie bedeutet, dass ein MIME-umgebrochener Anhang ohne jede Vorverarbeitung dekodiert wird. Eine lustige Tatsache: Diese Nachsicht teilt die ganze eingebaute Familie, einschließlich der spanbasierten System.Buffers.Text.Base64-Klasse und der URL-sicheren Base64Url-Klasse, so dass Sie dasselbe nachsichtige Verhalten bekommen, welche API Sie auch greifen. Alles außerhalb des Alphabets von 64 Symbolen, jede verletzte Längenregel oder falsch platziertes Padding verdient eine Ausnahme. Hier trifft derselbe Dekodierer auf ein paar verschiedene Eingaben:
| Eingabe | Ergebnis |
|---|---|
"TWFu" |
Dekodiert zu Man (3 Bytes). |
"TWF" + CRLF + "u" |
Dekodiert zu Man. Zeilenumbrüche in der Mitte sind für den Dekodierer unsichtbar. |
"TWFu" + nicht brechendes Leerzeichen |
FormatException. Nur die vier obigen Weißraum-Zeichen werden übersprungen; ein nicht brechendes Leerzeichen ist keines davon. |
"TWE" |
FormatException. Weißraum einmal abgezogen, muss die Länge ein Vielfaches von 4 sein. |
"TWFu=" |
FormatException. Padding nach Ende der Daten ist nicht erlaubt. |
"====" |
FormatException. Mehr als zwei Padding-Zeichen ist ungültig. |
"" oder nur Weißraum |
Ein leeres Byte-Array. Ein stiller, gültiger Erfolg. |
"TW=u" |
FormatException. Padding in der Mitte ist ungültig. |
Der ehrliche Vertrag ist also klein und einprägsam: Eine Nothing-Referenz wirft ArgumentNullException, eine leere oder nur aus Weißraum bestehende Eingabe dekodiert zu einem leeren Array, gültige Eingabe dekodiert zu Bytes, und alles andere Ungültige wirft eine ganz bestimmte Ausnahme, FormatException.
Von Bytes zu Text: Den Zeichensatz wählen
Im Moment, in dem Sie entscheiden, dass die dekodierten Bytes tatsächlich Text sind, müssen Sie einen Zeichensatz benennen, denn Bytes sind erst dann Text, wenn Sie sagen, wie man sie lesen soll. Visual-Basic-Strings sind intern UTF-16, aber die Bytes, die aus dem Dekodierer kommen, wurden von jemand anderem gemacht, wahrscheinlich nach einem anderen Schema, deshalb müssen Sie deren Wahl treffen. Das praktische Menü:
Encoding.UTF8: der sichere Standard für alles, was über das Web oder durch eine API gereist ist. Wenn Sie unsicher sind, fangen Sie hier an.Encoding.Unicode: UTF-16 little-endian, die einheimische Variante von .NET. Sinnvoll, wenn beide Seiten des Austauschs .NET-Programme sind, die ausdrücklich UTF-16 gewählt haben.Encoding.ASCII: nur 7 Bit. Nicht-ASCII-Bytes werden durch ein Fragezeichen ersetzt, das ist also eine verlustbehaftete Wahl, die Akzente still und leise zerstört.Encoding.Default: Auf .NET Framework war das die ANSI-Zeichenseite der Maschine, auf .NET (Core) ist es aber immer UTF-8, unabhängig vom Gebietsschema. Meiden Sie es trotzdem für Daten, die Sie austauschen - benennen Sie die Kodierung ausdrücklich, normalerweiseEncoding.UTF8.
Imports System
Imports System.Text
Module CharsetDemo
Sub Main()
' Das Wort "Café" als UTF-8-Bytes gespeichert
Dim bytes() As Byte = System.Convert.FromBase64String("Q2Fmw6k=")
Dim correct As String = Encoding.UTF8.GetString(bytes)
Console.WriteLine(correct)
' Café
End Sub
End Module
Lesen Sie dieselben fünf Bytes stattdessen mit Encoding.Unicode, und Sie bekommen eine kurze Kette aus Unsinn - ein paar seltsame Zeichen aus dem CJK-Bereich plus ein Ersatzzeichen - weil der Dekodierer die Bytes zu je zwei zusammenfasst. Lesen Sie die UTF-8-Bytes von "Café" mit Encoding.ASCII, wird der Akzent zu ??, einem Paar Fragezeichen, denn der Akzent ist in UTF-8 zwei Bytes. Keine dieser Wahl wirft eine Ausnahme; sie produzieren nur still und leise den falschen Text, deshalb ist der Zeichensatz eine Entscheidung, die Sie absichtlich treffen, kein Standard, den Sie erben.
Das URL-sichere Alphabet: Base64Url
Standard-Base64 verwendet + und /, und beide Zeichen tragen ihre eigenen Bedeutungen innerhalb von URLs, deshalb kann das Standard-Alphabet einen Link kaputtmachen, in dem Moment, in dem er in einem Query-String landet. Die Lösung, standardisiert in RFC 4648, Abschnitt 5, ist die für URLs und Dateinamen sichere Variante: dasselbe 64-Zeichen-Schema, in dem - den Platz von + einnimmt und _ den Platz von /, und bei der das Padding am Ende typischerweise gestrichen wird, weil es sich aus der Länge ergibt. Auf dieses Alphabet treffen Sie in JWTs, API-Tokens und überall dort, wo Base64 in einer URL mitfährt. .NET 9 hat eine eigene Klasse dafür hinzugefügt, System.Buffers.Text.Base64Url, und sie macht Freude bei der Nutzung:
Imports System.Buffers.Text
Imports System.Text
Module UrlSafeOpener
Sub Main()
' URL-sichere Eingabe, kein Padding am Ende
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
Zwei Verhaltensweisen lohnen es, sie zu kennen. Der Base64Url-Kodierer produziert aus Design-Gründen Ausgabe ohne Padding, aber sein Dekodierer akzeptiert sowohl gepaddete als auch ungepaddete Eingabe, ist also freundlich zu Daten aus anderen Ökosystemen. Und Base64Url.IsValid lässt Sie einen Kandidaten-String vor dem Dekodieren vorab prüfen, was praktisch ist, wenn die Daten aus der Außenwelt kommen. Wenn Sie an einer älteren Laufzeit ohne die Klasse feststecken, ist die Umwandlung das Tauschen zweier Zeichen und eine Padding-Auffüllung, genau das Umgekehrte von dem, was der Kodierer getan hat:
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
Auf .NET Framework 4.6.2 oder neuer können Sie stattdessen das Microsoft.Bcl.Memory-NuGet-Paket installieren und die echte Base64Url-Klasse nutzen. Auf jeden Fall ist die Regel einfach: Erkennen Sie das Alphabet aus dem Kontext (URL, JWT, API-Token), und wählen Sie dann den passenden Dekodierer.
Dateien öffnen
Einer der ältesten Anwendungsfälle von Base64 ist das Schmuggeln von Binärdaten durch Textdateien: eine .b64- oder .txt-Datei, die kodierte Bytes enthält. In Visual Basic besteht die Rundreise aus zwei Dateiaufrufen und einem Dekodieren. Lesen Sie den Text, dekodieren Sie ihn, schreiben Sie die 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
Die Weißraum-Nachsicht macht das auf befriedigende Weise robust: Der Datei ist es egal, ob das Payload als eine lange Zeile geschrieben wurde, bei 76 Zeichen umgebrochen oder bei 64 Zeichen umgebrochen, denn der Dekodierer überspringt die Zeilenumbrüche ohnehin. Halten Sie sich eine Größen-Tatsache in der Hinterhand: Die Textdatei ist ungefähr ein Drittel größer als die Binärdaten, die sie versteckt, deshalb kommt eine 10-Megabyte-Datei als rund 13,3 Megabytes Zeichen an. Nicht dramatisch, aber es ist die Zahl, die Sie sich merken, wenn eine "kleine" Textdatei groß wirkt.
Bilder und Data-URIs
Das Data-URI-Schema (RFC 2397) lässt eine URL ihren eigenen Inhalt tragen: data:, gefolgt vom Medientyp, dem wörtlichen Markierer ;base64, einem Komma und dann den kodierten Bytes. Sie haben es überall im Web gesehen, in HTML und CSS, wo es kleine Bilder und Schriften direkt im Markup einbettet, statt auf eine separate Datei zu zeigen. In Visual Basic ist das Auspacken nur ein String-Schnitt und ein Dekodieren. Das Beispiel unten zieht ein PNG aus einem Data-URI und baut daraus ein WPF-Bild:
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
Beachten Sie die defensive Prüfung des Headers: Ein Data-URI ohne den ;base64-Markierer enthält stattdessen URL-escapete Daten, und das als Base64 zu dekodieren, würde entweder fehlschlagen oder Müll produzieren. Der RFC selbst warnt, dass Data-URIs nur für kurze Werte nützlich sind, und HTML hat seine eigenen Attribut-Längen-Grenzen, deshalb betrachten Sie dies als das richtige Werkzeug für Icons, Avatare und Thumbnails, nicht dafür, Ihre ganze Fotobibliothek in einem Attribut zu versenden.
HTTP, APIs und Basic Auth
Base64 ist überall in Web-APIs, und die beiden häufigsten Erscheinungen sind der HTTP-Basic-Auth-Header und JSON-Felder, die Binärdaten oder vorab kodierte Daten tragen. Basic Auth ist der einfachste Fall: Der Client sendet Authorization: Basic, gefolgt vom Base64 von username:password. Das Dekodieren davon in Visual Basic ist ein Präfix-Check und ein Aufruf:
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
Die Funktion gibt username:password als einen einzelnen String zurück, den Sie dann am Doppelpunkt aufteilen. Der andere Alltag-Fall ist eine JSON-Antwort, in der ein Feld ein vorab kodierter Blob ist, wie ein Bild oder ein Zertifikat. Mit HttpClient und System.Text.Json (System.Text.Json ist seit .NET Core 3.0 an Bord, und HttpClient schon lange davor) ist das Muster geradlinig:
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
Zwei praktische Hinweise. Geben Sie dekodiert Zugangsdaten niemals in ein Log oder eine UI aus, nur weil es geht, und verlassen Sie sich niemals auf Basic Auth über plain HTTP, denn dann haben Sie das Passwort nur in einem interessanteren Alphabet ausgesprochen.
JWTs: Die drei Teile lesen
Ein JSON Web Token in seiner kompakten Form ist drei durch Punkte getrennte Teile aus Base64Url: der Header, das Payload und die Signatur. Die ersten beiden sind normales JSON, das Sie mit Ihren Augen lesen können (oder mit einem Dekodier-Aufruf), während das dritte eine kryptografische Signatur ist, die mit dem richtigen Schlüssel geprüft, nicht dekodiert werden muss. Ein Beispiel-Token aus einer bekannten Demo sieht so aus: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.W-5gI_FdnMBdpgG4twX96rptvh13gmXQ75kKLRXVaGs. Das Payload davon in Visual Basic zu lesen heißt: an den Punkten aufteilen, das URL-sichere Alphabet zurück in das Standard-Alphabet wandeln und dekodieren:
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
' Das URL-sichere Alphabet zurück in das Standard-Alphabet wandeln
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
Führen Sie das gegen das Beispiel-Token aus, und Sie bekommen das JSON {"sub":"1234567890","name":"John Doe"}. Lesen Sie den Header auf dieselbe Weise, und Sie bekommen {"alg":"HS256","typ":"JWT"}. Die Warnung, die hier zählt: Ein JWT zu lesen ist nicht, es zu verifizieren. Jeder kann ein Token basteln, deshalb validieren Sie die Signatur mit dem Schlüssel des Ausstellers, bevor Sie einem Claim darin vertrauen. Für diese Aufgabe übernimmt Ihnen das System.IdentityModel.Tokens.Jwt-NuGet-Paket (die IdentityModel-Suite vom Microsoft-Entra-Team) die Base64Url-Details, den Signatur-Check und das Parsen der Claims, und genau dort wollen Sie es nicht selbst bauen.
E-Mail-Anhänge, umgebrochen bei 76 Zeichen
Die E-Mail ist der Ort, an dem Base64 seine Reputation verdient hat. SMTP wurde für 7-Bit-ASCII entworfen, deshalb muss ein binärer Anhang zu Text werden, bevor er fliegen kann, und der MIME-Standard (RFC 2045) wählte Base64 mit einer Zeilen-Länge-Grenze von 76 Zeichen, einem engen Verwandten der noch älteren 64-Zeichen-Zeilen von PEM. Wenn Sie je eine rohe E-Mail erhalten haben, haben Sie das Ergebnis gesehen: ein Block aus dichtem Base64, aufgeräumt in kurze Zeilen gebrochen, unter einem Content-Transfer-Encoding: base64-Header. Der schöne Teil für einen Dekodierer ist, dass Sie nichts aufwickeln müssen. Der .NET-Dekodierer überspringt Zeilenumbrüche und Leerzeichen, wo immer sie auftauchen, deshalb dekodiert der umgebrochene Block so, wie er ist:
Imports System
Imports System.Text
Module MimeOpener
Sub Main()
' Ein 59-Byte-Satz, MIME-umgebrochen bei 76 Zeichen mit 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
Wenn Sie mit den System.Net.Mail-Klassen arbeiten, ist das Dekodieren noch unsichtbarer: Ein Attachment, das Sie einem MailMessage hinzufügen, trägt eine ContentEncoding von TransferEncoding.Base64, und die Mail-Bibliothek umbricht, sendet und entpackt die ganze Zeremonie für Sie. Den manuellen Dekodier-Schritt brauchen Sie nur, wenn Sie rohes MIME aus einem Stream, einer Test-Fixture oder einer Legacy-Mailbox-Datei lesen.
Datenbanken, Konfiguration und Umgebungsvariablen
Nur-Text-Speicher fragt ständig nach Base64: eine Datenbank-Spalte, typisiert als Text, ein XML-Konfigurationswert, eine Umgebungsvariable. Alle wollen normale Zeichen, deshalb werden Binärdaten vor der Speicherung kodiert und beim Zurückkommen dekodiert. Die Dekodier-Seite ist immer derselbe Einzeiler, und der interessante Teil ist die Größen-Mathematik. Eine gewöhnliche NVARCHAR-Spalte in SQL Server endet bei 8.000 Zeichen, das heißt etwa 6.000 Bytes Binär, bevor die 33-Prozent-Steuer Sie über die Grenze drückt; darüber hinaus greifen Sie zu den MAX-Varianten oder, ehrlicher gesagt, zu einer echten Binärspalte. Auf Windows ist eine einzelne benutzerdefinierte Umgebungsvariable auf 32.767 Zeichen gedeckelt (und auf XP-Ära-Systemen war der gesamte Umgebungsblock ebenfalls auf diese Größe gedeckelt), deshalb hat "den ganzen Lizenz-Blob in eine Umgebungsvariable legen" eine harte Obergrenze. Hier ist ein Dekodier-Muster, das sich lohnt, es in einer Ecke des Kopfes zu behalten: einen gespeicherten Fingerabdruck gegen eine Datei prüfen, mit einem konstanten-Zeit-Vergleich, damit ein Nicht-Treffen keine Zeit-Informationen preisgibt:
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
Dasselbe Muster funktioniert für jeden gespeicherten Hash: den gespeicherten Wert dekodieren, den frischen Hash berechnen und in fester Zeit vergleichen. Konfigurationsdateien folgen dem identischen Muster, egal ob der Wert aus einem XML-app.config-Eintrag, einer JSON-Einstellungsdatei oder einem Registry-String kam.
Big Data: Einen Stream dekodieren, ohne ihn zu laden
Jedes Beispiel bisher hat das ganze Payload in den Speicher gelesen, was für Anhänge und Konfigurationswerte in Ordnung ist, aber falsch für eine zwei-Gigabyte-Datei, die jemand in eine Textdatei kodiert hat. Für diese Größenordnung hat .NET ein Streaming-Paar, das seit .NET Framework 1.1 (2003) existiert: die FromBase64Transform-Krypto-Transformation, eingewickelt in einen CryptoStream. Sie lesen Chunks kodierten Textes, die Transformation dekodiert sie auf dem Flug, und Sie schreiben die Bytes raus, so bleibt der Speicher flach, egal wie groß die Datei ist:
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
Da die kodierte Datei normaler ASCII-Text ist, ist das Lesen als Byte-Stream vollkommen sicher, und die Transformation kommt mit dem Zeilen-Umbruch zurecht, ohne dass Sie etwas tun. Die Ausgabedatei kommt mit ungefähr drei Viertel der Eingabe-Größe heraus, was dieselbe 33-Prozent-Steuer ist, die auf dem Hinweg bezahlt und auf dem Rückweg eingesammelt wird.
Fallen, die Visual Basic besonders beißen
Die meisten Fallen in diesem Abschnitt sind mit anderen .NET-Sprachen geteilt, aber ein paar tragen eine deutlich VB-typische Mütze, deshalb sind sie hier zusammen:
- Byte gegenüber Byte(). In Visual Basic ist ein einzelnes Byte
Byteund ein Array von BytesByte(), wobei die leeren Klammern die ganze Arbeit machen.Dim b As Bytezu schreiben, wennByte()gemeint war, ist der klassische Fehler des ersten Tages, und genau so etwas fängtOption Strict Onzur Kompilierzeit ab. Wenn Ihr Projekt es noch nicht an hat, schalten Sie es ein: Diedotnet new console -lang VB-Vorlage überlässt die Entscheidung Ihnen, während die Visual-Studio-Projektvorlagen es setzen. - Die Span-Mauer. Die modernen spanbasierten APIs sind aus VB aufrufbar, aber nur an der Aufrufstelle: Sie können ein
Byte()- oderChar()-Array direkt an eine Methode übergeben, die einen Span entgegennimmt, und der Compiler wandelt es für Sie um. Was Sie nicht können, ist, in Ihrem eigenen Code einen Span zu benennen. Deklarieren Sie eine Variable, ein Feld oder einen Parameter vom TypSpanoderReadOnlySpan, und der Compiler antwortet mit "Types with embedded references are not supported in this version of your compiler". Das VB-Idiom lautet also: Rufen Sie die Span-APIs mit normalen Arrays auf, und versuchen Sie niemals, einen Span in einer Variable zu speichern. - BitConverter ist nicht Base64.
BitConverter.ToString(bytes)rendert Bytes als Hex, getrennt durch Gedankenstriche, was es zu einer verlockenden falschen Antwort für jeden macht, der "Bytes in String umwandeln" gehört hat. Es gibt Ihnen gerne4D-61-6E, wenn die APITWFuerwartet. Wenn Sie unsicher sind, greifen Sie zuSystem.Convert. - MidB ist ein Geist. Klassisches Visual Basic hatte byte-Level-String-Funktionen,
MidB,LeftBundRightB, gerichtet auf Doppelbyte-Zeichensätze. Jeder .NET-String ist jetzt Unicode, und die Laufzeit-Dokumentation ist direkt: Sie werden nicht mehr unterstützt. Wenn ein Legacy-Snippet sie verwendet, schreiben Sie es mit Byte-Arrays und den APIs aus diesem Artikel neu. - Encoding.Default folgt der Maschine. Die Geschichte der Gebietsschema-Ausweichung ist die von .NET Framework: Auf modernem .NET ist
Defaultimmer UTF-8, deshalb dekodieren dieselben Bytes überall auf dieselbe Weise. Für Daten, die Sie teilen, benennen Sie die Kodierung ausdrücklich, normalerweiseEncoding.UTF8- der Rat gilt in jedem Fall. - Rundreisen sind keine Identität. Wenn Sie einen String dekodieren und dann das Ergebnis kodieren, ist der neue String nicht garantiert gleich dem Original: Weißraum verschwindet, und Padding wird normalisiert. Ein Payload mit Zeilenumbrüchen kommt als eine saubere Zeile zurück. Für Daten in Ordnung, gefährlich, wenn Ihre Logik den kodierten Text statt der dekodierten Bytes vergleicht.
- Nur-Weißraum-Eingabe ist ein stiller Erfolg. Ein String aus nur Leerzeichen und Zeilenumbrüchen dekodiert zu einem leeren Byte-Array ohne jeden Fehler, was bedeutet, dass "der Benutzer hat nichts außer Zeilenumbrüchen eingefügt" genauso aussieht wie "der Benutzer hat ein leeres Payload eingefügt". Wenn der Unterschied wichtig ist, prüfen Sie die Eingabe-Länge, bevor Sie dekodieren.
Best Practices fürs Dekodieren
Destilliert aus allem Obigen, die Gewohnheiten, die Dekodier-Code langweilig halten (im besten Sinne):
- Behandeln Sie Base64 als Transport, nicht als Schutz. Es ist eine Kodierung, keine Verschlüsselung: Jeder kann das Original mit einem Funktionsaufruf lesen, und RFC 4648 merkt sogar an, dass nachlässiger Alphabet-Umgang verdeckte Kanäle öffnen kann. Verschlüsseln Sie zuerst, und kodieren Sie dann, wenn Sie Inhalt verstecken müssen.
- Für unzuverlässige Eingabe bevorzugen Sie die
Try-Methoden oder einenIsValid-Vorabcheck dem Zulassen, dassFormatExceptionfliegt. Ein Boolesch-Wert lässt sich leichter in eine freundliche Fehlermeldung verwandeln, als eine Ausnahme zu schlucken ist. - Wählen Sie den Zeichensatz absichtlich, mit UTF-8 als Standard, es sei denn, Sie haben einen dokumentierten Grund für ein anderes Schema.
- Passen Sie das Alphabet an die Quelle an: Standard-Base64 für MIME, E-Mail und Konfiguration; Base64Url für JWTs und alles innerhalb einer URL.
- Streamen Sie alles Große durch
FromBase64TransformundCryptoStream, statt es in einen String zu laden. - Vergleichen Sie Fingerabdrücke und Hashes mit
CryptographicOperations.FixedTimeEquals, nicht mit=, damit die Zeit nicht preisgibt, wie viel vom Wert übereingestimmt hat. - Behalten Sie
Option Strict On, damit dieByte/Byte()-Familie von Versehen ein Kompilierfehler ist statt eines Produktions-Rätsels.
Wie Visual Basic seinen Dekodierer bekam
Die Geschichte beginnt in einer Ära, in der Visual Basic gar kein Base64 hatte. In der Welt von Visual Basic 6 und VBA (die Makro-Sprache, die heute noch in Excel und Office läuft) entliehen Entwickler, die Base64 brauchten, es von den COM-Komponenten, die schon auf der Maschine waren. Der berühmte Trick benutzte ein XML-DOM-Element: Der MSXML-Parser lässt einen Knoten seinen DataType als bin.base64 deklarieren, so dass man, wenn man einen Base64-String in die text-Eigenschaft des Knotens schreibt und seine nodeTypedValue zurückliest, die rohen Bytes in die Hand bekommt, während das DOM die eigentliche Base64-Mathematik erledigt (das ADO-Stream-Objekt besitzt eine eigene Charset-Eigenschaft, die nur echte Zeichensatz-Namen wie "utf-8" oder "iso-8859-1" versteht, nicht "base64", deshalb greift der Trick stattdessen nach MSXML). Die Kodierung lief dieselbe Idee in umgekehrter Richtung ab: Bytes in nodeTypedValue schreiben und den kodierten String aus text zurücklesen:
' Der klassische VB6 / VBA-Dekodier-Trick, für den Kontext
Dim node As Object
Set node = CreateObject("MSXML2.DOMDocument").createElement("b64")
node.DataType = "bin.base64"
node.text = packed ' der Base64-String
Dim bytes() As Byte
bytes = node.nodeTypedValue
Es funktionierte, es war clever, und es ist der Grund, warum "base64 VBA" drei Jahrzehnte später Suchmaschinen noch aufleuchten lässt. Dann änderte 2002 alles: Visual Basic 7.0 (die erste .NET-Version der Sprache, damals Visual Basic .NET genannt) trat der neuen Common Language Runtime bei, und das .NET Framework brachte System.Convert mit FromBase64String und seinen Freunden von Haus aus mit. Ab .NET Framework 1.1 im Jahr 2003 hatte jedes VB-Programm einen erstklassigen Dekodierer ohne zu registrierende Komponenten. Die moderne Welle kam 2018 mit .NET Core 2.1, das die ausnahmsfreien Try-Methoden und die schnelle spanbasierte System.Buffers.Text.Base64-Klasse hinzugefügt hat, und 2024 mit .NET 9, das das URL-sichere Alphabet endgültig als Base64Url standardisierte. Stand 2026 ist .NET 10 - im November 2025 veröffentlicht - der Langzeit-Support-Release, und die Preview-Bibliotheken von .NET 11 fügen eine neue Generation von Base64-Komfortmethoden hinzu, deshalb wird der Dekodierer immer besser, während der originale Einzeiler von 2003 unverändert weiterläuft.
Fun Facts aus der VB-Welt
- Der offizielle Visual-Basic-Compiler ist selbst in Visual Basic geschrieben. Als Teil des Open-Source-Projekts Roslyn kompiliert die Sprache sich selbst.
- Das allererste Visual Basic kam 1991 auf den Markt, bevor die Web-Ära loskam. Der große Moment von Base64 kam mit MIME 1993, und VB selbst wuchs zwei Jahre später eine 32-Bit-Fähigkeit hinzu, als Visual Basic 4 im Jahr 1995 zum ersten Mal 32-Bit-Programme möglich machte. VB 5 im Jahr 1997 ging den ganzen Weg: nur 32 Bit, kein 16 Bit mehr im Karton.
- Die byte-Level-Funktionen
MidB,LeftBundRightBaus dem klassischen VB sind in .NET offiziell "nicht mehr unterstützt", weil jeder VB-String seit Tag eins des Frameworks Unicode ist. Eine ganze Familie von APIs, in den Ruhestand versetzt durch eine Kodierungs-Wahl. - Die Base64-Maschinerie der Laufzeit ist kein schmucker Tabellen-Lookup: Die moderne Implementierung führt hardwarevektorierte Code-Pfade (AVX-512, AVX2 und SSE-Varianten) aus, wenn die Maschine sie unterstützt, deshalb ist "langsamer Text-Codec" nicht das, was unter der Haube passiert.
- Der MSXML-
bin.base64-Trick aus der VB6-Ära läuft heute noch in produktiven Excel-Makros, was bedeutet, dass ein Workaround aus den späten 1990ern und einConvert-Aufruf aus 2003 fröhlich nebeneinander in derselben Codebase derselben Organisation koexistieren.
Bevor Sie gehen
Dieser Artikel hat die Dekodier-Seite von Base64 in Visual Basic abgedeckt, vom Einzeiler bis zum Streaming, von JWTs bis zu den Fallen, die eine VB-Mütze tragen. Die andere Seite der Münze, die eigenen Bytes und Texte überhaupt erst in Base64 zu verwandeln, hat ihren eigenen Satz von Entscheidungen über Padding, Zeilenumbrüche und die Größen-Steuer, und sie wird in allen Details im Begleit-Artikel zur Kodierung auf der Schwester-Site behandelt. Der Link dazu sitzt direkt unter dieser Zeile, und das Werkzeug auf der Startseite bleibt der schnellste Weg, ein kleines Payload von Hand zu prüfen.
Zuletzt aktualisiert: 2026-09-08
Verwandter Artikel: Base64-Kodierung in Visual Basic: Ein vollständiger Leitfaden