ฉันจะเข้ารหัสและถอดรหัสสตริงเบส 64 ได้อย่างไร


885
  1. ฉันจะคืนสตริงที่เข้ารหัส base64 ที่กำหนดเป็นสตริงได้อย่างไร

  2. ฉันจะถอดรหัสสตริงที่เข้ารหัส base64 เป็นสตริงได้อย่างไร


4
หากนี่คือคำถามและคำตอบ "แบ่งปันความรู้" ฉันคิดว่าเรากำลังมองหาบางสิ่งบางอย่างในเชิงลึกมากขึ้น นอกจากนี้การค้นหาอย่างรวดเร็วของ SO จะเปิดขึ้น: stackoverflow.com/a/7368168/419
Kev

1
@Gnark สตริงใด ๆ ที่ถูกเข้ารหัสโดย schema การเข้ารหัสบิตพื้นฐานบางอย่าง ไม่ว่าจะเป็น ASCII, UTF7, UTF8, .... คำถามที่โพสต์นั้นไม่สมบูรณ์ที่สุด
Lorenz Lo Sauer

2
ถามตัวเองว่าคุณต้องทำสิ่งนี้จริงๆหรือ โปรดจำไว้ว่า base64 นั้นมีจุดประสงค์หลักเพื่อแสดงข้อมูลไบนารีใน ASCII สำหรับการจัดเก็บในช่องถ่านในฐานข้อมูลหรือส่งทางอีเมล คุณต้องการนำข้อมูลอักขระแปลงเป็นไบต์แล้วแปลงกลับเป็นข้อมูลอักขระในครั้งนี้อ่านไม่ได้และไม่มีคำใบ้ว่าการเข้ารหัสดั้งเดิมคืออะไร
bbsimonbb

ทำไมเราต้องสนใจการเข้ารหัสดั้งเดิม? เราเข้ารหัสสตริงเป็นไบต์โดยใช้การแทน UTF8 ซึ่งสามารถแทนอักขระสตริงที่เป็นไปได้ทั้งหมด จากนั้นเราจะจัดลำดับข้อมูลนั้นและท้ายที่สุดเราจะทำการ deserialize ข้อมูลนั้นและเราสร้างสตริงเดียวกันกับที่เรามีอยู่เดิม (วัตถุสตริงไม่ได้เก็บข้อมูลเกี่ยวกับการเข้ารหัสที่ใช้อยู่แล้ว) เหตุใดจึงมีข้อกังวลเกี่ยวกับการเข้ารหัสที่ใช้ เราสามารถพิจารณาได้ว่ามันเป็นวิธีที่เป็นกรรมสิทธิ์ในการแสดงข้อมูลต่อเนื่องซึ่งเราไม่ควรสนใจ
Mladen B.

คำตอบ:


1667

เปลี่ยนเป็นรหัส

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 - ทำไมการตรวจสอบที่เป็นโมฆะ? เขาไม่ได้เป็นคนที่พูดถึงสายป้อนข้อมูล การตรวจสอบ Null ควรป้องกันNullReferenceExceptionในรหัสของคุณเองไม่ใช่ของคนอื่น
เคน

16
@ken และคนอื่นจะพูดว่า "คุณควรเปิดเผยข้อผิดพลาดในรหัสของคุณเองไม่ใช่คนอื่น" กล่าวถึงหลักการของความประหลาดใจน้อยที่สุด spiced กับ "ล้มเหลวเร็ว" และ "encapsulation ที่เหมาะสม" บางครั้งสิ่งนี้หมายถึงการห่อข้อผิดพลาดของส่วนประกอบระดับล่าง ในกรณีนี้ฉันจะยอมรับว่าการตัดข้อผิดพลาด deref นั้นน่าสงสัยอย่างแน่นอน (และเราทุกคนก็ยอมรับอย่างช้าๆกับความจริงที่ว่า null เนื่องจากแนวคิดเป็นบิตของการแฮ็กที่จะเริ่มต้นด้วย) แต่เรายังเห็นผลบางอย่าง มิฉะนั้น: ชื่อพารามิเตอร์ที่ระบุในข้อยกเว้นอาจไม่ถูกต้องหากไม่ได้ตรวจสอบ
tne

6
ส่งคืน System.Text.Encoding.UTF8.GetString (base64EncodedBytes, 0, base64EncodedBytes.Length); สำหรับ Windows Phone 8
steveen zoleko

46

ฉันแบ่งปันการใช้งานของฉันกับคุณสมบัติที่เป็นระเบียบ:

  • ใช้วิธีการขยายสำหรับการเข้ารหัสคลาส เหตุผลคือบางคนอาจต้องสนับสนุนการเข้ารหัสประเภทต่าง ๆ (ไม่เพียง แต่ UTF8 เท่านั้น)
  • การปรับปรุงอื่น ๆ ล้มเหลวอย่างงดงามด้วยผลลัพธ์ที่เป็นโมฆะสำหรับรายการที่เป็นโมฆะ - มันมีประโยชน์มากในสถานการณ์ในชีวิตจริงและรองรับการเทียบเท่าสำหรับ X = ถอดรหัส (เข้ารหัส (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);
        }
    }
}

5
การกลับมาnullในกรณีที่nullเป็นพฤติกรรมที่ไม่สอดคล้องกันมาก ไม่มี. net API อื่นที่ทำงานกับสตริงได้
t3chb0t

4
@ t3chb0t รู้สึกอิสระที่จะปรับให้เข้ากับความต้องการของคุณ วิธีที่นำเสนอในที่นี้ได้รับการปรับให้เป็นของเรา นี่ไม่ใช่ API สาธารณะ;)
andrew.fox

1
ตอนนี้คุณไม่ต้องส่ง 2 ตัวแปรไปยังอีกฝ่ายในการสื่อสารของคุณ (ซึ่งคุณกำลังส่งข้อมูลที่เข้ารหัส base64)? คุณต้องการส่งทั้งการเข้ารหัสที่ใช้และข้อมูล base64 จริงหรือไม่ มันง่ายกว่าไหมถ้าคุณใช้การประชุมทั้งสองด้านเพื่อใช้การเข้ารหัสเดียวกัน ด้วยวิธีนี้คุณเพียงแค่ต้องส่งข้อมูล base64 ใช่ไหม
Mladen B.

38

จากคำตอบของ Andrew Fox และ Cebe ฉันหันไปหามันและทำให้มันเป็นนามสกุลของสตริงแทน Base64String extension

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
ฉันจะเพิ่ม ParseBase64 (ข้อความสตริงนี้, การเข้ารหัส, ออกสตริง 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;   
            }
        }
    }
}

13

คุณสามารถใช้รูทีนด้านล่างเพื่อแปลงสตริงเป็นรูปแบบ base64

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

นอกจากนี้คุณสามารถใช้OnlineUtility.inเครื่องมือออนไลน์ที่ดีมากในการเข้ารหัสสตริงในรูปแบบ base64


เครื่องมือออนไลน์ไม่ได้ช่วยในสถานการณ์เช่นนี้เขากำลังถามว่าจะใช้รหัสอย่างไร ฉันมักจะสงสัยว่าทำไมผู้คนถึงพูดว่า "ลองใช้เครื่องมือออนไลน์นี้!" เพราะ OP ไม่ขอเครื่องมือออนไลน์: 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);
        }
    }

การใช้

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

1
คำถามไม่ได้เกี่ยวกับการเข้ารหัส URL แต่ก็มีประโยชน์ ..
Momoro

อ๊ะโพสต์ไว้ในคำถามที่ผิด
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)");

ฉันหวังว่านี่จะช่วยได้!


1

สำหรับผู้ที่เพียงต้องการเข้ารหัส / ถอดรหัสแต่ละเบส 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;
}

มีBase64 หลายรุ่นที่ไม่เห็นด้วยกับสิ่งที่จะใช้กับตัวเลข 62 และ 63 ดังนั้นDecodeBase64Digitสามารถทนได้หลายอย่าง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.