Как мне кодировать и декодировать строку base64?

885
  1. Как вернуть строку в кодировке base64 для данной строки?

  2. Как мне декодировать строку в кодировке base64 в строку?

Кевин Дридгер
источник
4
Если это вопрос и ответ «обмена знаниями», я думаю, что мы ищем что-то более глубокое. Также появляется быстрый поиск SO: stackoverflow.com/a/7368168/419
Kev
1
@Gnark Любая строка кодируется определенной базовой схемой кодирования битов. Будь то ASCII, UTF7, UTF8, .... Поставленный вопрос в лучшем случае неполон.
Лоренц Ло Зауэр
2
Спросите себя, вам действительно нужно это сделать? Помните, что base64 в первую очередь предназначен для представления двоичных данных в ASCII, для хранения в поле char в базе данных или отправки по электронной почте (где могут быть введены новые строки). Вы действительно хотите взять символьные данные, преобразовать их в байты, а затем преобразовать обратно в символьные данные, на этот раз не читаемые и без намека на то, какой была первоначальная кодировка?
bbsimonbb
Почему мы должны заботиться об оригинальной кодировке? Мы кодируем строку в байты, используя представление UTF8, которое может представлять все возможные строковые символы. Затем мы сериализуем эти данные, а на другом конце мы десериализуем эти данные и восстанавливаем ту же строку, которая у нас была изначально (строковый объект в любом случае не содержит информацию об используемой кодировке). Так почему же существует проблема, связанная с используемой кодировкой? Мы можем рассматривать это как проприетарный способ представления сериализованных данных, который нас не должен интересовать в любом случае.
Младен Б.

Ответы:

1668

шифровать

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

раскодировать

public static string Base64Decode(string base64EncodedData) {
  var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
  return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
}
Кевин Дридгер
источник
41
Null проверяет наличие входных строк в обеих функциях, и решение является идеальным :)
Sverrir Sigmundarson
22
@SverrirSigmundarson: Это или сделать их методы расширения.
TJ Crowder
73
@SverrirSigmundarson - Почему проверка на ноль? Он не разыменовывает входную строку. Нулевые проверки должны предотвращать NullReferenceExceptionв вашем собственном коде, а не в чужом.
Кен
16
@ken А кто-то еще скажет: «Вы должны сообщать об ошибках только в своем собственном коде, а не в чужом», ссылаясь на принцип наименьшего удивления, приправленный «неудачей рано» и «правильной инкапсуляцией». Иногда это означает ошибки упаковки компонентов более низкого уровня, иногда что-то совсем другое. В этом случае я согласен с тем, что перенос ошибки разыменования определенно сомнителен (плюс мы все медленно соглашаемся с тем фактом, что null как концепция с самого начала является чем-то вроде хака), но мы все же можем увидеть некоторые эффекты в противном случае: имя параметра, указанное в исключении, может быть неверным, если его не проверять.
TNE
6
return System.Text.Encoding.UTF8.GetString (base64EncodedBytes, 0, base64EncodedBytes.Length); для Windows Phone 8
Стивен Золеко
46

Я делюсь своей реализацией с некоторыми полезными функциями:

  • использует методы расширения для класса кодирования. Обоснование заключается в том, что кому-то может потребоваться поддержка различных типов кодировок (не только UTF8).
  • Еще одним улучшением является изящный сбой с нулевым результатом для нулевого ввода - это очень полезно в реальных сценариях и поддерживает эквивалентность для X = decode (encode (X)).

Примечание: Помните, что для использования метода расширения вы должны (!) Импортировать пространство имен с usingключевым словом (в данном случае using MyApplication.Helpers.Encoding).

Код:

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

Пример использования:

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
источник
5
Возвращение nullв случае nullочень противоречивого поведения. Никакой другой .net API, который работает со строками, не делает этого.
t3chb0t
4
@ t3chb0t не стесняйтесь настроить его под свои нужды. Как то, как это представлено здесь, было приспособлено к нашему. Это не публичный API;)
andrew.fox
1
Разве вам теперь не нужно отправлять 2 переменные другой стороне в вашем общении (кому вы отправляете данные в кодировке base64)? Вам необходимо отправить как используемую кодировку, так и фактические данные base64? Не проще ли, если вы используете соглашение с обеих сторон, чтобы использовать одну и ту же кодировку? Таким образом, вам нужно будет только отправить данные base64, верно?
Младен Б.
38

Основываясь на ответах Эндрю Фокса и Себе, я перевернул их и сделал их строковыми расширениями вместо расширений Base64String.

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;
        }
    }
}
j2associates
источник
1
Я бы добавил ParseBase64 (этот текст строки, Кодировка кодирования, out string decodedText) (чтобы заполнить исключение, если необходимо, и вызвал бы это в TryParseBase64
João Antunes
22

Небольшое изменение в ответе andrew.fox, так как строка для декодирования может быть неверной строкой в ​​кодировке base64:

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
источник
13

Вы можете использовать следующую подпрограмму для преобразования строки в формат base64

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

Также вы можете использовать очень хороший онлайн-инструмент OnlineUtility.in для кодирования строки в формате base64.

Четан Чапекар
источник
Онлайн инструменты не помогают в этой ситуации - он спрашивает, как его кодировать. Я часто задаюсь вопросом, почему люди говорят: «Зацените этот онлайн-инструмент!», Потому что ОП не запрашивал онлайн-инструмент: D
Моморо,
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);
        }
    }

Применение

    var text = "Sample Text";
    var base64 = text.EncodeBase64();
    base64 = text.EncodeBase64(Encoding.UTF8); //or with Encoding
Самера Р.
источник
4

URL безопасный Base64 Кодировка / Декодирование

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
источник
1
Вопрос был не о кодировке URL, но все еще полезен ..
Моморо
Упс, выложил под неправильным вопросом
juliushuck
Нет проблем, все еще интересно посмотреть, как кодировать / декодировать URL-адрес :)
Momoro
3

Вы можете отобразить это так:

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;

Теперь конвертируем обратно.

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

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

Надеюсь, это поможет!

Momoro
источник
1

Для тех, кто просто хочет кодировать / декодировать отдельные цифры base64:

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

Существуют различные версии Base64, которые не согласны с тем, что использовать для цифр 62 и 63, поэтому DecodeBase64Digitмогут допускать некоторые из них.

Qwertie
источник