C# Tips | 文字列処理:Base64デコード

C# C#
スポンサーリンク

はじめに 「Base64デコード」は“梱包されたデータを元に戻す”作業

前回の「Base64エンコード」は、
バイナリや文字列を「壊れにくい文字列」に梱包する話でした。

Base64デコードは、その逆です。

「Base64という梱包をほどいて、元のバイト列や文字列に戻す」

これが役割です。

業務では、例えば次のような場面で使われます。

  • 外部APIからBase64文字列で送られてきたファイルを元に戻す
  • JSONの中にBase64で埋め込まれたバイナリを復元する
  • トークンや署名の中身を確認するためにデコードしてみる

ここでは、C#でのBase64デコードを、
「仕組み → 文字列デコード → バイナリデコード → URLセーフ対応」
という流れで、初心者向けにかみ砕いて説明していきます。


Base64デコードの基本イメージ

エンコードとデコードは“きれいな往復”になっている

Base64エンコードとデコードの関係は、こうです。

  • 元データ(バイト列)
    → Base64エンコード
    → Base64文字列
  • Base64文字列
    → Base64デコード
    → 元データ(バイト列)

文字列を扱う場合は、さらにその前後に「エンコーディング」が入ります。

  • 文字列
    → エンコーディング(UTF-8など)
    → バイト列
    → Base64エンコード
    → Base64文字列
  • Base64文字列
    → Base64デコード
    → バイト列
    → エンコーディングで文字列に戻す

C#では、この「Base64部分」を Convert.FromBase64String が担当します。


C#での基本:Base64文字列 → 元の文字列に戻す

文字列として復元するユーティリティの完成形

まずは、「Base64文字列から元の文字列(UTF-8)に戻す」ユーティリティを作ってみます。

using System;
using System.Text;

public static class Base64Util
{
    public static string DecodeBase64ToString(string? base64)
    {
        if (string.IsNullOrWhiteSpace(base64))
        {
            return string.Empty;
        }

        byte[] bytes;

        try
        {
            bytes = Convert.FromBase64String(base64);
        }
        catch (FormatException)
        {
            // Base64として不正な文字列の場合
            return string.Empty;
        }

        string text = Encoding.UTF8.GetString(bytes);

        return text;
    }
}
C#

これを一つずつ分解していきます。


重要ポイント1:Convert.FromBase64String は「バイト列」に戻す

byte[] bytes = Convert.FromBase64String(base64);
C#

Convert.FromBase64String は、
Base64文字列を「元のバイト配列」に戻すメソッドです。

ここで返ってくるのはあくまで「バイト列」であって、
まだ「文字列」ではありません。

文字列として扱いたい場合は、
このあとにエンコーディングで文字列に戻す必要があります。


重要ポイント2:エンコーディングをエンコード側と揃える(UTF-8前提にする)

string text = Encoding.UTF8.GetString(bytes);
C#

ここがとても重要です。

Base64は「バイト列」をそのまま文字列化したものなので、
デコードした結果のバイト列を「どう解釈するか」は、
エンコード時のエンコーディングに依存します。

もしエンコード側が Encoding.UTF8.GetBytes(text) でバイト列を作っていたなら、
デコード側も Encoding.UTF8.GetString(bytes) で文字列に戻す必要があります。

業務で自分たちがエンコードもデコードも担当するなら、
「UTF-8で統一する」と決めてしまうのが一番安全です。


重要ポイント3:不正なBase64文字列への備え(例外処理)

try
{
    bytes = Convert.FromBase64String(base64);
}
catch (FormatException)
{
    return string.Empty;
}
C#

Convert.FromBase64String は、
渡された文字列がBase64として不正な場合、FormatException を投げます。

外部から受け取ったデータをデコードする場合、
「壊れている」「途中で切れている」「Base64じゃないものが来た」
といったケースは普通に起こり得ます。

業務ユーティリティとしては、

  • 例外をそのまま投げる
  • 空文字を返す
  • nullを返す
  • エラーコード付きの結果型を返す

など、プロジェクトの方針に合わせて決める必要があります。

ここでは「初心者向けで扱いやすい」という観点から、
不正なBase64の場合は空文字を返す実装にしています。


動作例で挙動を確認する

正しいBase64の場合

string original = "こんにちは";
string base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(original));

string decoded = Base64Util.DecodeBase64ToString(base64);

Console.WriteLine(original); // こんにちは
Console.WriteLine(base64);   // 例: 44GT44KT44Gr44Gh44Gv
Console.WriteLine(decoded);  // こんにちは
C#

エンコード → デコードで、元の文字列に戻っていることが分かります。

不正なBase64の場合

string invalid = "これはBase64ではない";

string decoded = Base64Util.DecodeBase64ToString(invalid);

Console.WriteLine(decoded); // ""
C#

このように、不正な文字列が来ても例外でアプリ全体が落ちることはなく、
ユーティリティ側で「空文字を返す」という方針にしています。


バイナリとして復元したい場合のユーティリティ

Base64 → バイト配列に戻すだけの版

文字列ではなく、「バイナリとして扱いたい」ケースも多いです。
例えば、ファイルの中身や画像データなどです。

その場合は、エンコーディングは不要で、
Base64 → バイト配列の変換だけを行います。

public static class Base64Util
{
    public static byte[] DecodeBase64ToBytes(string? base64)
    {
        if (string.IsNullOrWhiteSpace(base64))
        {
            return Array.Empty<byte>();
        }

        try
        {
            return Convert.FromBase64String(base64);
        }
        catch (FormatException)
        {
            return Array.Empty<byte>();
        }
    }
}
C#

これを使えば、例えばこんな処理が書けます。

string base64 = GetFromApi(); // APIからBase64文字列を受け取ったとする
byte[] data = Base64Util.DecodeBase64ToBytes(base64);

if (data.Length > 0)
{
    File.WriteAllBytes("output.bin", data);
}
C#

URLセーフBase64(Base64URL)のデコード

URLセーフBase64の復元手順

前回のBase64エンコードで触れた「URLセーフBase64」は、
+-/_ に置き換え、= を省略する形式でした。

デコードするときは、その逆をやります。

  1. -+ に戻す
  2. _/ に戻す
  3. 足りない = を補う(4の倍数になるまで)
  4. Convert.FromBase64String に渡す

ユーティリティとして書くと、こうなります。

using System;
using System.Text;

public static class Base64UrlUtil
{
    public static string DecodeBase64UrlToString(string? base64Url)
    {
        if (string.IsNullOrWhiteSpace(base64Url))
        {
            return string.Empty;
        }

        string base64 = base64Url
            .Replace("-", "+")
            .Replace("_", "/");

        int padding = 4 - (base64.Length % 4);
        if (padding is > 0 and < 4)
        {
            base64 = base64.PadRight(base64.Length + padding, '=');
        }

        byte[] bytes;

        try
        {
            bytes = Convert.FromBase64String(base64);
        }
        catch (FormatException)
        {
            return string.Empty;
        }

        return Encoding.UTF8.GetString(bytes);
    }
}
C#

JWTなど、Web系のトークンを扱うときに、このURLセーフBase64デコードがよく登場します。


業務ユーティリティとしてのまとめ方

入力と出力をはっきり分けたAPIにする

実務で使いやすくするには、
「何を渡して、何が返ってくるか」が明確なメソッドに分けておくとよいです。

例えば、次のような構成です。

public static class Base64Decoding
{
    // Base64文字列 → UTF-8文字列
    public static string ToStringUtf8(string? base64)
        => Base64Util.DecodeBase64ToString(base64);

    // Base64文字列 → バイト配列
    public static byte[] ToBytes(string? base64)
        => Base64Util.DecodeBase64ToBytes(base64);

    // URLセーフBase64 → UTF-8文字列
    public static string FromUrlToStringUtf8(string? base64Url)
        => Base64UrlUtil.DecodeBase64UrlToString(base64Url);
}
C#

呼び出し側は、

  • 「普通のBase64を文字列として復元したい」
  • 「Base64をバイナリとして復元したい」
  • 「URLセーフBase64を文字列として復元したい」

といった意図に応じて、メソッドを選べます。

例外をどう扱うかを“ユーティリティ側で決めておく”

Base64デコードは、外部入力を扱うことが多いので、
不正な文字列が来る可能性を常に意識する必要があります。

今回の例では、

  • 不正なBase64 → 空文字 or 空配列を返す

という方針にしましたが、
プロジェクトによっては、

  • 不正なBase64 → カスタム例外を投げる
  • 結果型に「成功/失敗」を含める

といった設計もあり得ます。

大事なのは、「呼び出し側が毎回例外処理を考えなくていいように、
ユーティリティ側でルールを固定しておく」ことです。


まとめ 「Base64デコードユーティリティ」は“外から来た梱包を安全にほどくための道具”

Base64デコードは、
「外部から送られてきたデータ」や「ファイル・トークンの中身」を、
安全に元の形に戻すための基本テクニックです。

押さえておきたいポイントは、

  • Convert.FromBase64String は「Base64 → バイト配列」の変換を行う中核メソッドであること。
  • 文字列として扱う場合は、エンコード側と同じエンコーディング(UTF-8など)で GetString すること。
  • 不正なBase64文字列が来る前提で、例外処理の方針をユーティリティ側で決めておくこと。
  • URLやJWTなどでは「URLセーフBase64」が使われるので、そのデコード手順も押さえておくと実務で強いこと。

ここまで理解できれば、「なんとなくFromBase64Stringしている」段階から一歩進んで、
“外部入力やプロトコル仕様を意識した、業務で使えるBase64デコードユーティリティ”を、
自分のC#コードの中に自然に組み込めるようになっていきます。

タイトルとURLをコピーしました