Wie codiere und decodiere ich einen base64-String?

885
  1. Wie gebe ich eine Base64-codierte Zeichenfolge mit einer bestimmten Zeichenfolge zurück?

  2. Wie dekodiere ich eine Base64-codierte Zeichenfolge in eine Zeichenfolge?

Kevin Driedger
quelle
4
Wenn dies eine Frage und Antwort zum "Teilen des Wissens" ist, suchen wir meiner Meinung nach etwas, das etwas tiefer geht. Auch eine schnelle Suche nach SO erscheint: stackoverflow.com/a/7368168/419
Kev
1
@Gnark Jede Zeichenfolge wird von einem bestimmten zugrunde liegenden Bitcodierungsschema codiert. Sei es ASCII, UTF7, UTF8, .... Die gestellte Frage ist bestenfalls unvollständig.
Lorenz Lo Sauer
2
Fragen Sie sich, müssen Sie das wirklich tun? Denken Sie daran, dass base64 in erster Linie zur Darstellung von Binärdaten in ASCII, zum Speichern in einem Zeichenfeld in einer Datenbank oder zum Senden per E-Mail (wo neue Zeilen eingefügt werden könnten) vorgesehen ist. Möchten Sie wirklich Zeichendaten aufnehmen, in Bytes konvertieren und dann wieder in Zeichendaten konvertieren, diesmal unlesbar und ohne Hinweis auf die ursprüngliche Codierung?
Bbsimonbb
Warum sollten wir uns für die ursprüngliche Codierung interessieren? Wir codieren die Zeichenfolge mithilfe der UTF8-Darstellung in die Bytes, die alle möglichen Zeichenfolgenzeichen darstellen kann. Anschließend serialisieren wir diese Daten und am anderen Ende deserialisieren wir diese Daten und rekonstruieren dieselbe Zeichenfolge, die wir ursprünglich hatten (das Zeichenfolgenobjekt enthält ohnehin nicht die Informationen zur verwendeten Codierung). Warum gibt es also Bedenken hinsichtlich der verwendeten Codierung? Wir können es als eine proprietäre Art der Darstellung der serialisierten Daten betrachten, an der wir sowieso nicht interessiert sein sollten.
Mladen B.

Antworten:

1667

Kodieren

public static string Base64Encode(string plainText) {
  var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
  return System.Convert.ToBase64String(plainTextBytes);
}

Dekodieren

public static string Base64Decode(string base64EncodedData) {
  var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
  return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
}
Kevin Driedger
quelle
41
Null prüft auf Eingabezeichenfolgen in beiden Funktionen und die Lösung ist perfekt :)
Sverrir Sigmundarson
22
@SverrirSigmundarson: Das oder machen sie Erweiterungsmethoden.
TJ Crowder
73
@SverrirSigmundarson - Warum eine Nullprüfung durchführen? Er ist nicht derjenige, der die Eingabezeichenfolge dereferenziert. Nullprüfungen sollten NullReferenceExceptionin Ihrem eigenen Code verhindern, nicht in dem eines anderen.
Ken
16
@ken Und jemand anderes wird sagen "Sie sollten nur Fehler in Ihrem eigenen Code aufdecken, nicht den eines anderen", wobei er sich auf das Prinzip der geringsten Überraschung beruft, gewürzt mit "früh scheitern" und "ordnungsgemäße Kapselung". Manchmal bedeutet dies, Fehler von Komponenten niedrigerer Ebene zu verpacken, manchmal etwas ganz anderes. In diesem Fall stimme ich zu, dass das Umschließen eines Deref-Fehlers definitiv zweifelhaft ist (und wir sind uns alle langsam einig, dass Null als Konzept zunächst ein Hack ist), aber wir können immer noch einige Effekte sehen Andernfalls: Der in der Ausnahme angegebene Parametername ist möglicherweise nicht korrekt, wenn das Kontrollkästchen nicht aktiviert ist.
Der
6
return System.Text.Encoding.UTF8.GetString (base64EncodedBytes, 0, base64EncodedBytes.Length); für Windows Phone 8
Steve Zoleko
46

Ich teile meine Implementierung mit einigen netten Funktionen:

  • verwendet Erweiterungsmethoden für die Codierungsklasse. Grund dafür ist, dass jemand möglicherweise verschiedene Arten von Codierungen unterstützen muss (nicht nur UTF8).
  • Eine weitere Verbesserung besteht darin, dass das Null-Ergebnis für die Null-Eingabe ordnungsgemäß fehlschlägt. Dies ist in realen Szenarien sehr nützlich und unterstützt die Äquivalenz für X = decode (encode (X)).

Anmerkung: Denken Sie daran, dass Sie (!) Den Namespace mit dem Schlüsselwort (in diesem Fall ) importieren müssen , um die Erweiterungsmethode zu verwenden .usingusing MyApplication.Helpers.Encoding

Code:

namespace MyApplication.Helpers.Encoding
{
    public static class EncodingForBase64
    {
        public static string EncodeBase64(this System.Text.Encoding encoding, string text)
        {
            if (text == null)
            {
                return null;
            }

            byte[] textAsBytes = encoding.GetBytes(text);
            return System.Convert.ToBase64String(textAsBytes);
        }

        public static string DecodeBase64(this System.Text.Encoding encoding, string encodedText)
        {
            if (encodedText == null)
            {
                return null;
            }

            byte[] textAsBytes = System.Convert.FromBase64String(encodedText);
            return encoding.GetString(textAsBytes);
        }
    }
}

Anwendungsbeispiel:

using MyApplication.Helpers.Encoding; // !!!

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Test1();
            Test2();
        }

        static void Test1()
        {
            string textEncoded = System.Text.Encoding.UTF8.EncodeBase64("test1...");
            System.Diagnostics.Debug.Assert(textEncoded == "dGVzdDEuLi4=");

            string textDecoded = System.Text.Encoding.UTF8.DecodeBase64(textEncoded);
            System.Diagnostics.Debug.Assert(textDecoded == "test1...");
        }

        static void Test2()
        {
            string textEncoded = System.Text.Encoding.UTF8.EncodeBase64(null);
            System.Diagnostics.Debug.Assert(textEncoded == null);

            string textDecoded = System.Text.Encoding.UTF8.DecodeBase64(textEncoded);
            System.Diagnostics.Debug.Assert(textDecoded == null);
        }
    }
}
andrew.fox
quelle
5
Die Rückgabe nullim Falle von nullist ein sehr inkonsistentes Verhalten. Keine andere .net-API, die mit Zeichenfolgen arbeitet, tut dies.
t3chb0t
4
@ t3chb0t Sie können es jederzeit an Ihre Bedürfnisse anpassen. Da die Art und Weise, wie es hier präsentiert wird, an unsere angepasst wurde. Dies ist keine öffentliche API;)
andrew.fox
1
Müssen Sie jetzt nicht zwei Variablen an die andere Partei in Ihrer Kommunikation senden (an die Sie base64-codierte Daten senden)? Sie müssen sowohl die verwendete Codierung als auch die tatsächlichen base64-Daten senden? Ist es nicht einfacher, wenn Sie auf beiden Seiten eine Konvention verwenden, um dieselbe Codierung zu verwenden? Auf diese Weise müssten Sie nur base64-Daten senden, oder?
Mladen B.
38

Basierend auf den Antworten von Andrew Fox und Cebe habe ich es umgedreht und sie zu String-Erweiterungen anstelle von Base64String-Erweiterungen gemacht.

public static class StringExtensions
{
    public static string ToBase64(this string text)
    {
        return ToBase64(text, Encoding.UTF8);
    }

    public static string ToBase64(this string text, Encoding encoding)
    {
        if (string.IsNullOrEmpty(text))
        {
            return text;
        }

        byte[] textAsBytes = encoding.GetBytes(text);
        return Convert.ToBase64String(textAsBytes);
    }

    public static bool TryParseBase64(this string text, out string decodedText)
    {
        return TryParseBase64(text, Encoding.UTF8, out decodedText);
    }

    public static bool TryParseBase64(this string text, Encoding encoding, out string decodedText)
    {
        if (string.IsNullOrEmpty(text))
        {
            decodedText = text;
            return false;
        }

        try
        {
            byte[] textAsBytes = Convert.FromBase64String(text);
            decodedText = encoding.GetString(textAsBytes);
            return true;
        }
        catch (Exception)
        {
            decodedText = null;
            return false;
        }
    }
}
j2 assoziiert
quelle
1
Ich würde eine ParseBase64 hinzufügen (dieser Zeichenfolgentext, Codierungscodierung, out string decodedText) (um die Ausnahme bei Bedarf auszufüllen, und dies auf der TryParseBase64
João Antunes
22

Eine geringfügige Abweichung von der Antwort von andrew.fox, da die zu dekodierende Zeichenfolge möglicherweise keine korrekte Base64-codierte Zeichenfolge ist:

using System;

namespace Service.Support
{
    public static class Base64
    {
        public static string ToBase64(this System.Text.Encoding encoding, string text)
        {
            if (text == null)
            {
                return null;
            }

            byte[] textAsBytes = encoding.GetBytes(text);
            return Convert.ToBase64String(textAsBytes);
        }

        public static bool TryParseBase64(this System.Text.Encoding encoding, string encodedText, out string decodedText)
        {
            if (encodedText == null)
            {
                decodedText = null;
                return false;
            }

            try
            {
                byte[] textAsBytes = Convert.FromBase64String(encodedText);
                decodedText = encoding.GetString(textAsBytes);
                return true;
            }
            catch (Exception)
            {
                decodedText = null;
                return false;   
            }
        }
    }
}
Cebe
quelle
13

Sie können die folgende Routine verwenden, um Zeichenfolgen in das Base64-Format zu konvertieren

public static string ToBase64(string s)
{
    byte[] buffer = System.Text.Encoding.Unicode.GetBytes(s);
    return System.Convert.ToBase64String(buffer);
}

Sie können auch das sehr gute Online-Tool OnlineUtility.in verwenden , um Zeichenfolgen im Base64-Format zu codieren

Chetan Chaphekar
quelle
Online-Tools helfen in dieser Situation nicht weiter - Er fragt, wie man es codiert. Ich frage mich oft, warum die Leute "Check out this online tool!" Sagen, weil das OP nicht nach einem Online-Tool gefragt hat: D
Momoro
9
    using System;
    using System.Text;

    public static class Base64Conversions
    {
        public static string EncodeBase64(this string text, Encoding encoding = null)
        { 
            if (text == null) return null;

            encoding = encoding ?? Encoding.UTF8;
            var bytes = encoding.GetBytes(text);
            return Convert.ToBase64String(bytes);
        }

        public static string DecodeBase64(this string encodedText, Encoding encoding = null)
        {
            if (encodedText == null) return null;

            encoding = encoding ?? Encoding.UTF8;
            var bytes = Convert.FromBase64String(encodedText);
            return encoding.GetString(bytes);
        }
    }

Verwendungszweck

    var text = "Sample Text";
    var base64 = text.EncodeBase64();
    base64 = text.EncodeBase64(Encoding.UTF8); //or with Encoding
Sameera R.
quelle
4

URL-sicher Base64-Codierung / -Decodierung

public static class Base64Url
{
    public static string Encode(string text)
    {
        return Convert.ToBase64String(Encoding.UTF8.GetBytes(text)).TrimEnd('=').Replace('+', '-')
            .Replace('/', '_');
    }

    public static string Decode(string text)
    {
        text = text.Replace('_', '/').Replace('-', '+');
        switch (text.Length % 4)
        {
            case 2:
                text += "==";
                break;
            case 3:
                text += "=";
                break;
        }
        return Encoding.UTF8.GetString(Convert.FromBase64String(text));
    }
}
juliushuck
quelle
1
Die Frage betraf nicht die URL-Codierung, war aber dennoch hilfreich .
Momoro
Hoppla, habe es unter der falschen Frage gepostet
juliushuck
Kein Problem, es ist immer noch interessant zu sehen, wie man eine URL codiert / decodiert :)
Momoro
3

Sie können es folgendermaßen anzeigen:

var strOriginal = richTextBox1.Text;

byte[] byt = System.Text.Encoding.ASCII.GetBytes(strOriginal);

// convert the byte array to a Base64 string
string strModified = Convert.ToBase64String(byt);

richTextBox1.Text = "" + strModified;

Jetzt konvertieren Sie es zurück.

var base64EncodedBytes = System.Convert.FromBase64String(richTextBox1.Text);

richTextBox1.Text = "" + System.Text.Encoding.ASCII.GetString(base64EncodedBytes);
MessageBox.Show("Done Converting! (ASCII from base64)");

Ich hoffe das hilft!

Momoro
quelle
1

Für diejenigen, die einfach einzelne base64-Ziffern codieren / decodieren möchten:

public static int DecodeBase64Digit(char digit, string digit62 = "+-.~", string digit63 = "/_,")
{
    if (digit >= 'A' && digit <= 'Z') return digit - 'A';
    if (digit >= 'a' && digit <= 'z') return digit + (26 - 'a');
    if (digit >= '0' && digit <= '9') return digit + (52 - '0');
    if (digit62.IndexOf(digit) > -1)  return 62;
    if (digit63.IndexOf(digit) > -1)  return 63;
    return -1;
}

public static char EncodeBase64Digit(int digit, char digit62 = '+', char digit63 = '/')
{
    digit &= 63;
    if (digit < 52)
        return (char)(digit < 26 ? digit + 'A' : digit + ('a' - 26));
    else if (digit < 62)
        return (char)(digit + ('0' - 52));
    else
        return digit == 62 ? digit62 : digit63;
}

Es gibt verschiedene Versionen von Base64, die sich nicht darüber einig sind, was für die Ziffern 62 und 63 verwendet werden soll, und daher DecodeBase64Digitmehrere davon tolerieren können.

Qwertie
quelle