Bagaimana cara menyandikan dan mendekode string base64?

885
  1. Bagaimana cara mengembalikan string yang disandikan base64 diberi string?

  2. Bagaimana cara men-decode string yang disandikan base64 ke dalam string?

Kevin Driedger
sumber
4
Jika ini adalah pertanyaan dan jawaban "berbagi pengetahuan", saya pikir kami sedang mencari sesuatu yang sedikit lebih mendalam. Pencarian SO yang cepat juga muncul: stackoverflow.com/a/7368168/419
Kev
1
@ Mark Setiap string dikodekan oleh skema bit-encoding yang mendasari tertentu. Baik itu ASCII, UTF7, UTF8, .... Pertanyaan yang diajukan paling tidak lengkap.
Lorenz Lo Sauer
2
Tanyakan pada diri sendiri apakah Anda benar-benar perlu melakukan ini? Ingat base64 terutama dimaksudkan untuk mewakili data biner di ASCII, untuk menyimpan dalam bidang char dalam database atau mengirim melalui email (di mana baris baru dapat disuntikkan). Apakah Anda benar-benar ingin mengambil data karakter, mengonversinya menjadi byte, lalu mengonversinya kembali ke data karakter, kali ini tidak dapat dibaca dan tanpa petunjuk tentang apa pengkodean aslinya?
bbsimonbb
Mengapa kita harus peduli dengan penyandian asli? Kami menyandikan string ke dalam byte menggunakan representasi UTF8, yang dapat mewakili semua karakter string yang mungkin. Kami kemudian membuat serial data itu dan di sisi lain kami deserialize data itu dan kami merekonstruksi string yang sama yang kami miliki sebelumnya (objek string tetap tidak menyimpan informasi tentang pengkodean yang digunakan). Jadi mengapa ada kekhawatiran terkait pengkodean yang digunakan? Kita dapat menganggapnya sebagai cara berpemilik untuk merepresentasikan data bersambung, yang tidak seharusnya kita tertarik.
Mladen B.

Jawaban:

1668

Menyandi

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

Membaca sandi

public static string Base64Decode(string base64EncodedData) {
  var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
  return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
}
Kevin Driedger
sumber
41
Null memeriksa string input di kedua fungsi dan solusinya sempurna :)
Sverrir Sigmundarson
22
@SverrirSigmundarson: Itu atau buat mereka metode ekstensi.
TJ Crowder
73
@SverrirSigmundarson - Mengapa cek nol? Dia bukan orang yang mereferensi string input. Pemeriksaan kosong harus mencegah NullReferenceExceptionkode Anda sendiri, bukan milik orang lain.
ken
16
@ken Dan orang lain akan mengatakan "Anda hanya harus mengekspos kesalahan dalam kode Anda sendiri, bukan orang lain", menerapkan prinsip paling tidak mengejutkan, dibumbui dengan "gagal awal" dan "enkapsulasi yang tepat". Kadang-kadang ini berarti membungkus kesalahan komponen tingkat rendah, terkadang sesuatu yang lain sama sekali. Dalam hal ini, saya akan setuju bahwa membungkus kesalahan deref jelas meragukan (ditambah kita semua perlahan-lahan menyetujui fakta bahwa null sebagai konsep adalah sedikit peretasan untuk memulai), tetapi kita masih dapat melihat beberapa efek jika tidak: nama parameter yang diberikan dalam pengecualian mungkin tidak benar jika dibiarkan tidak dicentang.
mentega
6
return System.Text.Encoding.UTF8.GetString (base64EncodedBytes, 0, base64EncodedBytes.Length); untuk windows phone 8
steveen zoleko
46

Saya membagikan implementasi saya dengan beberapa fitur rapi:

  • menggunakan Metode Extension untuk kelas Encoding. Alasannya adalah bahwa seseorang mungkin perlu mendukung berbagai jenis penyandian (tidak hanya UTF8).
  • Peningkatan lainnya gagal dengan anggun dengan hasil nol untuk entri nol - ini sangat berguna dalam skenario kehidupan nyata dan mendukung kesetaraan untuk X = decode (encode (X)).

Catatan: Ingatlah bahwa untuk menggunakan Metode Ekstensi Anda harus (!) Mengimpor namespace dengan usingkata kunci (dalam hal ini using MyApplication.Helpers.Encoding).

Kode:

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

Contoh penggunaan:

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
sumber
5
Kembali nulljika nullada perilaku yang sangat tidak konsisten. Tidak ada .net API lain yang berfungsi dengan string yang melakukan itu.
t3chb0t
4
@ t3chb0t merasa bebas untuk menyesuaikannya dengan kebutuhan Anda. Seperti cara itu disajikan di sini disesuaikan dengan kita. Ini bukan API publik;)
andrew.fox
1
Bukankah sekarang Anda harus mengirim 2 variabel ke pihak lain dalam komunikasi Anda (kepada siapa Anda mengirim data yang disandikan base64)? Anda perlu mengirim encoding yang digunakan dan data base64 yang sebenarnya? Bukankah lebih mudah jika Anda menggunakan konvensi di kedua sisi untuk menggunakan pengkodean yang sama? Dengan begitu Anda hanya perlu mengirim data base64, kan?
Mladen B.
38

Berdasarkan jawaban dari Andrew Fox dan Cebe, saya memutarnya dan menjadikannya ekstensi string, bukan ekstensi 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;
        }
    }
}
j2bergaul
sumber
1
Saya akan menambahkan ParseBase64 (teks string ini, Encoding encoding, out string decodedText) (untuk mengisi pengecualian jika diperlukan, dan menyebutnya pada TryParseBase64
João Antunes
22

Sedikit variasi pada andrew.fox menjawab, karena string yang akan didekode mungkin bukan string yang dienkode base64 yang benar:

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

Anda dapat menggunakan rutinitas di bawah ini untuk mengonversi string ke format base64

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

Anda juga dapat menggunakan alat OnlineUtility.in online yang sangat bagus untuk menyandikan string dalam format base64

chetan chaphekar
sumber
Alat daring tidak membantu dalam situasi ini - Dia bertanya bagaimana cara KODE TI. Saya sering bertanya-tanya mengapa orang mengatakan "Lihat alat online ini!", Karena OP tidak meminta alat online: 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);
        }
    }

Pemakaian

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

URL aman 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));
    }
}
juliushuck
sumber
1
Pertanyaan bukan tentang Pengkodean URL, tetapi masih membantu ..
Momoro
Whoops, mempostingnya di bawah pertanyaan yang salah
juliushuck
Tidak masalah, masih menarik untuk melihat cara menyandikan / mendekodekan URL :)
Momoro
3

Anda dapat menampilkannya seperti ini:

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;

Sekarang, ubah kembali.

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

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

Saya harap ini membantu!

Momoro
sumber
1

Bagi mereka yang hanya ingin menyandikan / mendekodekan masing-masing digit 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;
}

Ada berbagai versi Base64 yang tidak setuju tentang apa yang harus digunakan untuk angka 62 dan 63, sehingga DecodeBase64Digitdapat mentolerir beberapa di antaranya.

Qwertie
sumber