Làm cách nào để mã hóa và giải mã chuỗi base64?


885
  1. Làm cách nào để trả về một chuỗi được mã hóa base64 cho một chuỗi?

  2. Làm cách nào để giải mã chuỗi mã hóa base64 thành chuỗi?


4
Nếu đây là câu hỏi và câu trả lời "chia sẻ kiến ​​thức", tôi nghĩ chúng ta đang tìm kiếm một cái gì đó sâu hơn một chút. Ngoài ra, một tìm kiếm nhanh của SO bật lên: stackoverflow.com/a/7368168/419
Kev

1
@Gnark Bất kỳ chuỗi nào được mã hóa bởi một lược đồ mã hóa bit cơ bản nhất định. Có thể là ASCII, UTF7, UTF8, .... Câu hỏi được đặt ra là không đầy đủ nhất.
Lorenz Lo Sauer

2
Hãy tự hỏi bạn có thực sự cần phải làm điều này? Hãy nhớ cơ sở 64 chủ yếu nhằm thể hiện dữ liệu nhị phân trong ASCII, để lưu trữ trong trường char trong cơ sở dữ liệu hoặc gửi qua email (nơi có thể chèn các dòng mới). Bạn có thực sự muốn lấy dữ liệu ký tự, chuyển đổi nó thành byte, sau đó chuyển đổi lại thành dữ liệu ký tự, lần này không thể đọc được và không có gợi ý về mã hóa ban đầu là gì?
bbsimonbb

Tại sao chúng ta nên quan tâm đến mã hóa ban đầu? Chúng tôi mã hóa chuỗi thành các byte bằng cách sử dụng biểu diễn UTF8, có thể biểu diễn tất cả các ký tự chuỗi có thể. Sau đó, chúng tôi tuần tự hóa dữ liệu đó và ở đầu bên kia, chúng tôi giải tuần tự hóa dữ liệu đó và chúng tôi xây dựng lại cùng một chuỗi mà chúng tôi có ban đầu (đối tượng chuỗi không giữ thông tin về mã hóa được sử dụng). Vậy tại sao có bất kỳ mối quan tâm liên quan đến mã hóa được sử dụng? Chúng ta có thể coi nó giống như một cách độc quyền để thể hiện dữ liệu được tuần tự hóa, điều mà chúng ta không nên quan tâm dù sao đi nữa.
Mladen B.

Câu trả lời:


1667

Mã hóa

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

Giải mã

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

41
Null kiểm tra các chuỗi đầu vào trong cả hai chức năng và giải pháp là hoàn hảo :)
Sverrir Sigmundarson

22
@SverrirSigmundarson: Điều đó hoặc biến chúng thành các phương thức mở rộng.
TJ Crowder

73
@SverrirSigmundarson - Tại sao kiểm tra null? Anh ấy không phải là người hủy bỏ chuỗi đầu vào. Kiểm tra Null nên ngăn chặn NullReferenceExceptiontrong mã của riêng bạn, không phải của người khác.
ken

16
@ken Và người khác sẽ nói "bạn chỉ nên phơi bày lỗi trong mã của riêng bạn chứ không phải của người khác", viện dẫn nguyên tắc ít bất ngờ nhất, được thêm vào là "thất bại sớm" và "đóng gói đúng". Đôi khi điều này có nghĩa là gói lỗi của các thành phần cấp thấp hơn, đôi khi một cái gì đó hoàn toàn khác. Trong trường hợp này, tôi sẽ đồng ý rằng việc gói một lỗi deref chắc chắn là không rõ ràng (cộng với tất cả chúng ta đều đồng ý với thực tế rằng null là một khái niệm là một chút hack để bắt đầu), nhưng chúng ta vẫn có thể thấy một số hiệu ứng mặt khác: tên tham số được đưa ra trong ngoại lệ có thể không chính xác nếu không được chọn.
tne

6
return System.Text.Encoding.UTF8.GetString (base64EncodingBytes, 0, base64EncodingBytes.Ldrops); cho windows phone 8
steveen zoleko 9/12/2015

46

Tôi đang chia sẻ triển khai của mình với một số tính năng gọn gàng:

  • sử dụng các Phương thức mở rộng cho lớp Mã hóa. Lý do là ai đó có thể cần hỗ trợ các loại mã hóa khác nhau (không chỉ UTF8).
  • Một cải tiến khác đang thất bại một cách duyên dáng với kết quả null cho mục nhập null - nó rất hữu ích trong các tình huống thực tế và hỗ trợ tương đương cho X = decode (mã hóa (X)).

Lưu ý: Hãy nhớ rằng để sử dụng Phương thức tiện ích mở rộng, bạn phải (!) Nhập không gian tên bằng usingtừ khóa (trong trường hợp này using MyApplication.Helpers.Encoding).

Mã số:

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

Ví dụ sử dụng:

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

5
Trở lại nulltrong trường hợp nulllà một hành vi rất không nhất quán. Không có API .net nào khác hoạt động với chuỗi làm điều đó.
t3chb0t

4
@ t3chb0t hãy thoải mái điều chỉnh nó theo nhu cầu của bạn. Như cách nó được trình bày ở đây đã được điều chỉnh cho chúng ta. Đây không phải là API công khai;)
andrew.fox

1
Bây giờ bạn không phải gửi 2 biến cho bên kia trong liên lạc của mình (người mà bạn đang gửi dữ liệu được mã hóa base64)? Bạn cần gửi cả mã hóa được sử dụng và dữ liệu cơ sở thực tế? Sẽ không dễ dàng hơn nếu bạn sử dụng một quy ước ở cả hai bên để sử dụng cùng một mã hóa? Bằng cách đó, bạn chỉ phải gửi dữ liệu base64, phải không?
Mladen B.

38

Dựa trên câu trả lời của Andrew Fox và Cebe, tôi đã xoay nó và biến chúng thành các phần mở rộng chuỗi thay vì phần mở rộng 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;
        }
    }
}

1
Tôi sẽ thêm một ParseBase64 (văn bản chuỗi này, mã hóa mã hóa, ra chuỗi giải mã chuỗi) (để điền ngoại lệ nếu cần và gọi nó trên TryPudeBase64
João Antunes

22

Một biến thể nhỏ trên câu trả lời của andrew.fox, vì chuỗi giải mã có thể không phải là chuỗi được mã hóa base64 chính xác:

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

13

Bạn có thể sử dụng thường trình dưới đây để chuyển đổi chuỗi sang định dạng base64

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

Ngoài ra, bạn có thể sử dụng công cụ trực tuyến rất tốt OnlineUtility.in để mã hóa chuỗi ở định dạng base64


Các công cụ trực tuyến không giúp ích trong tình huống này - Anh ấy hỏi làm thế nào để MÃ CNTT. Tôi thường tự hỏi tại sao mọi người nói "Hãy xem công cụ trực tuyến này!", Vì OP không yêu cầu một công cụ trực tuyến: 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);
        }
    }

Sử dụng

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

4

Mã hóa / giải mã cơ sở an toàn 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));
    }
}

1
Câu hỏi không phải về Mã hóa URL, nhưng vẫn hữu ích ..
Momoro

Rất tiếc, đã đăng nó dưới câu hỏi sai
juliushuck

Không có vấn đề gì, vẫn rất thú vị để xem cách mã hóa / giải mã URL :)
Momoro

3

Bạn có thể hiển thị nó như thế này:

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;

Bây giờ, chuyển đổi nó trở lại.

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

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

Tôi hi vọng cái này giúp được!


1

Đối với những người chỉ đơn giản muốn mã hóa / giải mã từng chữ số cơ sở64:

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

nhiều phiên bản khác nhau của Base64 không đồng ý về việc sử dụng gì cho các chữ số 62 và 63, vì vậy DecodeBase64Digitcó thể chấp nhận một số trong số này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.