ToolDeck

ถอดรหัส Base64 ใน C# — คู่มือ

·Game Developer & Unity Engineer·ตรวจสอบโดยEmma Richardson·เผยแพร่เมื่อ

ใช้ ถอดรหัส Base64 ออนไลน์ ฟรีโดยตรงในเบราว์เซอร์ของคุณ — ไม่ต้องติดตั้ง

ลอง ถอดรหัส Base64 ออนไลน์ ออนไลน์ →

โปรเจกต์ .NET แทบทุกโปรเจกต์ที่ผมเคยทำล้วนต้องการถอดรหัส Base64 ในที่สุด — ไม่ว่าจะเป็นการดึง connection string จาก Kubernetes secrets, การอ่าน binary payload จาก webhook, หรือการตรวจสอบ JWT token ระหว่าง debug session เมธอดหลักในการถอดรหัส Base64 ใน C# คือ Convert.FromBase64String() ซึ่งคืน byte[] ที่นำไปส่งต่อให้ Encoding.UTF8.GetString() เพื่อให้ได้ text ที่อ่านได้ สำหรับการตรวจสอบเร็ว ๆ โดยไม่ต้องเขียนโค้ด Base64 decoder ของ ToolDeck จัดการได้ทันทีในเบราว์เซอร์ คู่มือนี้ครอบคลุม Convert.FromBase64String(),TryFromBase64String() แบบ span-based สำหรับ .NET 5+, API ประสิทธิภาพสูง System.Buffers.Text.Base64, การแยก JWT payload, การถอดรหัสไฟล์และ API response, การ streaming ด้วย CryptoStream และข้อผิดพลาด 4 อย่างที่นักพัฒนา C# มักพบบ่อยที่สุด

  • Convert.FromBase64String(s) + Encoding.UTF8.GetString(bytes) คือ pipeline มาตรฐานสองขั้นตอน — ใช้งานได้กับทุกเวอร์ชัน .NET
  • Convert.TryFromBase64String() หลีกเลี่ยง exception กับ input ไม่ถูกต้องและเขียนลงใน Span<byte> — เหมาะสำหรับ hot path บน .NET 5+
  • System.Buffers.Text.Base64.DecodeFromUtf8() ให้การถอดรหัสแบบ zero-allocation สำหรับ UTF-8 byte buffer ใน service ที่ต้องการประสิทธิภาพสูง
  • JWT token ใช้ Base64url (- และ _ แทน + และ /) — ต้อง normalize input ก่อนเรียก Convert.FromBase64String()
  • CryptoStream กับ FromBase64Transform รองรับการถอดรหัสแบบ streaming สำหรับไฟล์ขนาดใหญ่โดยไม่ต้องโหลดทั้งหมดลงในหน่วยความจำ

การถอดรหัส Base64 คืออะไร?

Base64 encoding แปลง binary data เป็น alphabet 64 ตัวอักษร ASCII เพื่อให้ผ่านช่องทาง text-only ได้อย่างปลอดภัย — JSON field, HTTP header, email body, XML attribute ทุก 3 byte ของ input กลายเป็น 4 ตัวอักษร Base64 ซึ่งเป็นเหตุผลที่ output ของ Base64 ใหญ่กว่าต้นฉบับประมาณ 33% เสมอ การถอดรหัสคือการย้อนกระบวนการนี้ อักษร = ที่ท้ายบอก decoder ว่าต้องตัด byte กี่ตัวออกจาก group สุดท้าย= ตัวเดียวหมายความว่า block สุดท้ายมี 2 bytes; == หมายความว่ามี 1 byte Base64 ไม่ใช่การเข้ารหัส — ทุกคนสามารถย้อนกลับได้ จุดประสงค์คือการขนส่งข้อมูลอย่างปลอดภัยผ่านช่องทางที่จัดการ binary ดิบไม่ได้ ไม่ใช่ความลับ

Before · text
After · text
cmVkaXM6Ly9jYWNoZS1wcm9kLmludGVybmFsOjYzNzkvc2Vzc2lvbi1zdG9yZQ==
redis://cache-prod.internal:6379/session-store

Convert.FromBase64String() — เมธอดถอดรหัสมาตรฐาน

เมธอด Convert.FromBase64String() อยู่ใน .NET มาตั้งแต่สมัย Framework 1.1 ไม่ต้องติดตั้ง NuGet ไม่ต้อง import อะไรนอกจาก System — แค่เรียกและรับ byte[] กลับมา pipeline สองขั้นตอนสำหรับถอดรหัส Base64 เป็น C# string เหมือนกันเสมอ: Convert.FromBase64String() เพื่อรับ bytes แล้ว Encoding.UTF8.GetString() เพื่อตีความ bytes เหล่านั้นเป็น text ข้อที่ต้องระวังคือเมธอดนี้คืน raw bytes ไม่ใช่ string คุณต้องเลือก Encoding ที่ถูกต้องเพื่อแปลง bytes เหล่านั้นกลับเป็น text และการเลือกนั้นสำคัญกว่าที่คิด การใช้ encoding ที่ไม่ตรงจะผลิต mojibake — ตัวอักษรที่เสียหายโดยไม่มี exception แจ้งเตือน

ตัวอย่างขั้นต่ำที่ใช้งานได้

C# (.NET 6+)
using System;
using System.Text;

// Connection string เก็บเป็น Base64 ใน Kubernetes secret
string encoded = "cmVkaXM6Ly9jYWNoZS1wcm9kLmludGVybmFsOjYzNzkvc2Vzc2lvbi1zdG9yZQ==";

byte[] decodedBytes = Convert.FromBase64String(encoded);
string connectionString = Encoding.UTF8.GetString(decodedBytes);

Console.WriteLine(connectionString);
// redis://cache-prod.internal:6379/session-store

ใช้ Encoding.UTF8 เสมอ เว้นแต่มีเหตุผลเฉพาะ .NET runtime แทน string ภายในเป็น UTF-16 แต่ข้อมูลส่วนใหญ่ที่ผ่านขอบเขตระบบ (API response, config file, secret) encode เป็น UTF-8 การใช้ Encoding.ASCII กับข้อมูลที่มีตัวอักษรหลายไบต์จะแทนที่ด้วย ? โดยไม่มี exception — แค่ output ที่เสียหาย

การตรวจสอบแบบ round-trip

C# (.NET 6+)
using System;
using System.Text;

string original = "postgres://db-admin:Kx8!mQ@db-prod.us-east-1.internal:5432/orders";

// Encode
string encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(original));
Console.WriteLine(encoded);
// cG9zdGdyZXM6Ly9kYi1hZG1pbjpLeDghbVFAZGItcHJvZC51cy1lYXN0LTEuaW50ZXJuYWw6NTQzMi9vcmRlcnM=

// Decode
byte[] decoded = Convert.FromBase64String(encoded);
string recovered = Encoding.UTF8.GetString(decoded);

Console.WriteLine(recovered == original); // True

การเลือก Encoding ที่เหมาะสม

Encoding ที่ส่งให้ GetString() ต้องตรงกับที่ใช้ ตอน encode ข้อมูลต้นฉบับ เลือกผิดแล้วจะได้ตัวอักษรขยะโดยไม่มี exception — decoder ผลิต nonsense ออกมาอย่างสุขใจ นี่คือสรุปในทางปฏิบัติ:

  • Encoding.UTF8 — ค่าเริ่มต้นที่ปลอดภัย รองรับ ASCII และ Unicode ทั้งหมด ใช้นี้ถ้าไม่แน่ใจ
  • Encoding.ASCII — สำหรับข้อมูล 7-bit ASCII บริสุทธิ์เท่านั้น ตัวอักษรหลายไบต์จะกลายเป็น ?
  • Encoding.Unicode — คือ UTF-16LE ใน .NET บาง string ภายใน Windows และ PowerShell exports ใช้สิ่งนี้
  • Encoding.Latin1 — encoding ยุโรปตะวันตกแบบ legacy พบในบริการ SOAP เก่าและระบบ mainframe
C# (.NET 6+)
using System;
using System.Text;

// Bytes เดียวกัน, encoding ต่างกัน — ผลลัพธ์ต่างกัน
byte[] decoded = Convert.FromBase64String("w7bDvMOk");

Console.WriteLine(Encoding.UTF8.GetString(decoded));    // öüä  (ถูกต้อง)
Console.WriteLine(Encoding.ASCII.GetString(decoded));   // ??????  (สูญหาย)
Console.WriteLine(Encoding.Latin1.GetString(decoded));  // öüä  (mojibake)

decode helper ที่ใช้ซ้ำได้พร้อม error handling

เนื่องจาก Convert.FromBase64String() โยน exception กับ input ไม่ถูกต้อง และการลบ whitespace เกิดขึ้นบ่อย ผมจึงเก็บ helper เล็ก ๆ ไว้ในโปรเจกต์ส่วนใหญ่:

C# (.NET 6+)
using System;
using System.Text;

static class Base64Helper
{
    public static string? DecodeToString(string encoded)
    {
        if (string.IsNullOrWhiteSpace(encoded))
            return null;

        // ลบ whitespace ที่ decoder ของ .NET ปฏิเสธ
        string cleaned = encoded
            .Replace("
", "")
            .Replace("
", "")
            .Replace(" ", "")
            .Trim();

        try
        {
            byte[] bytes = Convert.FromBase64String(cleaned);
            return Encoding.UTF8.GetString(bytes);
        }
        catch (FormatException)
        {
            return null; // หรือโยน domain-specific exception
        }
    }
}

// การใช้งาน
string? decoded = Base64Helper.DecodeToString("  cmVkaXM6Ly9jYWNoZQ==  \n");
Console.WriteLine(decoded); // redis://cache
หมายเหตุ:Convert.FromBase64String() โยน FormatException ถ้า input มีตัวอักษรที่ไม่อยู่ใน Base64 alphabet — รวมถึง space, newline และตัวอักษร URL-safe อย่าง - และ _ helper ข้างต้น จัดการ whitespace โดยอัตโนมัติ

การถอดรหัส Base64 เป็น Type ที่ไม่ใช่มาตรฐาน

decoder มักคืน byte[] เสมอ สิ่งที่ทำกับ bytes เหล่านั้น ขึ้นอยู่กับข้อมูลต้นฉบับ บางครั้งเป็น GUID เก็บเป็น 16 raw bytes บางครั้งเป็น protobuf message ที่ serialize แล้ว บางครั้งเป็น timestamp ในรูปแบบ binary นี่คือการแปลงที่ผมใช้บ่อยที่สุด

Base64 เป็น GUID

C# (.NET 6+)
using System;

// บาง API ส่ง GUID เป็น Base64 ขนาด 22 ตัวอักษรแทน hex string 36 ตัวอักษร
string compactGuid = "C0HqetxMckKlZw4CssPUeQ==";
byte[] guidBytes = Convert.FromBase64String(compactGuid);
Guid recovered = new Guid(guidBytes);

Console.WriteLine(recovered);
// 7aea41c0-4cdc-4272-a567-0e02b2c3d479

Base64 เป็น deserialized JSON ด้วย System.Text.Json

C# (.NET 6+)
using System;
using System.Text;
using System.Text.Json;

// JSON payload ที่ encode เป็น Base64 จาก message queue
string encoded = "eyJzZXJ2aWNlIjoicGF5bWVudC1nYXRld2F5IiwicmVnaW9uIjoiZXUtd2VzdC0xIiwicmVwbGljYXMiOjR9";

byte[] jsonBytes = Convert.FromBase64String(encoded);
string json = Encoding.UTF8.GetString(jsonBytes);
Console.WriteLine(json);
// {"service":"payment-gateway","region":"eu-west-1","replicas":4}

// Deserialize เป็น record
var deployEvent = JsonSerializer.Deserialize<DeployEvent>(jsonBytes);
Console.WriteLine($"{deployEvent!.Service} in {deployEvent.Region}");
// payment-gateway in eu-west-1

record DeployEvent(string Service, string Region, int Replicas);

Base64 เป็น hex string

C# (.NET 5+)
using System;

// SHA-256 hash เก็บเป็น Base64
string hashBase64 = "n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg=";
byte[] hashBytes = Convert.FromBase64String(hashBase64);
string hex = Convert.ToHexString(hashBytes);

Console.WriteLine(hex);
// 9F86D081884C7D659A2FEAA0C55AD015A3BF4F1B2B0B822CD15D6C15B0F00A08
คำเตือน:อย่า deserialize ข้อมูล Base64 ที่ไม่น่าไว้ใจโดยใช้ BinaryFormatterมันมีช่องโหว่ remote code execution ที่เป็นที่รู้จักและถูกยกเลิกใน .NET 8+ ถ้า content ที่ encode มาจากแหล่งภายนอก ให้ parse เป็น JSON หรือ protobuf แทนการใช้ .NET binary serialization

อ้างอิงเมธอดถอดรหัส Base64

.NET มีเมธอดถอดรหัสหลายตัวใน namespace สองแห่ง คลาส Convert รองรับการถอดรหัสทั่วไป ส่วน System.Buffers.Text.Base64 เน้น scenario ที่มีปริมาณงานสูง ที่คุณกำลังทำงานกับ raw UTF-8 byte buffer อยู่แล้ว

เมธอด
ค่าที่คืน
ประเภท Input
คำอธิบาย
Convert.FromBase64String(string)
byte[]
string
ถอดรหัส Base64 string มาตรฐานเป็น byte array; โยน FormatException เมื่อ input ไม่ถูกต้อง
Convert.TryFromBase64String(string, Span<byte>, out int)
bool
string + Span<byte>
พยายามถอดรหัสลงใน Span ที่ผู้เรียกจัดสรรไว้; คืน false เมื่อล้มเหลวแทนการโยน exception (.NET 5+)
Convert.FromBase64CharArray(char[], int, int)
byte[]
char[] + offset + length
ถอดรหัสส่วนหนึ่งของ char array; มีประโยชน์สำหรับ parse buffer โดยไม่ต้องสร้าง substring
Convert.TryFromBase64Chars(ReadOnlySpan<char>, Span<byte>, out int)
bool
ReadOnlySpan<char> + Span<byte>
ถอดรหัสแบบ Span-based ไม่มี allocation จาก char span (.NET 5+)
System.Buffers.Text.Base64.DecodeFromUtf8(ROSpan<byte>, Span<byte>, out int, out int, bool)
OperationStatus
ReadOnlySpan<byte> + Span<byte>
ถอดรหัส byte แบบ UTF-8 ประสิทธิภาพสูง; คืน enum OperationStatus (.NET Core 2.1+)
System.Buffers.Text.Base64.DecodeFromUtf8InPlace(Span<byte>, out int)
OperationStatus
Span<byte>
ถอดรหัสใน buffer เดิม ไม่ต้องจัดสรรหน่วยความจำเพิ่ม (.NET Core 2.1+)

Convert.TryFromBase64String() — การถอดรหัสแบบไม่โยน Exception

Pattern Try เป็นมาตรฐานใน .NET สำหรับ operation ที่อาจล้มเหลว กับ user input Convert.TryFromBase64String() ที่มีมาตั้งแต่ .NET 5 คืน bool แทนการโยน FormatException มันเขียน decoded bytes ลงใน Span<byte> ที่ผู้เรียกจัดเตรียมไว้ ซึ่งหมายความว่า คุณสามารถใช้หน่วยความจำบน stack สำหรับ payload ขนาดเล็กและข้าม heap ได้เลย

C# (.NET 5+)
using System;
using System.Text;

string userInput = "eyJob3N0IjoiMTAuMC4xLjUwIiwicG9ydCI6ODQ0M30=";

// Stack-allocate สำหรับ payload ขนาดเล็ก (< 1KB เป็น rule of thumb ที่ดี)
Span<byte> buffer = stackalloc byte[256];

if (Convert.TryFromBase64String(userInput, buffer, out int bytesWritten))
{
    string result = Encoding.UTF8.GetString(buffer[..bytesWritten]);
    Console.WriteLine(result);
    // {"host":"10.0.1.50","port":8443}
}
else
{
    Console.WriteLine("Invalid Base64 input — skipping");
}

วิธีนี้เหมาะมากสำหรับ request middleware หรือ validation pipeline ที่ input ไม่ถูกต้องเป็นเรื่องปกติ ไม่ใช่ exception การโยนและรับ FormatException ทุก request ที่มีรูปแบบผิดเพิ่ม overhead ที่วัดได้ที่ scale — TryFromBase64String() หลีกเลี่ยงได้ทั้งหมด

การ validate input Base64 โดยไม่ต้องถอดรหัส

pattern ที่พบบ่อยใน API controller: ตรวจสอบว่า input เป็น Base64 ถูกต้อง ก่อนส่งต่อ downstream คุณใช้ TryFromBase64String() เป็น validator ได้โดยจัดสรร buffer ทิ้ง:

C# (.NET 5+)
using System;

static bool IsValidBase64(string input)
{
    // คำนวณขนาดสูงสุดที่ decode แล้ว
    Span<byte> buffer = stackalloc byte[((input.Length + 3) / 4) * 3];
    return Convert.TryFromBase64String(input, buffer, out _);
}

// การใช้งานใน API controller
Console.WriteLine(IsValidBase64("eyJob3N0IjoiMTAuMC4xLjUwIn0=")); // True
Console.WriteLine(IsValidBase64("not!!valid!!base64"));              // False
Console.WriteLine(IsValidBase64(""));                                // True (ว่างคือ valid)
หมายเหตุ:output buffer ต้องมีขนาดใหญ่พอ หาก buffer เล็กเกินไป TryFromBase64String() คืน false แม้ input จะถูกต้อง คำนวณขนาดที่ต้องการเป็น (inputLength / 4) * 3 เพื่อความปลอดภัย

ถอดรหัส Base64 จากไฟล์และ API Response

อ่านไฟล์ที่ encode เป็น Base64 จาก disk

Certificate, encrypted blob และไฟล์ export ข้อมูลบางครั้งส่งมาเป็น Base64 text pattern ปกติ: อ่านไฟล์เป็น string ลบ whitespace หรือ line break ที่จะทำให้เกิด FormatException ถอดรหัสเป็น bytes แล้วเขียน binary output ให้ใส่ใจ error handling — ข้อผิดพลาดจาก file I/O และ Base64 format ควร catch แยกกัน

C# (.NET 6+)
using System;
using System.IO;

string inputPath = "tls-cert.pem.b64";
string outputPath = "tls-cert.pem";

try
{
    string encoded = File.ReadAllText(inputPath).Trim();
    // ลบ line break — decoder ของ .NET ปฏิเสธ
    encoded = encoded.Replace("
", "").Replace("
", "");

    byte[] decoded = Convert.FromBase64String(encoded);
    File.WriteAllBytes(outputPath, decoded);

    Console.WriteLine($"Decoded {decoded.Length} bytes -> {outputPath}");
}
catch (IOException ex)
{
    Console.Error.WriteLine($"File error: {ex.Message}");
}
catch (FormatException ex)
{
    Console.Error.WriteLine($"Invalid Base64: {ex.Message}");
}

การถอดรหัส field Base64 จาก HTTP API response

Cloud API (Azure Key Vault, AWS Secrets Manager, GitHub Contents API) มักส่ง binary data เป็น Base64 string ฝังอยู่ใน JSON workflow เหมือนกันเสมอ: ทำ HTTP request, parse JSON response, แยก Base64 field แล้วถอดรหัส ตัวอย่างด้านล่างใช้ HttpClient และ System.Text.Json — ทั้งสองมีใน .NET 6+ แล้ว

C# (.NET 6+)
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer sk-prod-9f8e7d6c");

try
{
    var response = await client.GetAsync("https://api.example.com/secrets/db-password");
    response.EnsureSuccessStatusCode();

    string body = await response.Content.ReadAsStringAsync();

    // API ส่งกลับ: {"name":"db-password","value":"cG9zdGdyZXM6eGs5bVAycVI=","version":3}
    using var doc = JsonDocument.Parse(body);
    string encodedValue = doc.RootElement.GetProperty("value").GetString()!;

    byte[] decoded = Convert.FromBase64String(encodedValue);
    string secret = Encoding.UTF8.GetString(decoded);

    Console.WriteLine($"Secret: {secret}");
    // Secret: postgres:xk9mP2qR
}
catch (HttpRequestException ex)
{
    Console.Error.WriteLine($"HTTP error: {ex.Message}");
}
catch (FormatException ex)
{
    Console.Error.WriteLine($"Base64 decode failed: {ex.Message}");
}
หมายเหตุ:แยก block catch สำหรับ network error และ FormatException ออกจากกัน การรวมกันทำให้บอกไม่ได้ว่า API ส่งข้อมูลไม่ถูกต้องหรือ request ล้มเหลว ใน production ให้ log ค่า Base64 ดิบ (หรืออย่างน้อย length และ 20 ตัวอักษรแรก) ตอน catch FormatException — ช่วยให้ debug ได้ง่ายขึ้นมาก

การถอดรหัส Base64 จาก Command Line

ไม่จำเป็นต้องมีโปรเจกต์ที่ compile แล้วเสมอ เครื่องมือ dotnet-script และ PowerShell รองรับการถอดรหัส Base64 ด้วย one-liner สำหรับการตรวจสอบเร็ว ๆ ระหว่าง debug วิธีเหล่านี้เร็วกว่าการสร้าง console app

bash
# PowerShell (ติดตั้งมาใน Windows, ใช้ได้บน Linux/macOS ด้วย)
[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("eyJob3N0IjoiMTAuMC4xLjUwIn0="))
# {"host":"10.0.1.50"}

# คำสั่ง base64 ของ Linux / macOS
echo "eyJob3N0IjoiMTAuMC4xLjUwIn0=" | base64 --decode
# {"host":"10.0.1.50"}

# macOS ใช้ -D แทน --decode
echo "eyJob3N0IjoiMTAuMC4xLjUwIn0=" | base64 -D

# dotnet-script (ติดตั้ง: dotnet tool install -g dotnet-script)
echo 'Console.WriteLine(System.Text.Encoding.UTF8.GetString(Convert.FromBase64String("eyJob3N0IjoiMTAuMC4xLjUwIn0=")));' | dotnet-script eval

# Decode และ pretty-print JSON ด้วย jq
echo "eyJob3N0IjoiMTAuMC4xLjUwIiwicG9ydCI6ODQ0M30=" | base64 --decode | jq .

สำหรับการวาง encoded string ลงในเบราว์เซอร์โดยตรง Base64 decoder ของ ToolDeck รองรับทั้ง standard และ URL-safe variant โดยไม่ต้องตั้งค่าอะไร

ทางเลือกประสิทธิภาพสูง: System.Buffers.Text.Base64

คลาส System.Buffers.Text.Base64 ที่มีมาตั้งแต่ .NET Core 2.1 ทำงานบน raw UTF-8 byte span แทน .NET string วิธีนี้ข้าม overhead ของการแปลง string-to-byte ทั้งหมด — ไม่มี string allocation กลาง, ไม่มีขั้นตอน UTF-16 encoding ผมใช้มันใน ASP.NET Core middleware ที่ข้อมูลขาเข้าเป็น ReadOnlySpan<byte> จาก request body อยู่แล้ว การสร้าง string แค่เพื่อส่งให้ Convert.FromBase64String() เพิ่ม allocation เป็นสองเท่าโดยไม่จำเป็น ใน BenchmarkDotNet test บน .NET 8 path แบบ span-based เร็วกว่าประมาณ 2-3 เท่าสำหรับ payload ขนาดต่ำกว่า 1 KB และช่องว่างยิ่งกว้างขึ้นกับ input ขนาดใหญ่เพราะ GC pressure ไม่เพิ่ม

C# (.NET 6+)
using System;
using System.Buffers.Text;
using System.Text;

// จำลอง raw UTF-8 bytes จาก HTTP request body
byte[] utf8Input = Encoding.UTF8.GetBytes("eyJob3N0IjoiMTAuMC4xLjUwIiwicG9ydCI6ODQ0M30=");

byte[] output = new byte[Base64.GetMaxDecodedFromUtf8Length(utf8Input.Length)];

OperationStatus status = Base64.DecodeFromUtf8(
    utf8Input, output, out int bytesConsumed, out int bytesWritten);

if (status == OperationStatus.Done)
{
    string result = Encoding.UTF8.GetString(output.AsSpan(0, bytesWritten));
    Console.WriteLine(result);
    // {"host":"10.0.1.50","port":8443}
    Console.WriteLine($"Consumed: {bytesConsumed}, Written: {bytesWritten}");
    // Consumed: 44, Written: 31
}
else
{
    Console.WriteLine($"Decode failed: {status}");
    // ค่าที่เป็นไปได้: InvalidData, DestinationTooSmall, NeedMoreData
}

ค่าที่คืนคือ OperationStatus — enum สี่ค่า: Done, InvalidData, DestinationTooSmall, และ NeedMoreData ค่าสุดท้ายมีประโยชน์สำหรับการถอดรหัสบางส่วน ของข้อมูล streaming สำหรับ zero allocation อย่างแท้จริง ใช้คู่กับ ArrayPool<byte>.Shared.Rent() แทน new byte[]

DecodeFromUtf8InPlace — เขียนทับ input buffer

C# (.NET 6+)
using System;
using System.Buffers.Text;
using System.Text;

// input buffer จะถูกเขียนทับด้วย decoded bytes
byte[] data = Encoding.UTF8.GetBytes("c2VydmVyLWNvbmZpZw==");

OperationStatus status = Base64.DecodeFromUtf8InPlace(data, out int bytesWritten);

if (status == OperationStatus.Done)
{
    Console.WriteLine(Encoding.UTF8.GetString(data.AsSpan(0, bytesWritten)));
    // server-config
}
หมายเหตุ:DecodeFromUtf8InPlace แก้ไข input buffer ห้ามใช้ถ้าต้องการ Base64 string เดิมภายหลัง — bytesWritten ไบต์แรกของ array ตอนนี้มี decoded data แล้ว และส่วนที่เหลือคือ garbage

สิ่งที่ต้องระวัง: System.Buffers.Text.Base64 ไม่รองรับ URL-safe Base64 โดยตรง ถ้า input ใช้ตัวอักษร - และ _ (JWT token เป็นต้น) คุณยังต้องแทนด้วย + และ / ก่อนเรียกเมธอดเหล่านี้ span-based API ใช้ alphabet มาตรฐาน RFC 4648 เท่านั้น ไม่มี variant DecodeFromUtf8Url — ช่องว่างที่น่าแปลกใจเมื่อ Base64url พบได้ทั่วไปใน API สมัยใหม่

Terminal Output พร้อม Syntax Highlighting

ไลบรารี Spectre.Console ให้ terminal output ที่หลากหลาย รวมถึง JSON highlighting — มีประโยชน์เมื่อสร้าง CLI tool ที่ถอดรหัส Base64 และแสดงผลลัพธ์ ติดตั้งด้วย dotnet add package Spectre.Console

C# (.NET 6+)
using System;
using System.Text;
using Spectre.Console;
using Spectre.Console.Json;

string encoded = "eyJob3N0IjoiMTAuMC4xLjUwIiwicG9ydCI6ODQ0MywibWF4Q29ubiI6MTAwfQ==";
byte[] decoded = Convert.FromBase64String(encoded);
string json = Encoding.UTF8.GetString(decoded);

// Pretty-print พร้อม syntax highlighting ใน terminal
AnsiConsole.Write(new JsonText(json));
// แสดง JSON สีสัน:
// {
//   "host": "10.0.1.50",
//   "port": 8443,
//   "maxConn": 100
// }

สิ่งนี้มีประโยชน์เป็นพิเศษสำหรับ CLI tool ที่ดึงและถอดรหัส config จาก remote service ถอดรหัส Base64 config, deserialize เป็น JSON และแสดง output ที่มี highlight — ทั้งหมดในไม่กี่บรรทัด Spectre.Console ยังมี table rendering, progress bar และ tree view ถ้าต้องการแสดง decoded data structure ที่ซับซ้อนขึ้นใน terminal

คำเตือน:output ของ Spectre.Console มี ANSI escape sequence อย่า pipe ลงไฟล์ หรือคืนจาก API — ใช้สำหรับแสดงใน terminal เท่านั้น

Streaming ไฟล์ Base64 ขนาดใหญ่ด้วย CryptoStream

การโหลดไฟล์ Base64 ขนาด 500 MB ด้วย File.ReadAllText() แล้วเรียก Convert.FromBase64String() จะใช้ heap ประมาณ 700 MB: ตัว string เอง (UTF-16 ดังนั้นสองเท่าของขนาดไฟล์) บวกกับ decoded byte array การรวม CryptoStream + FromBase64Transform ถอดรหัสทีละ chunk ทำให้การใช้หน่วยความจำคงที่

C# (.NET 6+)
using System.IO;
using System.Security.Cryptography;

string inputPath = "database-export.sql.b64";
string outputPath = "database-export.sql";

using var inputStream = new FileStream(inputPath, FileMode.Open, FileAccess.Read);
using var transform = new FromBase64Transform(FromBase64TransformMode.IgnoreWhiteSpaces);
using var base64Stream = new CryptoStream(inputStream, transform, CryptoStreamMode.Read);
using var outputStream = new FileStream(outputPath, FileMode.Create, FileAccess.Write);

base64Stream.CopyTo(outputStream);

Console.WriteLine($"Decoded {new FileInfo(outputPath).Length} bytes -> {outputPath}");

flag FromBase64TransformMode.IgnoreWhiteSpaces รองรับ Base64 ที่มีการตัดบรรทัด (PEM file, email export) โดยไม่ต้องทำความสะอาดด้วยตนเอง ถ้าไม่มี flag นี้ line break ใน input ทำให้เกิด FormatExceptionนี่คือสิ่งที่ใกล้เคียงที่สุดกับ getMimeDecoder() ของ Java ใน .NET — มันข้าม whitespace ระหว่างถอดรหัสโดยอัตโนมัติ

ชื่อ CryptoStream อาจทำให้เข้าใจผิด — ไม่มีอะไรเกี่ยวกับ cryptography ใน Base64 Microsoft ใส่ FromBase64Transform ใน namespace System.Security.Cryptography เพราะมัน implement ICryptoTransform ซึ่งเป็น interface เดียวกับที่ AES และ cipher transform อื่น ๆ ใช้ ตัว stream เองแค่ส่งข้อมูลผ่าน transform ใด ๆ ทีละ chunk คิดว่ามันเป็น streaming transform pipeline แบบทั่วไปที่อยู่ใน namespace ไม่ถูกต้อง

Async streaming สำหรับ ASP.NET Core

C# (.NET 6+)
using System.IO;
using System.Security.Cryptography;

async Task DecodeStreamAsync(Stream inputStream, string outputPath)
{
    using var transform = new FromBase64Transform(FromBase64TransformMode.IgnoreWhiteSpaces);
    using var base64Stream = new CryptoStream(inputStream, transform, CryptoStreamMode.Read);
    await using var outputStream = new FileStream(
        outputPath, FileMode.Create, FileAccess.Write, FileShare.None,
        bufferSize: 81920, useAsync: true);

    await base64Stream.CopyToAsync(outputStream);
}

// การใช้งานใน endpoint:
// await DecodeStreamAsync(Request.Body, "uploaded-file.bin");
หมายเหตุ:เปลี่ยนจาก CopyTo เป็น CopyToAsync ใน ASP.NET Core handler Synchronous I/O บน request thread ถูก block โดยค่าเริ่มต้นใน Kestrel และโยน InvalidOperationException

วิธีถอดรหัส JWT Token Payload แบบ Base64 ใน C#

JWT มี segment ที่ encode แบบ Base64url สามส่วนคั่นด้วยจุด segment กลางคือ payload คุณถอดรหัสได้โดยไม่ต้องใช้ JWT library — แยกด้วย ., normalize ตัวอักษร Base64url, แก้ padding แล้วเรียก Convert.FromBase64String()สิ่งนี้ทำให้เกือบทุกคนสะดุดครั้งแรก เพราะ JWT ใช้ - และ _ แทน + และ / และตัด padding = ออก

C# (.NET 6+)
using System;
using System.Text;

static string DecodeJwtPayload(string token)
{
    string[] parts = token.Split('.');
    if (parts.Length != 3)
        throw new ArgumentException($"Invalid JWT: expected 3 segments, got {parts.Length}");

    // นำ payload (segment ที่สอง)
    string payload = parts[1];

    // แทนตัวอักษร URL-safe ด้วย Base64 มาตรฐาน
    payload = payload.Replace('-', '+').Replace('_', '/');

    // เติม padding ให้เป็นจำนวนคูณ 4
    switch (payload.Length % 4)
    {
        case 2: payload += "=="; break;
        case 3: payload += "=";  break;
    }

    byte[] bytes = Convert.FromBase64String(payload);
    return Encoding.UTF8.GetString(bytes);
}

// ทดสอบด้วย token จริง
string token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9"
    + ".eyJzdWIiOiJ1c3ItNjcyIiwiaXNzIjoiYXV0aC5leGFtcGxlLmNvbSIsImV4cCI6MTc0MTk1NjgwMCwicm9sZXMiOlsiYWRtaW4iLCJiaWxsaW5nIl19"
    + ".SIGNATURE_PLACEHOLDER";

Console.WriteLine(DecodeJwtPayload(token));
// {"sub":"usr-672","iss":"auth.example.com","exp":1741956800,"roles":["admin","billing"]}

หมายเหตุสั้น ๆ: วิธีนี้แค่อ่าน payload ไม่ได้ verify signature สำหรับการ validate auth ใน production ใช้ library ที่เหมาะสมเช่น Microsoft.IdentityModel.JsonWebTokens แต่สำหรับ debug, log และ test assertion วิธี manual นี้เพียงพอแล้ว

การ parse decoded JWT payload เป็น typed object

เมื่อได้ JSON string แล้ว ให้ deserialize ด้วย System.Text.Json เพื่อเข้าถึง claim แต่ละรายการโดยไม่ต้องจัดการ string:

C# (.NET 6+)
using System;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;

record JwtPayload(
    [property: JsonPropertyName("sub")] string Subject,
    [property: JsonPropertyName("iss")] string Issuer,
    [property: JsonPropertyName("exp")] long Expiration,
    [property: JsonPropertyName("roles")] string[] Roles
);

// หลังจาก DecodeJwtPayload() ด้านบน
string json = DecodeJwtPayload(token);
var claims = JsonSerializer.Deserialize<JwtPayload>(json)!;

Console.WriteLine($"User: {claims.Subject}");
Console.WriteLine($"Issuer: {claims.Issuer}");
Console.WriteLine($"Expires: {DateTimeOffset.FromUnixTimeSeconds(claims.Expiration):u}");
Console.WriteLine($"Roles: {string.Join(", ", claims.Roles)}");
// User: usr-672
// Issuer: auth.example.com
// Expires: 2025-03-14 12:00:00Z
// Roles: admin, billing

ข้อผิดพลาดที่พบบ่อย

ผมเคยพบข้อผิดพลาดเหล่านี้ทั้งหมดใน C# service ใน production สองอย่างแรก รับผิดชอบต่อ bug ส่วนใหญ่ที่เกี่ยวกับ Base64 ที่ผมเห็นใน code review แต่ละข้อดูชัดเจนเมื่อดูแยก แต่ง่ายที่จะพลาดเมื่อคุณกำลังทำฟีเจอร์ใหญ่ และการถอดรหัส Base64 เป็นเพียงขั้นตอนหนึ่งใน pipeline

ลืมลบ whitespace จาก input

ปัญหา: Base64 string ที่อ่านจาก config file, environment variable หรือ user input มักมี trailing newline Convert.FromBase64String() ปฏิเสธตัวอักษรใด ๆ ที่ไม่อยู่ใน Base64 alphabet รวมถึง \r\n

วิธีแก้: เรียก .Trim() หรือ .Replace() เพื่อลบ whitespace ก่อนถอดรหัส

Before · C#
After · C#
// Environment variable มี trailing newline
string encoded = Environment.GetEnvironmentVariable("DB_PASS_B64")!;
byte[] decoded = Convert.FromBase64String(encoded);
// FormatException: The input is not a valid Base-64 string
string encoded = Environment.GetEnvironmentVariable("DB_PASS_B64")!;
string cleaned = encoded.Replace("\n", "").Replace("\r", "").Trim();
byte[] decoded = Convert.FromBase64String(cleaned);
Console.WriteLine(Encoding.UTF8.GetString(decoded));
ใช้ Convert.FromBase64String() กับ URL-safe Base64

ปัญหา: JWT token และ API payload บางอย่างใช้ - และ _ (URL-safe alphabet) decoder มาตรฐานรองรับแค่ + และ / — มันโยน FormatException เมื่อพบตัวอักษร - ตัวแรก

วิธีแก้: แทน - ด้วย + และ _ ด้วย / ก่อนถอดรหัส และแก้ padding ด้วย

Before · C#
After · C#
// JWT payload — ใช้ URL-safe Base64
string payload = "eyJzdWIiOiJ1c3ItNjcyIn0";
byte[] decoded = Convert.FromBase64String(payload);
// FormatException
string payload = "eyJzdWIiOiJ1c3ItNjcyIn0";
payload = payload.Replace('-', '+').Replace('_', '/');
switch (payload.Length % 4)
{
    case 2: payload += "=="; break;
    case 3: payload += "="; break;
}
byte[] decoded = Convert.FromBase64String(payload);
Console.WriteLine(Encoding.UTF8.GetString(decoded));
// {"sub":"usr-672"}
แปลง binary data เป็น string

ปัญหา: การเรียก Encoding.UTF8.GetString() บน decoded bytes ของรูปภาพหรือ protobuf จะได้ garbage ยิ่งกว่านั้น การแปลง string นั้นกลับเป็น bytes จะทำให้ข้อมูลเสียหายโดยไม่มีเสียง เพราะ sequence UTF-8 ที่ไม่ถูกต้องจะถูกแทนที่

วิธีแก้: เก็บ binary data เป็น byte[] ตลอด pipeline เรียก GetString() เฉพาะเมื่อรู้ว่า content เป็น text

Before · C#
After · C#
byte[] decoded = Convert.FromBase64String(pngBase64);
string imageStr = Encoding.UTF8.GetString(decoded); // ทำให้ binary เสียหาย
File.WriteAllText("image.png", imageStr); // ไฟล์เสีย
byte[] decoded = Convert.FromBase64String(pngBase64);
// เขียน bytes โดยตรง — ไม่ต้องแปลงเป็น string
File.WriteAllBytes("image.png", decoded);
ไม่ระบุ encoding (ใช้ค่าเริ่มต้นของแพลตฟอร์ม)

ปัญหา: บาง .NET Framework API รุ่นเก่า default เป็น ANSI code page ของระบบ ซึ่งต่างกันระหว่างเครื่อง Windows server ที่มี code page 1252 และ Linux container ที่มี UTF-8 ผลิต string ต่างกันจาก bytes เดียวกัน

วิธีแก้: ระบุ Encoding.UTF8 อย่างชัดเจนเสมอ ไม่พึ่งพาค่าเริ่มต้นของแพลตฟอร์ม

Before · C#
After · C#
byte[] decoded = Convert.FromBase64String(encoded);
// Encoding.Default ต่างกันระหว่างแพลตฟอร์ม
string result = Encoding.Default.GetString(decoded);
byte[] decoded = Convert.FromBase64String(encoded);
string result = Encoding.UTF8.GetString(decoded);
// สม่ำเสมอทั้งบน Windows, Linux, macOS

การเปรียบเทียบเมธอด

.NET มีเมธอดถอดรหัส Base64 มากกว่าที่นักพัฒนาส่วนใหญ่ตระหนัก ตารางด้านล่าง ครอบคลุมตัวเลือกในตัวทุกตัวและทางเลือก third-party ที่พบบ่อยสองตัว คอลัมน์ "การจัดสรรหน่วยความจำ" สำคัญที่สุดสำหรับ service ที่มีปริมาณงานสูง — เมธอดที่จัดสรร byte[] ใหม่ทุกครั้งที่เรียกสร้างแรงกดดันต่อ GC ใน loop ที่เรียกถี่

เมธอด
การจัดสรรหน่วยความจำ
การจัดการข้อผิดพลาด
Streaming
Custom Types
ต้องติดตั้งเพิ่ม
Convert.FromBase64String()
New byte[]
FormatException
ไม่
ไม่
ไม่ (.NET Framework 1.1+)
Convert.TryFromBase64String()
Caller Span
คืน false
ไม่
ไม่
ไม่ (.NET 5+)
Convert.FromBase64CharArray()
New byte[]
FormatException
ไม่
ไม่
ไม่ (.NET Framework 1.1+)
Base64.DecodeFromUtf8()
Caller Span
OperationStatus
บางส่วน
ไม่
ไม่ (.NET Core 2.1+)
Base64.DecodeFromUtf8InPlace()
In-place
OperationStatus
ไม่
ไม่
ไม่ (.NET Core 2.1+)
CryptoStream + FromBase64Transform
Streaming buffer
Exception
ใช่
ไม่
ไม่ (.NET Framework 2.0+)
BouncyCastle Base64
New byte[]
Exception
ใช่
ไม่
ใช่ (NuGet)

สำหรับงานทั่วไป: Convert.FromBase64String() สำหรับ hot path ที่ validate user input: TryFromBase64String() สำหรับ ASP.NET Core middleware ที่ทำงานกับ raw request bytes: Base64.DecodeFromUtf8()สำหรับไฟล์ขนาดใหญ่: CryptoStream + FromBase64TransformBouncyCastle สมเหตุสมผลก็ต่อเมื่อมันอยู่ใน dependency tree ของคุณแล้ว สำหรับ cryptographic operation อื่น ๆ

สำหรับการตรวจสอบเร็ว ๆ โดยไม่ต้อง compile อะไร Base64 decoder ออนไลน์ เร็วกว่าการเขียน one-off console app

คำถามที่พบบ่อย

ถอดรหัส Base64 string เป็น text ใน C# ได้อย่างไร?

เรียก Convert.FromBase64String() เพื่อรับ byte array แล้วส่งไปที่ Encoding.UTF8.GetString() การ encoding ต้องตรงกับที่ใช้ตอน encode — UTF-8 เป็นค่าเริ่มต้นที่ปลอดภัยสำหรับระบบสมัยใหม่เกือบทั้งหมด หาก input อาจมี whitespace หรือขึ้นบรรทัดใหม่ ให้เรียก .Trim() หรือลบออกก่อนถอดรหัส

C# (.NET 6+)
using System;
using System.Text;

string encoded = "cG9zdGdyZXM6eGs5bVAycVI=";
byte[] bytes = Convert.FromBase64String(encoded);
string result = Encoding.UTF8.GetString(bytes);
Console.WriteLine(result);
// postgres:xk9mP2qR

Convert.FromBase64String() และ Convert.TryFromBase64String() ต่างกันอย่างไร?

FromBase64String() โยน FormatException เมื่อ input ไม่ถูกต้อง ส่วน TryFromBase64String() คืน bool และเขียนผลลัพธ์ลงใน Span<byte> ที่ผู้เรียกจัดเตรียมไว้ เหมาะสำหรับ hot path ที่ต้องการหลีกเลี่ยง overhead จาก exception TryFromBase64String() ต้องใช้ .NET 5 ขึ้นไป

C# (.NET 6+)
using System;

string input = "maybe-not-valid-base64!!";
Span<byte> buffer = stackalloc byte[256];

if (Convert.TryFromBase64String(input, buffer, out int written))
    Console.WriteLine($"Decoded {written} bytes");
else
    Console.WriteLine("Invalid Base64 input");

ถอดรหัส JWT payload แบบ Base64url ใน C# ได้อย่างไร?

แยก token ด้วยจุด เอา segment ที่สอง แทน - ด้วย + และ _ ด้วย / เติม padding ให้เป็นจำนวนคูณ 4 ด้วย = แล้วเรียก Convert.FromBase64String() JWT token ใช้ alphabet แบบ URL-safe ซึ่ง decoder มาตรฐานของ .NET ไม่รองรับโดยตรง

C# (.NET 6+)
string token = "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3ItNjcyIn0.SIG";
string payload = token.Split('.')[1];
payload = payload.Replace('-', '+').Replace('_', '/');
switch (payload.Length % 4)
{
    case 2: payload += "=="; break;
    case 3: payload += "="; break;
}
byte[] bytes = Convert.FromBase64String(payload);
Console.WriteLine(Encoding.UTF8.GetString(bytes));
// {"sub":"usr-672"}

เลือก Encoding ที่เหมาะสมสำหรับการถอดรหัส Base64 ใน C# ได้อย่างไร?

ใช้ Encoding.UTF8 เป็นค่าเริ่มต้น — รองรับ ASCII และ Unicode หลายไบต์ ใช้ Encoding.ASCII เฉพาะเมื่อมั่นใจว่าข้อมูลเป็น 7-bit ASCII บริสุทธิ์ ใช้ Encoding.Unicode (ซึ่งคือ UTF-16LE ใน .NET) เฉพาะเมื่อข้อมูลต้นฉบับ encode ด้วย UTF-16 ซึ่งพบได้กับ string ภายใน Windows และ PowerShell exports บางส่วน

ทำไม Convert.FromBase64String() จึงโยน FormatException?

มีสาเหตุที่พบบ่อย 3 อย่าง: input มี whitespace หรือขึ้นบรรทัดใหม่ (ลบออกก่อนถอดรหัส), input ใช้ตัวอักษร URL-safe เช่น - และ _ (แทนด้วย + และ / ตามลำดับ), หรือ padding หายไปหรือไม่ถูกต้อง (ความยาวรวมต้องเป็นคูณ 4 หลังเติม padding) ต่างจาก Java, .NET ไม่มี MIME decoder ในตัวที่รองรับ whitespace — คุณต้องทำความสะอาด input เองหรือใช้ CryptoStream กับ FromBase64Transform และ mode IgnoreWhiteSpaces

C# (.NET 6+)
// แก้ปัญหา whitespace
string cleaned = rawInput.Replace("\n", "").Replace("\r", "").Trim();
byte[] decoded = Convert.FromBase64String(cleaned);

สามารถถอดรหัส Base64 ขนาดใหญ่แบบ streaming ใน C# ได้หรือไม่?

ได้ ใช้ CryptoStream กับ FromBase64Transform จาก System.Security.Cryptography วิธีนี้ถอดรหัสทีละ chunk ขณะอ่าน ทำให้หน่วยความจำคงที่ไม่ว่าไฟล์จะใหญ่แค่ไหน ส่ง FromBase64TransformMode.IgnoreWhiteSpaces หาก input มีขึ้นบรรทัดใหม่ บน .NET 6+ ยังสามารถใช้ pattern IAsyncEnumerable กับ Base64.DecodeFromUtf8() สำหรับ chunked processing แบบ manual ได้ แต่ CryptoStream ง่ายกว่าสำหรับการถอดรหัสไฟล์ต่อไฟล์

C# (.NET 6+)
using System.IO;
using System.Security.Cryptography;

using var input = File.OpenRead("payload.b64");
using var transform = new FromBase64Transform();
using var cryptoStream = new CryptoStream(input, transform, CryptoStreamMode.Read);
using var output = File.Create("payload.bin");
cryptoStream.CopyTo(output);

เครื่องมือที่เกี่ยวข้อง

  • Base64 Encoder — encode text หรือ binary data เป็น Base64 ในเบราว์เซอร์ มีประโยชน์สำหรับสร้าง test fixture เพื่อวางใน C# unit test ของคุณ
  • JWT Decoder — decode และตรวจสอบ JWT ทั้งสาม segment พร้อมกัน พร้อม payload inspection ทีละ field — เร็วกว่าการเขียน C# helper เมื่อต้องการแค่อ่าน token
  • URL Decoder — ถอดรหัส URL-encoded string แบบ percent-decode มีประโยชน์เมื่อ API response ผสม Base64url data กับ query parameter แบบ percent-encoded
  • JSON Formatter — หลังจากถอดรหัส Base64 JWT payload หรือ API config แล้ว วาง JSON ที่นี่เพื่อ pretty-print และ validate โครงสร้าง
มีให้ในภาษาอื่นด้วย:JavaScriptPythonGoJava
AP
Alexei PetrovGame Developer & Unity Engineer

Alexei is a game developer who has shipped multiple titles using Unity and C#. He focuses on gameplay systems, runtime performance, and the serialisation and data-management patterns unique to game development. He writes about Unity scripting, C# async/await in game contexts, asset serialisation, binary data handling, and the intersection of game engineering and general software craftsmanship.

ER
Emma Richardsonผู้ตรวจสอบทางเทคนิค

Emma is a .NET developer and cloud engineer who builds production APIs and backend services with ASP.NET Core and Azure. She has worked on everything from microservice migrations to real-time SignalR applications. She writes about C# language features, the System.Text.Json and Newtonsoft.Json ecosystems, Azure integrations, and the architectural patterns that make .NET services scalable and maintainable.