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 durchgemischtes Kartendeck aus Buchstaben und Ziffern, hin und wieder ein Pluszeichen, ein Schrägstrich oder ein Gleichheitszeichen dazwischen, und derjenige, der ihn geschickt hat, schwört, dass er einmal ein ganz gewöhnlicher Satz, ein JPEG oder ein Konfigurations-Blob war. Dieser String ist Base64, und diese Seite ist Ihr Praxisleitfaden, um ihn wieder in das zu verwandeln, was er war. Die gute Nachricht vorab: Visual Basic hat seit den allerersten .NET-Framework-Tagen einen erstklassigen Base64-Dekodierer, er liegt in der Runtime bei, und Sie müssen nicht ein einziges Paket installieren, um ihn zu nutzen.
Eine kurze Auffrischung, denn die Startseite dieser Site erklärt das Format in aller Tiefe: Base64 schreibt drei Bytes als vier Zeichen aus einem Alphabet mit 64 Symbolen, und ein oder zwei =-Zeichen am Ende markieren, wo die eigentlichen Daten aufhörten. Kodierte Texte sind dadurch im Vergleich zum Original ein bisschen aufgebläht: vier Zeichen für jede drei Eingabe-Bytes, rund ein Drittel mehr. Dekodieren bedeutet einfach, diesen Tausch in die umgekehrte Richtung zu laufen zu lassen. Mit der Form des Problems im Kopf öffnen wir ein paar Umschläge.
Die Dekodierer-Familie: Eine Runtime, vier Epochen
Alles, was Sie zum Dekodieren brauchen, lebt in der .NET-Runtime. In den letzten zwei Jahrzehnten ist sie in vier Wellen gewachsen, und die älteren Wellen funktionieren noch genauso wie immer, also werden Sie sie alle in freier Wildbahn treffen:
| API | Verfügbar seit | Wofür es gut ist |
|---|---|---|
System.Convert.FromBase64String |
.NET Framework 1.1 (2003) | Der Klassiker. Ein String hinein, ein frisches Byte()-Array hinaus. Wirft bei schlechter Eingabe. |
System.Convert.FromBase64CharArray |
.NET Framework 1.1 (2003) | Dasselbe Dekodieren, liest aber aus einem Ausschnitt eines Zeichenarrays, das Sie bereits besitzen. |
System.Convert.TryFromBase64String, TryFromBase64Chars |
.NET Core 2.1 (2018) | Boolesch statt Exceptionen, schreibt in einen Puffer, den Sie bereitstellen. Die freundliche Wache für nicht vertrauenswürdige Eingaben. |
System.Buffers.Text.Base64 |
.NET Core 2.1 (2018) | Niedrigstufiges, span-basiertes Dekodieren: Statuscodes statt Exceptionen, In-Place-Auspacken und IsValid-Vorabprüfungen. |
System.Buffers.Text.Base64Url |
.NET 9 (2024) | Das URL-sichere Alphabet (- und _ statt + und /), mit optionalem Padding. Auf älteren Runtimes reitet es auf dem Microsoft.Bcl.Memory-NuGet-Paket mit. |
FromBase64Transform + CryptoStream |
.NET Framework 1.1 (2003) | Streaming-Dekodieren: Datei zu Datei, Netzwerk zu Festplatte, Chunk für Chunk, ohne den ganzen Payload im Speicher zu halten. |
Eine Visual-Basic-Klärung, bevor wir weitergehen. In einem VB-Projekt löst sich der nackte Name Convert zu System.Convert auf, weil die Standard-Projektvorlagen den System-Namespace für Sie importieren und nichts in der Visual-Basic-Runtime diesen Namen überschattet. Dieser Artikel schreibt trotzdem meistens die volle System.Convert-Form: Sie kostet nichts und macht die Absicht für jeden, der den Code liest, unübersehbar klar.
Zu den Versionen: .NET 10 ist das aktuelle Long-Term-Support-Release (November 2025, unterstützt bis November 2028), und .NET 8 sowie .NET 9 bleiben beide bis November 2026 unterstützt, während .NET 11 in der Vorschau ist und einen Stapel neuer Base64-Bequemlichkeitsmethoden hinzufügt. Die Dekodier-APIs sind über all diese hinweg stabil. Das einzige Versions-Tor ist Base64Url: Es ist ab .NET 9 an Bord, und auf .NET Framework 4.6.2 oder neuer holen Sie es sich mit dem Microsoft.Bcl.Memory-Paket. Nichts anderes in diesem Artikel braucht ein Paket.
Wenn Sie bei null anfangen, enthält das .NET-SDK Visual Basic von Haus aus, und so sieht die gesamte Zeremonie aus:
dotnet new console -lang VB -o EnvelopeOpener
cd EnvelopeOpener
dotnet run
Das gibt Ihnen ein kleines Program.vb mit Imports System oben, und Sie sind bereit zu dekodieren.
Der Einzeiler: FromBase64String
Neunzig Prozent des Dekodier-Alltags in Visual Basic sind ein einzelner 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 ins Gedächtnis einzubrennen. Erstens ist das Ergebnis Bytes, nicht Text: Der Dekodierer ist von Anfang bis Ende byte-orientiert, und genau das wollen Sie, denn der Payload könnte ein Satz sein, ein JPEG, ein Zertifikat oder ein Hash, und keines davon sollte eine Sonderbehandlung bekommen. Aus diesen Bytes einen lesbaren String zu machen ist ein separater, bewusster Schritt über ein Encoding-Objekt, und genau in diesem Schritt lebt Ihre Zeichensatz-Entscheidung (mehr dazu unten). Zweitens alloziert FromBase64String ein frisches Array, exakt bemessen auf die dekodierte Länge, so dass Sie nie überflüssige Kapazität mit sich herumschleppen. Drittens dekodiert "TWFu" zu dem 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 hat der .NET-Dekodierer eine Persönlichkeit, und eine charakterstarke dazu: Bei genau einer Sache ist er großzügig und bei allem anderen unbarmherzig. Die großzügige Sache ist der Weißraum. Der Dekodierer überspringt exakt vier Zeichen, wo immer sie auftauchen: das Leerzeichen (U+0020), der Tab (U+0009), der Zeilenumbruch (U+000A) und der Wagenrücksetzer (U+000D). Diese Politik ist eine bewusste Verbeugung vor der E-Mail, wo Base64-Payloads in kurzen Zeilen verpackt ankommen, und es bedeutet, dass ein MIME-umwickelter Anhang mit null Vorverarbeitung dekodiert wird. Ein hübscher Fakt: Diese Nachsicht teilt die ganze eingebaute Familie, einschließlich der span-basierten System.Buffers.Text.Base64-Klasse und der URL-sicheren Base64Url-Klasse, so dass Sie dasselbe nachsichtige Verhalten bekommen, egal, welche API Sie wählen. Alles außerhalb des Alphabets mit 64 Symbolen, jede gebrochene Längenregel oder Padding am falschen Ort erntet eine Exception. 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" + non-breaking space |
FormatException. Nur die vier Weißraum-Zeichen oben werden übersprungen; NBSP ist keins davon. |
"TWE" |
FormatException. Weißraum beiseite, muss die Länge ein Vielfaches von 4 sein. |
"TWFu=" |
FormatException. Padding nach dem Ende der Daten ist nicht erlaubt. |
"====" |
FormatException. Mehr als zwei Padding-Zeichen sind 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 merkbar: Eine Nothing-Referenz wirft ArgumentNullException, eine leere oder nur-Weißraum-Eingabe dekodiert zu einem leeren Array, gültige Eingabe dekodiert zu Bytes, und alles weitere Ungültige wirft eine sehr spezifische Exception, die FormatException.
Von Bytes zu Text: Den Zeichensatz wählen
In dem Moment, in dem Sie entscheiden, dass die dekodierten Bytes eigentlich Text sind, müssen Sie einen Zeichensatz benennen, denn Bytes sind erst dann Text, wenn Sie sagen, wie man sie zu lesen hat. 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, also müssen Sie ihre Wahl treffen. Das praktische Menü:
Encoding.UTF8: Die sichere Vorgabe für alles, was über das Web oder durch eine API gereist ist. Im Zweifel hier anfangen.Encoding.Unicode: UTF-16 Little-Endian, der native Geschmack von .NET. Vernünftig, 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, also ist dies 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) aber immer UTF-8, egal welche Locale. Meiden Sie es auch hier für austauschbare Daten - benennen Sie die Kodierung ausdrücklich, meistEncoding.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 Folge Unsinn - ein paar seltsame Zeichen aus dem CJK-Bereich plus ein Ersatzzeichen - weil der Dekodierer die Bytes zu zweit zusammenfasst. Lesen Sie die UTF-8-Bytes von "Café" mit Encoding.ASCII, und der Akzent wird zu ??, einem Paar Fragezeichen, weil der Akzent in UTF-8 zwei Bytes ist. Keine dieser Wahlen wirft eine Exception; sie produzieren nur still und leise den falschen Text, und deshalb ist der Zeichensatz eine Entscheidung, die Sie bewusst treffen, nicht eine Vorgabe, die Sie erben.
Das URL-sichere Alphabet: Base64Url
Standard-Base64 benutzt + und /, und beide Zeichen tragen ihre eigenen Bedeutungen innerhalb von URLs, also kann ein Standard-Alphabet einen Link zerbrechen, in dem Moment, in dem er in einen Query-String landet. Die Lösung, standardisiert in RFC 4648 Abschnitt 5, ist die Variante, die für URLs und Dateinamen sicher ist: dasselbe 64-Zeichen-Schema, in dem - den Platz von + einnimmt und _ den Platz von /, und das nachträgliche Padding wird typischerweise weggelassen, weil es durch die Länge mitgedacht ist. Dieses Alphabet treffen Sie in JWTs, API-Tokens und überall dort, wo Base64 innerhalb einer URL reist. .NET 9 fügte dafür eine eigene Klasse hinzu, System.Buffers.Text.Base64Url, und sie ist eine Freude zu benutzen:
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-Entscheidung Ausgabe ohne Padding, aber sein Dekodierer akzeptiert sowohl gepaddete als auch ungepaddete Eingabe, also ist er freundlich zu Daten aus anderen Ökosystemen. Und Base64Url.IsValid lässt Sie einen Kandidaten-String vor dem Dekodieren prüfen, was praktisch ist, wenn die Daten aus der Außenwelt kommen. Wenn Sie auf einer älteren Runtime ohne die Klasse stecken, ist die Umwandlung der Tausch von zwei Zeichen plus eine Padding-Nachbesserung, exakt 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 benutzen. Entweder wie auch immer, die Regel ist 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 Uses von Base64 ist das Schmuggeln von Binärdaten durch Textdateien: eine .b64- oder .txt-Datei, die kodierte Bytes enthält. In Visual Basic sind Hin- und Rückweg zwei Dateiaufrufe und ein 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 der Payload als eine lange Zeile geschrieben wurde, auf 76 Zeichen umwickelt oder auf 64, denn der Dekodierer überspringt die Zeilenumbrüche in beiden Fällen. Halten Sie eine Größen-Fakt in der Hinterhand: Die Textdatei ist rund ein Drittel größer als das Binär, das sie versteckt, also kommt eine 10-Megabyte-Datei als etwa 13,3 Megabyte 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 Marker ;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 in das Markup einbettet, statt auf eine separate Datei zu zeigen. In Visual Basic ist das Entpacken eines solchen Strings nur ein String-Split 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-Marker enthält stattdessen URL-escapete Daten, und deren Dekodieren als Base64 würde entweder scheitern oder Müll produzieren. Der RFC selbst warnt, dass Data-URIs nur für kurze Werte nützlich sind, und HTML hat seine eigenen Längen-Limits für Attribute, also behandeln Sie dies als das richtige Werkzeug für Icons, Avatare und Thumbnails, nicht dafür, Ihre ganze Fotobibliothek in einem Attribut zu verschiffen.
HTTP, APIs und Basic-Auth
Base64 ist in Web-APIs überall, und die zwei häufigsten Auftritte sind der HTTP-Basic-Auth-Header und JSON-Felder, die Binärdaten oder vor-kodierte Daten tragen. Basic-Auth ist der einfachste Fall: Der Client schickt Authorization: Basic gefolgt vom Base64 von username:password. Das Dekodieren 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 Alltagsfall ist eine JSON-Antwort, in der ein Feld ein vor-kodierter Blob ist, etwa ein Bild oder ein Zertifikat. Mit HttpClient und System.Text.Json (System.Text.Json liegt seit .NET Core 3.0 im Karton, und HttpClient schon viel früher) ist das Muster direkt:
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 Hausordnungs-Notizen. Geben Sie nie dekodierte Zugangsdaten in ein Log oder eine UI aus, nur weil Sie können, und verlassen Sie sich nie auf Basic-Auth über nacktes HTTP, denn dann haben Sie das Passwort lediglich in einem interessanteren Alphabet geschrieben.
JWTs: Die drei Teile lesen
Ein JSON Web Token in der kompakten Form ist drei punktgetrennte Stücke Base64Url: der Header, der Payload und die Signatur. Die ersten zwei sind klares 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 Beispieltoken aus einer gängigen Demo sieht so aus: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.W-5gI_FdnMBdpgG4twX96rptvh13gmXQ75kKLRXVaGs. Sein Payload in Visual Basic zu lesen heißt, an den Punkten aufteilen, das URL-sichere Alphabet zurück ins Standard-Alphabet verwandeln 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
' Wandle das URL-sichere Alphabet zurück ins Standard-Alphabet
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 Beispieltoken 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 heißt nicht, es zu verifizieren. Jeder kann ein Token bauen, also validieren Sie die Signatur mit dem Schlüssel des Ausstellers, bevor Sie einem Anspruch darin vertrauen. Für diese Aufgabe übernimmt das System.IdentityModel.Tokens.Jwt-NuGet-Paket (die IdentityModel-Suite vom Microsoft-Entra-Team) die Base64Url-Details, die Signaturprüfung und das Claim-Parsing für Sie, und genau das ist die Ebene, auf der Sie nicht selbst basteln wollen.
E-Mail-Anhänge, umgewickelt auf 76 Zeichen
E-Mail ist der Ort, an dem Base64 seinen Ruf verdient hat. SMTP wurde für 7-Bit-ASCII entworfen, also muss ein binärer Anhang zu Text werden, bevor er fliegen kann, und der MIME-Standard (RFC 2045) wählte Base64 mit einer Zeilenbeschränkung von 76 Zeichen, ein enger Verwandter der noch älteren 64-Zeichen-Zeilen von PEM. Wenn Sie je eine rohe E-Mail erhalten haben, haben Sie das Ergebnis gesehen: einen Block dichten Base64, zerschnitten in saubere kurze Zeilen, unter einem Content-Transfer-Encoding: base64-Header. Das Schöne für einen Dekodierer: Sie müssen nichts entpacken. Der .NET-Dekodierer überspringt Zeilenumbrüche und Leerzeichen, wo immer sie auftauchen, also dekodiert der umwickelte Block so, wie er ist:
Imports System
Imports System.Text
Module MimeOpener
Sub Main()
' Ein 59-Byte-Satz, MIME-umwickelt auf 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 einer MailMessage hinzufügen, trägt ein ContentEncoding von TransferEncoding.Base64, und die Mail-Bibliothek wickelt ein, sendet und wickelt das ganze Ritual für Sie aus. Sie brauchen das manuelle Dekodieren nur, wenn Sie rohes MIME von einem Stream, einer Testfixture oder einer Legacy-Mailbox-Datei lesen.
Datenbanken, Konfiguration und Umgebungsvariablen
Nur-Text-Speicher fragt ständig nach Base64: eine Datenbank-Spalte, die als Text typisiert ist, ein XML-Konfigurationswert, eine Umgebungsvariable. Alle wollen normale Zeichen, also wird Binäres vor dem Speichern kodiert und beim Wiederkommen dekodiert. Die Dekodier-Seite ist immer derselbe Einzeiler, und der interessante Teil ist die Größen-Mathematik. Eine normale NVARCHAR-Spalte in SQL Server geht bis 8.000 Zeichen, das heißt etwa 6.000 Bytes Binäres, bevor die 33-Prozent-Steuer Sie drüber drückt; darüber greifen Sie zu den MAX-Varianten oder, ehrlicher gesagt, zu einer echten binären Spalte. 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), also hat "den ganzen Lizenz-Blob in einer Env-Var speichern" eine harte Decke. Hier ist ein Dekodier-Muster, das es wert ist, in einer Ecke Ihres Kopfes zu leben: einen gespeicherten Fingerabdruck mit einer Datei abgleichen, mit einem konstanten-Zeit-Vergleich, damit eine Abweichung keine Timing-Informationen durchsickern lässt:
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 fixer Zeit vergleichen. Konfigurationsdateien folgen dem identischen Muster, egal ob der Wert aus einem XML-app.config-Eintrag kam, einer JSON-Einstellungsdatei oder einem Registry-String.
Großes Datenvolumen: Einen Stream dekodieren, ohne ihn zu laden
Jedes Beispiel bisher hat den ganzen Payload in den Speicher gelesen, was für Anhänge und Config-Werte 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: der FromBase64Transform-Crypto-Transform, eingewickelt in einen CryptoStream. Sie lesen Chunks kodierten Textes, der Transform dekodiert sie fliegend, und Sie schreiben die Bytes heraus, so dass der Speicher flach bleibt, 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
Weil die kodierte Datei normaler ASCII-Text ist, ist das Lesen als Byte-Stream vollkommen sicher, und der Transform kommt mit dem Zeilen-Umwickeln zurecht, ohne dass Sie etwas tun. Die Ausgabedatei kommt ungefähr drei Viertel so groß wie die Eingabe heraus, was dieselbe 33-Prozent-Steuer ist, die auf dem Hinweg bezahlt und auf dem Rückweg eingetrieben wird.
Fallen, die Visual Basic im Speziellen beißen
Die meisten Fallen in diesem Abschnitt teilen sich mit anderen .NET-Sprachen, aber ein paar tragen eine deutlich erkennbare VB-Mütze, also sind sie hier zusammen:
- Byte versus Byte(). In Visual Basic ist ein einzelnes Byte
Byteund ein Byte-ArrayByte(), und die leeren Klammern machen die ganze Arbeit.Dim b As Bytezu schreiben, wenn SieByte()meinen, ist der klassische Fehler des ersten Tages, und genau das ist die Sorte Sache, dieOption Strict Onzur Compile-Zeit fängt. Falls Ihr Projekt es noch nicht einschaltet hat, schalten Sie es ein: Diedotnet new console -lang VB-Vorlage lässt die Entscheidung Ihnen, während die Visual-Studio-Projektvorlagen es setzen. - Die Span-Mauer. Die modernen span-basierten APIs sind aus VB aufrufbar, aber nur an der Aufrufstelle: Sie können ein
Byte()- oderChar()-Array direkt in eine Methode legen, die einen Span annimmt, und der Compiler wandelt es für Sie um. Was Sie nicht können, ist einen Span in Ihrem eigenen Code 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 nie, einen Span in einer Variable zu speichern. - BitConverter ist nicht Base64.
BitConverter.ToString(bytes)rendert Bytes als Hex, getrennt durch Gedankenstriche, was es für jeden, der von "Bytes in String umwandeln" gehört hat, zu einer verlockenden falschen Antwort macht. Es gibt Ihnen fröhlich4D-61-6E, wo die APITWFuerwartet. Im Zweifel greifen Sie zuSystem.Convert. - MidB ist ein Gespenst. Klassisches Visual Basic hatte byte-basierte String-Funktionen,
MidB,LeftBundRightB, gerichtet auf Doppel-Byte-Zeichensätze. Jeder .NET-String ist jetzt Unicode, und die Runtime-Dokumentation ist unmissverständlich: Sie werden nicht mehr unterstützt. Wenn ein Legacy-Snippet sie benutzt, schreiben Sie es mit Byte-Arrays und den APIs aus diesem Artikel um. - Encoding.Default folgt der Maschine. Die Story von der Locale-Divergenz ist eine .NET-Framework-Sache: Auf modernem .NET ist
Defaultimmer UTF-8, also dekodieren dieselben Bytes überall auf dieselbe Weise. Für geteilte Daten benennen Sie die Kodierung ausdrücklich, meistEncoding.UTF8- der Rat gilt in beiden Fällen. - Rundgänge sind keine Identität. Wenn Sie einen String dekodieren und dann das Ergebnis kodieren, ist der neue String nicht garantiert identisch mit dem Original: Weißraum verschwindet, und Padding wird normalisiert. Ein Payload mit Zeilenumbrüchen kommt als eine saubere Zeile zurück. In Ordnung für Daten, 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 heißt, dass "der Benutzer hat nur Zeilenumbrüche eingefügt" aussieht wie "der Benutzer hat einen leeren Payload eingefügt". Wenn der Unterschied zählt, prüfen Sie die Eingabe-Länge, bevor Sie dekodieren.
Best Practices für das 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.
- Bei nicht vertrauenswürdiger Eingabe bevorzugen Sie die
Try-Methoden oder eineIsValid-Vorabprüfung, stattFormatExceptionfliegen zu lassen. Ein Boolescher Wert lässt sich leichter in eine freundliche Fehlermeldung verwandeln, als eine Exception zu schlucken. - Wählen Sie den Zeichensatz bewusst und machen Sie UTF-8 zur Vorgabe, 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 Config; Base64Url für JWTs und alles innerhalb einer URL.
- Streamen Sie alles Große durch
FromBase64TransformundCryptoStreamstatt es in einen String zu laden. - Vergleichen Sie Fingerabdrücke und Hashes mit
CryptographicOperations.FixedTimeEquals, nicht mit=, damit das Timing nicht durchsickert, wie viel vom Wert übereingestimmt hat. - Halten Sie
Option Strict On, damit dieByte/Byte()-Familie von Verfehlungen ein Compile-Fehler und kein Produktions-Rätsel ist.
Wie Visual Basic zu seinem Dekodierer kam
Die Story 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 bis heute in Excel und Office läuft) entlehnten Entwickler, die Base64 brauchten, es den COM-Komponenten, die bereits 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, also übergibt Ihnen das Zuweisen eines Base64-Strings an die text-Eigenschaft des Knotens und das Zurücklesen seiner nodeTypedValue die rohen Bytes, während das DOM die eigentliche Base64-Mathematik macht (die eigene Charset-Eigenschaft des ADO-Stream-Objekts versteht nur echte Zeichensatz-Namen wie "utf-8" oder "iso-8859-1", aber kein "base64", und deshalb greift der Trick zu MSXML). Das Kodieren lief mit derselben Idee in die umgekehrte Richtung, indem es Bytes in nodeTypedValue schrieb und den kodierten String aus text zurücklas:
' Der klassische VB6 / VBA-Dekodier-Trick, als 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 noch Suchmaschinen zum Leuchten bringt. Dann änderte 2002 alles: Visual Basic 7.0 (die erste .NET-Version der Sprache, damals noch Visual Basic .NET genannt) trat der neuen Common Language Runtime bei, und das .NET Framework brachte System.Convert mit FromBase64String und seinen Freunden aus der Dose. 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 Try-Methoden ohne Exceptions und die schnelle span-basierte System.Buffers.Text.Base64-Klasse hinzufügte, und 2024 mit .NET 9, das endlich das URL-sichere Alphabet als Base64Url standardisierte. Stand 2026 ist .NET 10 - im November 2025 veröffentlicht - das Long-Term-Support-Release, und die .NET-11-Bibliotheken in der Vorschau fügen eine neue Generation von Base64-Bequemlichkeitsmethoden hinzu, also wird der Dekodierer immer besser, während der originale Einzeiler von 2003 unverändert weiterläuft.
Schöne Fakten aus der VB-Welt
- Der offizielle Visual-Basic-Compiler ist selbst in Visual Basic geschrieben. Als Teil des Open-Source-Roslyn-Projekts kompiliert die Sprache sich selbst.
- Das allererste Visual Basic kam 1991 heraus, bevor die Web-Ära richtig rollte. Der große Moment von Base64 kam 1993 mit MIME, und VB selbst wuchs zwei Jahre später eine 32-Bit-Fähigkeit an, als Visual Basic 4 im Jahr 1995 erstmals 32-Bit-Programme ermöglichte. VB 5 im Jahr 1997 ging den ganzen Weg: Nur 32 Bit, kein 16 Bit mehr im Karton.
- Die byte-basierten Funktionen
MidB,LeftBundRightBaus klassischem VB sind in .NET offiziell "no longer supported", weil jeder VB-String seit dem ersten Tag des Frameworks Unicode ist. Eine ganze API-Familie, in den Ruhestand geschickt durch eine Kodierungs-Entscheidung. - Die Base64-Maschinerie der Runtime ist kein munterer Tabellen-Lookup: Die moderne Implementierung läuft hardware-vektorisierte Code-Pfade (AVX-512, AVX2 und SSE-Varianten), wenn die Maschine sie unterstützt, also ist "langsamer Text-Codec" nicht das, was unter der Haube passiert.
- Der MSXML-
bin.base64-Trick aus der VB6-Ära läuft bis heute in produktiven Excel-Makros, was heißt, dass ein Workaround aus den späten 1990ern und einConvert-Aufruf aus dem Jahr 2003 sich fröhlich im Codebase derselben Organisation die Wohnung teilen.
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 Hälfte der Münze, Ihre Bytes und Ihren Text überhaupt erst in Base64 zu verwandeln, hat ihren eigenen Satz Entscheidungen über Padding, Zeilenumbrüche und die Größen-Steuer, und sie wird im ausführlichen Begleit-Artikel zur Kodierung auf der Schwestern-Site in voller Tiefe behandelt. Der Link dazu sitzt direkt unter dieser Zeile, und das Werkzeug auf der Startseite bleibt der schnellste Weg, um einen kleinen Payload manuell zu prüfen.
Zuletzt aktualisiert: 2026-09-08
Verwandter Artikel: Base64-Kodierung in Visual Basic: Ein vollständiger Leitfaden