ChatGPT解决这个技术问题 Extra ChatGPT

How do I encode and decode a base64 string?

How do I return a base64 encoded string given a string? How do I decode a base64 encoded string into a string?

If this is a "sharing the knowledge" question and answer, I think we're looking for something a bit more in-depth. Also a quick search of SO turns up: stackoverflow.com/a/7368168/419
Ask yourself do you really need to do this? Remember base64 is primarily intended for representing binary data in ASCII, for storing in a char field in a database or sending via email (where new lines could be injected). Do you really want to take character data, convert it to bytes, then convert it back to character data, this time unreadable and with no hint of what the original encoding was ?
Why should we care about the original encoding? We encode the string into the bytes using UTF8 representation, which can represent all the possible string characters. We then serialize that data and on the other end we deserialize that data and we reconstruct the same string that we originally had (string object doesn't hold the information about encoding used anyway). So why is there any concern related to the encoding used? We can consider it like a proprietary way of representing the serialized data, which we shouldn't be interested at anyway.

A
Azeem

Encode

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

Decode

public static string Base64Decode(string base64EncodedData) {
  var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
  return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
}

Null checks for input strings in both functions and the solution is perfect :)
@SverrirSigmundarson: That or make them extension methods.
@SverrirSigmundarson - Why do a null check? He's not the one dereferencing the input string. Null checks should prevent NullReferenceException in your own code, not somebody else's.
@ken And somebody else will say "you should only expose errors in your own code, not somebody else's", invoking the principle of least surprise, spiced with "fail early" and "proper encapsulation". Sometimes this means wrapping errors of lower-level components, sometimes something else entirely. In this case, I'll agree that wrapping a deref error is definitely dubious (plus we're all slowly agreeing to the fact that null as a concept is a bit of a hack to begin with), but we can still see some effects otherwise: the parameter name given in the exception might not be correct if left unchecked.
return System.Text.Encoding.UTF8.GetString(base64EncodedBytes, 0, base64EncodedBytes.Length); for windows phone 8
Z
Zeigeist

One liner code:

Note: Use System and System.Text directives.

Encode:

string encodedStr = Convert.ToBase64String(Encoding.UTF8.GetBytes("inputStr"));

Decode:

string inputStr = Encoding.UTF8.GetString(Convert.FromBase64String(encodedStr));

Thanks for remembering to include mention of the namespaces - people always just assume that
@stimms any serious IDE will provide these to you though ;)
@derHugo if the namespace located in an assembly which is not referenced by default, then even a serious IDE can't help :)
@RAPTOR well in this case also adding the using statements wouldn't help much ;)
@derHugo that's true of course, but if we know the namespace we can guess the assembly name. (at least it helped me several times)
a
andrew.fox

I'm sharing my implementation with some neat features:

uses Extension Methods for Encoding class. Rationale is that someone may need to support different types of encodings (not only UTF8).

Another improvement is failing gracefully with null result for null entry - it's very useful in real life scenarios and supports equivalence for X=decode(encode(X)).

Remark: Remember that to use Extension Method you have to (!) import the namespace with using keyword (in this case using 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);
        }
    }
}

Usage example:

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);
        }
    }
}

Returning null in case of null is a very inconsistent behaviour. No other .net API that works with strings does that.
@t3chb0t feel free to adjust it to your needs. As the way it's presented here was adjusted to ours. This is not a public API ;)
A
Azeem

Based on the answers by Andrew Fox and Cebe, I turned it around and made them string extensions instead of Base64String extensions.

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;
        }
    }
}

I would add a ParseBase64(this string text, Encoding encoding, out string decodedText) (to populate the exception if needed, and call that on the TryParseBase64
C
Cebe

A slight variation on andrew.fox answer, as the string to decode might not be a correct base64 encoded string:

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;   
            }
        }
    }
}

D
Daniel

You can use below routine to convert string to base64 format

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

Also you can use very good online tool OnlineUtility.in to encode string in base64 format


Online tools don't help in this situation -- He's asking how to CODE IT. I often wonder why people say "Check out this online tool!", because the OP didn't ask for an online tool :D
j
julius-huck

URL safe Base64 Encoding/Decoding

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));
    }
}

Note that using Replace() and TrimEnd() several times in a row will allocate new strings that will instantly become garbage for the GC. Instead, you can use StringBuilder with a specified capacity to avoid the extra heap allocations.
S
Sameera R.
    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);
        }
    }

Usage

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

J
Josef
// Encoding
string passw = "tes123";
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(passw);
string pass = System.Convert.ToBase64String(plainTextBytes);

// Normal
var encodedTextBytes = Convert.FromBase64String(pass);
string plainText = Encoding.UTF8.GetString(encodedTextBytes);

Q
Qwertie

For those that simply want to encode/decode individual base64 digits:

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;
}

There are various versions of Base64 that disagree about what to use for digits 62 and 63, so DecodeBase64Digit can tolerate several of these.


M
Momoro

You can display it like this:

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;

Now, converting it back.

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

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

I hope this helps!