Como codifico e decodifico uma string base64?

885
  1. Como faço para retornar uma string codificada em base64, dada uma string?

  2. Como decodificar uma string codificada em base64 em uma string?

Kevin Driedger
fonte
4
Se essa é uma pergunta e resposta para "compartilhar o conhecimento", acho que estamos procurando algo um pouco mais profundo. Também aparece uma pesquisa rápida de SO: stackoverflow.com/a/7368168/419
Kev
1
@Gnark Qualquer string é codificada por um determinado esquema de codificação de bits subjacente. Seja ASCII, UTF7, UTF8, .... A questão colocada é, na melhor das hipóteses, incompleta.
Lorenz Lo Sauer
2
Pergunte a si mesmo: você realmente precisa fazer isso? Lembre-se de que o base64 se destina principalmente a representar dados binários em ASCII, a armazenar em um campo char em um banco de dados ou a enviar por e-mail (onde novas linhas podem ser injetadas). Deseja realmente obter dados de caracteres, convertê-los em bytes e convertê-los novamente em dados de caracteres, desta vez ilegíveis e sem nenhuma dica do que era a codificação original?
precisa saber é o seguinte
Por que devemos nos preocupar com a codificação original? Codificamos a string nos bytes usando a representação UTF8, que pode representar todos os caracteres possíveis da string. Em seguida, serializamos esses dados e, por outro lado, desserializamos esses dados e reconstruímos a mesma string que tínhamos originalmente (o objeto string não mantém as informações sobre codificação usadas de qualquer maneira). Então, por que existe alguma preocupação relacionada à codificação usada? Podemos considerá-lo como uma maneira proprietária de representar os dados serializados, pelos quais não devemos nos interessar.
Mladen B.

Respostas:

1668

Codificar

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

Decodificar

public static string Base64Decode(string base64EncodedData) {
  var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
  return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
}
Kevin Driedger
fonte
41
Verificações nulos para cadeias de entrada em ambas as funções e a solução é perfeito :)
Sverrir Sigmundarson
22
@SverrirSigmundarson: Isso ou torná-los métodos de extensão.
TJ Crowder
73
@SverrirSigmundarson - Por que uma verificação nula? Ele não é quem desreferencia a string de entrada. As verificações nulas devem impedir o NullReferenceExceptionseu próprio código, não o de outra pessoa.
ken
16
@ken E outra pessoa dirá "você só deve expor erros no seu próprio código, não no de outra pessoa", invocando o princípio da menor surpresa, temperado com "falha antecipada" e "encapsulamento adequado". Às vezes, isso significa ocultar erros de componentes de nível inferior, às vezes algo completamente diferente. Nesse caso, eu concordarei que a quebra de um deref é definitivamente duvidosa (além disso, todos concordamos lentamente com o fato de que o conceito nulo é um pouco complicado, para começar), mas ainda podemos ver alguns efeitos caso contrário: o nome do parâmetro fornecido na exceção pode não estar correto se não estiver marcado.
tne
6
retornar System.Text.Encoding.UTF8.GetString (base64EncodedBytes, 0, base64EncodedBytes.Length); para windows phone 8
steveen zoleko
46

Estou compartilhando minha implementação com alguns recursos interessantes:

  • usa a extensão Methods for Encoding class. A justificativa é que alguém pode precisar oferecer suporte a diferentes tipos de codificações (não apenas UTF8).
  • Outra melhoria está falhando normalmente com resultado nulo para entrada nula - é muito útil em cenários da vida real e suporta equivalência para decodificação X = (codificar (X)).

Observação: lembre-se de que para usar o método de extensão, é necessário (!) Importar o espaço para nome com a usingpalavra - chave (neste caso using MyApplication.Helpers.Encoding).

Código:

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

Exemplo de uso:

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
fonte
5
Retornar nullno caso de nullé um comportamento muito inconsistente. Nenhuma outra API .net que funciona com strings faz isso.
T3chb0t
4
@ t3chb0t fique à vontade para ajustá-lo às suas necessidades. Como a forma como é apresentada aqui foi ajustada à nossa. Esta não é uma API pública;)
andrew.fox
1
Agora você não precisa enviar 2 variáveis ​​para a outra parte em sua comunicação (para quem você está enviando dados codificados em base64)? Você precisa enviar a codificação usada e os dados base64 reais? Não é mais fácil se você usar uma convenção de ambos os lados para usar a mesma codificação? Dessa forma, você só teria que enviar dados base64, certo?
Mladen B.
38

Com base nas respostas de Andrew Fox e Cebe, eu mudei e fiz extensões de string em vez de extensões 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
fonte
1
Eu gostaria de acrescentar um ParseBase64 (este texto corda, codificação de codificação, a decodedText string) (para preencher a exceção se necessário, e chamada que na TryParseBase64
João Antunes
22

Uma pequena variação na resposta andrew.fox, pois a sequência a ser decodificada pode não ser a sequência codificada em base64 correta:

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
fonte
13

Você pode usar a rotina abaixo para converter string em formato base64

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

Além disso, você pode usar a ferramenta online muito boa OnlineUtility.in para codificar string no formato base64

chetan chaphekar
fonte
As ferramentas online não ajudam nessa situação - ele está perguntando como codificá-lo. Muitas vezes me pergunto por que as pessoas dizem "Confira esta ferramenta on-line!", Porque o OP não pediu uma ferramenta on-line: 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);
        }
    }

Uso

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

Codificação / Decodificação Base64 segura de URL

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
fonte
1
A pergunta não era sobre codificação de URL, mas ainda é útil ..
Momoro 21/03
Opa, postei na pergunta errada
juliushuck 24/03
Não tem problema, ainda é interessante ver como codificar / decodificar um URL :)
Momoro
3

Você pode exibi-lo assim:

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;

Agora, convertendo de volta.

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

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

Eu espero que isso ajude!

Momoro
fonte
1

Para aqueles que simplesmente desejam codificar / decodificar dígitos base64 individuais:

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

Existem várias versões do Base64 que discordam sobre o que usar nos dígitos 62 e 63, portanto DecodeBase64Digitpodem tolerar vários deles.

Qwertie
fonte