Whiz Tools

Base64 エンコーダ/デコーダ

テキストを Base64 エンコーディングに変換します

コピー

Base64 エンコーダーとデコーダー

はじめに

Base64 は、バイナリデータを ASCII 文字列形式で表現するバイナリからテキストへのエンコーディング方式です。これは、バイナリ形式で保存されたデータを、テキストコンテンツのみを信頼性高くサポートするチャネルを介して運ぶために設計されています。Base64 エンコーディングは、バイナリデータを安全にテキストベースのプロトコルで送信できる 64 文字のセットに変換します(このため、名前が付けられています)。

Base64 文字セットは次のように構成されています:

  • 大文字の A-Z(26 文字)
  • 小文字の a-z(26 文字)
  • 数字の 0-9(10 文字)
  • 通常は「+」と「/」の 2 文字(2 文字)

このツールを使用すると、テキストを Base64 形式に簡単にエンコードしたり、Base64 文字列を元のテキストにデコードしたりできます。これは、開発者、IT プロフェッショナル、およびテキストベースのチャネルを介して安全に送信する必要があるデータに取り組んでいる人々に特に便利です。

Base64 エンコーディングの仕組み

エンコーディングプロセス

Base64 エンコーディングは、バイナリデータの 3 バイト(24 ビット)のグループを 4 つの Base64 文字に変換することによって機能します。このプロセスは次の手順に従います:

  1. 入力テキストをそのバイナリ表現に変換します(ASCII または UTF-8 エンコーディングを使用)
  2. バイナリデータを 24 ビット(3 バイト)のチャンクにグループ化します
  3. 各 24 ビットのチャンクを 4 つの 6 ビットグループに分割します
  4. 各 6 ビットグループを対応する Base64 文字に変換します

入力の長さが 3 で割り切れない場合、出力と入力の長さの 4:3 の比率を維持するために「=」文字でパディングが追加されます。

数学的表現

バイトのシーケンス b1,b2,b3b_1, b_2, b_3 に対して、対応する Base64 文字 c1,c2,c3,c4c_1, c_2, c_3, c_4 は次のように計算されます:

c1=Base64[(b1>>2)]c_1 = \text{Base64}[(b_1 >> 2)]
c2=Base64[((b1&3)<<4)(b2>>4)]c_2 = \text{Base64}[((b_1 \& 3) << 4) | (b_2 >> 4)]
c3=Base64[((b2&15)<<2)(b3>>6)]c_3 = \text{Base64}[((b_2 \& 15) << 2) | (b_3 >> 6)]
c4=Base64[(b3&63)]c_4 = \text{Base64}[(b_3 \& 63)]

ここで、Base64[i]\text{Base64}[i] は Base64 アルファベットの ii 番目の文字を表します。

デコーディングプロセス

Base64 デコーディングはエンコーディングプロセスを逆転させます:

  1. 各 Base64 文字をその 6 ビット値に変換します
  2. これらの 6 ビット値を連結します
  3. ビットを 8 ビットのチャンク(バイト)にグループ化します
  4. 各バイトを対応する文字に変換します

パディング

エンコードするバイト数が 3 で割り切れない場合、パディングが適用されます:

  • 1 バイトだけ残っている場合、それは 2 つの Base64 文字に変換され、「==」で終わります
  • 2 バイト残っている場合、それらは 3 つの Base64 文字に変換され、「=」で終わります

テキスト「Hello」を Base64 にエンコードしてみましょう:

  1. 「Hello」の ASCII 表現:72 101 108 108 111
  2. バイナリ表現:01001000 01100101 01101100 01101100 01101111
  3. 6 ビットチャンクにグループ化:010010 000110 010101 101100 011011 000110 1111
  4. 最後のチャンクには 4 ビットしかないため、ゼロでパディングします:010010 000110 010101 101100 011011 000110 111100
  5. 10 進数に変換:18, 6, 21, 44, 27, 6, 60
  6. Base64 アルファベットで調べる:S, G, V, s, b, G, 8
  7. 結果は「SGVsbG8=」です

入力の長さ(5 バイト)が 3 で割り切れないため、末尾に「=」のパディングがあります。

公式

Base64 エンコードされた文字列の長さを計算するための一般的な公式は次のとおりです:

encoded_length=4×input_length3\text{encoded\_length} = 4 \times \lceil \frac{\text{input\_length}}{3} \rceil

ここで、x\lceil x \rceil は天井関数(最も近い整数に切り上げる)を表します。

使用例

Base64 エンコーディングはさまざまなアプリケーションで広く使用されています:

  1. メール添付ファイル:MIME(Multipurpose Internet Mail Extensions)は、メール内のバイナリ添付ファイルを Base64 でエンコードします。

  2. データ URL:HTML、CSS、または JavaScript 内に小さな画像、フォント、または他のリソースを直接埋め込むために「data:」URL スキームを使用します。

  3. API 通信:JSON ペイロードや他のテキストベースの API フォーマットでバイナリデータを安全に送信します。

  4. テキストフォーマットでのバイナリデータの保存:バイナリデータを XML、JSON、または他のテキストベースのフォーマットに保存する必要がある場合。

  5. 認証システム:HTTP の基本認証は Base64 エンコーディングを使用します(ただし、セキュリティのためではなく、単にエンコーディングのためです)。

  6. 暗号化:さまざまな暗号プロトコルやシステムの一部として、しばしばキーや証明書をエンコードするために使用されます。

  7. クッキーの値:クッキーに保存するために複雑なデータ構造をエンコードします。

代替案

Base64 は広く使用されていますが、特定の状況でより適切な代替案もあります:

  1. URL セーフ Base64:URL エンコーディングの問題を避けるために「-」と「_」を使用するバリアント。URL に含まれるデータに便利です。

  2. Base32:32 文字セットを使用し、出力が長くなりますが、人間の可読性が高く、大文字と小文字を区別しません。

  3. 16 進エンコーディング:単純に 16 進数に変換しますが、サイズが 2 倍になるため、非常に単純で広くサポートされています。

  4. バイナリ転送:大きなファイルや効率が重要な場合、適切な Content-Type ヘッダーを使用した HTTP などの直接バイナリ転送プロトコルが好まれます。

  5. 圧縮 + Base64:大きなテキストデータの場合、エンコーディング前に圧縮することでサイズの増加を軽減できます。

  6. JSON/XML シリアル化:構造化データの場合、Base64 エンコーディングよりもネイティブな JSON または XML シリアル化を使用する方が適切かもしれません。

歴史

Base64 エンコーディングは、バイナリデータをテキスト用に設計されたチャネルを介して送信する必要がある初期のコンピュータと電気通信システムにそのルーツを持っています。

Base64 の正式な仕様は、1987 年に RFC 989 の一部として初めて公開され、プライバシー強化メール(PEM)を定義しました。これは、RFC 1421(1993 年)および RFC 2045(1996 年、MIME の一部)で更新されました。

「Base64」という用語は、エンコーディングがバイナリデータを表現するために 64 の異なる ASCII 文字を使用することに由来します。この 64 文字の選択は意図的であり、64 は 2 の累乗(2^6)であるため、バイナリと Base64 の間の変換が効率的になります。

時が経つにつれ、Base64 のいくつかのバリアントが登場しました:

  • 標準 Base64:RFC 4648 で定義され、A-Z、a-z、0-9、+、/ および = でパディングを使用
  • URL セーフ Base64:URL エンコーディングの問題を避けるために - と _ を使用
  • ファイル名セーフ Base64:ファイル名での使用を目的とした、URL セーフに似たもの
  • IMAP 用の修正 Base64:IMAP プロトコルで使用される特別な文字の異なるセット

Base64 は、現代のコンピューティングにおいても基本的なツールであり続けており、特に JSON のようなテキストベースのデータフォーマットに依存するウェブアプリケーションや API の台頭に伴い重要性が増しています。

コード例

さまざまなプログラミング言語での Base64 エンコーディングとデコーディングの例を以下に示します:

// JavaScript Base64 エンコーディング/デコーディング
function encodeToBase64(text) {
  return btoa(text);
}

function decodeFromBase64(base64String) {
  try {
    return atob(base64String);
  } catch (e) {
    throw new Error("無効な Base64 文字列");
  }
}

// 使用例
const originalText = "Hello, World!";
const encoded = encodeToBase64(originalText);
console.log("エンコードされた:", encoded);  // SGVsbG8sIFdvcmxkIQ==

try {
  const decoded = decodeFromBase64(encoded);
  console.log("デコードされた:", decoded);  // Hello, World!
} catch (error) {
  console.error(error.message);
}
# Python Base64 エンコーディング/デコーディング
import base64

def encode_to_base64(text):
    # 文字列をバイトに変換してからエンコード
    text_bytes = text.encode('utf-8')
    base64_bytes = base64.b64encode(text_bytes)
    return base64_bytes.decode('utf-8')

def decode_from_base64(base64_string):
    try:
        # Base64 文字列をバイトに変換してからデコード
        base64_bytes = base64_string.encode('utf-8')
        text_bytes = base64.b64decode(base64_bytes)
        return text_bytes.decode('utf-8')
    except Exception as e:
        raise ValueError(f"無効な Base64 文字列: {e}")

# 使用例
original_text = "Hello, World!"
encoded = encode_to_base64(original_text)
print(f"エンコードされた: {encoded}")  # SGVsbG8sIFdvcmxkIQ==

try:
    decoded = decode_from_base64(encoded)
    print(f"デコードされた: {decoded}")  # Hello, World!
except ValueError as e:
    print(e)
// Java Base64 エンコーディング/デコーディング
import java.util.Base64;
import java.nio.charset.StandardCharsets;

public class Base64Example {
    public static String encodeToBase64(String text) {
        byte[] textBytes = text.getBytes(StandardCharsets.UTF_8);
        byte[] encodedBytes = Base64.getEncoder().encode(textBytes);
        return new String(encodedBytes, StandardCharsets.UTF_8);
    }
    
    public static String decodeFromBase64(String base64String) {
        try {
            byte[] base64Bytes = base64String.getBytes(StandardCharsets.UTF_8);
            byte[] decodedBytes = Base64.getDecoder().decode(base64Bytes);
            return new String(decodedBytes, StandardCharsets.UTF_8);
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException("無効な Base64 文字列: " + e.getMessage());
        }
    }
    
    public static void main(String[] args) {
        String originalText = "Hello, World!";
        String encoded = encodeToBase64(originalText);
        System.out.println("エンコードされた: " + encoded);  // SGVsbG8sIFdvcmxkIQ==
        
        try {
            String decoded = decodeFromBase64(encoded);
            System.out.println("デコードされた: " + decoded);  // Hello, World!
        } catch (IllegalArgumentException e) {
            System.err.println(e.getMessage());
        }
    }
}
<?php
// PHP Base64 エンコーディング/デコーディング
function encodeToBase64($text) {
    return base64_encode($text);
}

function decodeFromBase64($base64String) {
    $decoded = base64_decode($base64String, true);
    if ($decoded === false) {
        throw new Exception("無効な Base64 文字列");
    }
    return $decoded;
}

// 使用例
$originalText = "Hello, World!";
$encoded = encodeToBase64($originalText);
echo "エンコードされた: " . $encoded . "\n";  // SGVsbG8sIFdvcmxkIQ==

try {
    $decoded = decodeFromBase64($encoded);
    echo "デコードされた: " . $decoded . "\n";  // Hello, World!
} catch (Exception $e) {
    echo "エラー: " . $e->getMessage() . "\n";
}
?>
// C# Base64 エンコーディング/デコーディング
using System;
using System.Text;

class Base64Example
{
    public static string EncodeToBase64(string text)
    {
        byte[] textBytes = Encoding.UTF8.GetBytes(text);
        return Convert.ToBase64String(textBytes);
    }
    
    public static string DecodeFromBase64(string base64String)
    {
        try
        {
            byte[] base64Bytes = Convert.FromBase64String(base64String);
            return Encoding.UTF8.GetString(base64Bytes);
        }
        catch (FormatException)
        {
            throw new FormatException("無効な Base64 文字列");
        }
    }
    
    static void Main()
    {
        string originalText = "Hello, World!";
        string encoded = EncodeToBase64(originalText);
        Console.WriteLine($"エンコードされた: {encoded}");  // SGVsbG8sIFdvcmxkIQ==
        
        try
        {
            string decoded = DecodeFromBase64(encoded);
            Console.WriteLine($"デコードされた: {decoded}");  // Hello, World!
        }
        catch (FormatException e)
        {
            Console.WriteLine($"エラー: {e.Message}");
        }
    }
}
# Ruby Base64 エンコーディング/デコーディング
require 'base64'

def encode_to_base64(text)
  Base64.strict_encode64(text)
end

def decode_from_base64(base64_string)
  begin
    Base64.strict_decode64(base64_string)
  rescue ArgumentError => e
    raise "無効な Base64 文字列: #{e.message}"
  end
end

# 使用例
original_text = "Hello, World!"
encoded = encode_to_base64(original_text)
puts "エンコードされた: #{encoded}"  # SGVsbG8sIFdvcmxkIQ==

begin
  decoded = decode_from_base64(encoded)
  puts "デコードされた: #{decoded}"  # Hello, World!
rescue StandardError => e
  puts "エラー: #{e.message}"
end
// Go Base64 エンコーディング/デコーディング
package main

import (
    "encoding/base64"
    "fmt"
)

func encodeToBase64(text string) string {
    return base64.StdEncoding.EncodeToString([]byte(text))
}

func decodeFromBase64(base64String string) (string, error) {
    bytes, err := base64.StdEncoding.DecodeString(base64String)
    if err != nil {
        return "", fmt.Errorf("無効な Base64 文字列: %v", err)
    }
    return string(bytes), nil
}

func main() {
    originalText := "Hello, World!"
    encoded := encodeToBase64(originalText)
    fmt.Println("エンコードされた:", encoded)  // SGVsbG8sIFdvcmxkIQ==
    
    decoded, err := decodeFromBase64(encoded)
    if err != nil {
        fmt.Println("エラー:", err)
    } else {
        fmt.Println("デコードされた:", decoded)  // Hello, World!
    }
}
// Swift Base64 エンコーディング/デコーディング
import Foundation

func encodeToBase64(_ text: String) -> String? {
    if let data = text.data(using: .utf8) {
        return data.base64EncodedString()
    }
    return nil
}

func decodeFromBase64(_ base64String: String) -> String? {
    if let data = Data(base64Encoded: base64String) {
        return String(data: data, encoding: .utf8)
    }
    return nil
}

// 使用例
let originalText = "Hello, World!"
if let encoded = encodeToBase64(originalText) {
    print("エンコードされた: \(encoded)")  // SGVsbG8sIFdvcmxkIQ==
    
    if let decoded = decodeFromBase64(encoded) {
        print("デコードされた: \(decoded)")  // Hello, World!
    } else {
        print("エラー: Base64 文字列をデコードできませんでした")
    }
} else {
    print("エラー: テキストをエンコードできませんでした")
}
' Excel VBA Base64 エンコーディング/デコーディング
' 注:これは Microsoft XML, v6.0 への参照を必要とします
Function EncodeToBase64(text As String) As String
    Dim xmlObj As Object
    Set xmlObj = CreateObject("MSXML2.DOMDocument")
    
    Dim xmlNode As Object
    Set xmlNode = xmlObj.createElement("b64")
    
    xmlNode.DataType = "bin.base64"
    xmlNode.nodeTypedValue = StrConv(text, vbFromUnicode)
    
    EncodeToBase64 = xmlNode.text
    
    Set xmlNode = Nothing
    Set xmlObj = Nothing
End Function

Function DecodeFromBase64(base64String As String) As String
    On Error GoTo ErrorHandler
    
    Dim xmlObj As Object
    Set xmlObj = CreateObject("MSXML2.DOMDocument")
    
    Dim xmlNode As Object
    Set xmlNode = xmlObj.createElement("b64")
    
    xmlNode.DataType = "bin.base64"
    xmlNode.text = base64String
    
    DecodeFromBase64 = StrConv(xmlNode.nodeTypedValue, vbUnicode)
    
    Set xmlNode = Nothing
    Set xmlObj = Nothing
    Exit Function
    
ErrorHandler:
    DecodeFromBase64 = "エラー: 無効な Base64 文字列"
End Function

' ワークシートでの使用:
' =EncodeToBase64("Hello, World!")
' =DecodeFromBase64("SGVsbG8sIFdvcmxkIQ==")
# R Base64 エンコーディング/デコーディング
# 'base64enc' パッケージが必要です
# install.packages("base64enc")
library(base64enc)

encode_to_base64 <- function(text) {
  # テキストを生バイトに変換してからエンコード
  text_raw <- charToRaw(text)
  base64_encoded <- base64encode(text_raw)
  return(rawToChar(base64_encoded))
}

decode_from_base64 <- function(base64_string) {
  tryCatch({
    # Base64 文字列を生バイトに変換してからデコード
    base64_raw <- charToRaw(base64_string)
    decoded_raw <- base64decode(base64_raw)
    return(rawToChar(decoded_raw))
  }, error = function(e) {
    stop(paste("無効な Base64 文字列:", e$message))
  })
}

# 使用例
original_text <- "Hello, World!"
encoded <- encode_to_base64(original_text)
cat("エンコードされた:", encoded, "\n")  # SGVsbG8sIFdvcmxkIQ==

tryCatch({
  decoded <- decode_from_base64(encoded)
  cat("デコードされた:", decoded, "\n")  # Hello, World!
}, error = function(e) {
  cat("エラー:", e$message, "\n")
})
% MATLAB Base64 エンコーディング/デコーディング
function demo_base64()
    originalText = 'Hello, World!';
    
    % エンコード
    encoded = encode_to_base64(originalText);
    fprintf('エンコードされた: %s\n', encoded);  % SGVsbG8sIFdvcmxkIQ==
    
    % デコード
    try
        decoded = decode_from_base64(encoded);
        fprintf('デコードされた: %s\n', decoded);  % Hello, World!
    catch e
        fprintf('エラー: %s\n', e.message);
    end
end

function encoded = encode_to_base64(text)
    % テキストを uint8 配列に変換してからエンコード
    bytes = uint8(text);
    encoded = base64encode(bytes);
end

function decoded = decode_from_base64(base64String)
    try
        % Base64 文字列を uint8 配列にデコード
        bytes = base64decode(base64String);
        decoded = char(bytes);
    catch
        error('無効な Base64 文字列');
    end
end
// C Base64 エンコーディング/デコーディング(OpenSSL を使用)
#include <stdio.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/buffer.h>
#include <stdint.h>

char* encode_to_base64(const char* input) {
    BIO *bio, *b64;
    BUF_MEM *bufferPtr;
    
    b64 = BIO_new(BIO_f_base64());
    bio = BIO_new(BIO_s_mem());
    bio = BIO_push(b64, bio);
    
    BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
    BIO_write(bio, input, strlen(input));
    BIO_flush(bio);
    BIO_get_mem_ptr(bio, &bufferPtr);
    
    char* result = (char*)malloc(bufferPtr->length + 1);
    memcpy(result, bufferPtr->data, bufferPtr->length);
    result[bufferPtr->length] = '\0';
    
    BIO_free_all(bio);
    
    return result;
}

char* decode_from_base64(const char* input) {
    BIO *bio, *b64;
    size_t length = strlen(input);
    char* buffer = (char*)malloc(length);
    
    b64 = BIO_new(BIO_f_base64());
    bio = BIO_new_mem_buf(input, -1);
    bio = BIO_push(b64, bio);
    
    BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
    int decoded_length = BIO_read(bio, buffer, length);
    
    if (decoded_length <= 0) {
        free(buffer);
        BIO_free_all(bio);
        return NULL; // 無効な Base64 入力
    }
    
    buffer[decoded_length] = '\0';
    
    BIO_free_all(bio);
    
    return buffer;
}

int main() {
    const char* original_text = "Hello, World!";
    
    char* encoded = encode_to_base64(original_text);
    printf("エンコードされた: %s\n", encoded);  // SGVsbG8sIFdvcmxkIQ==
    
    char* decoded = decode_from_base64(encoded);
    if (decoded) {
        printf("デコードされた: %s\n", decoded);  // Hello, World!
        free(decoded);
    } else {
        printf("エラー: 無効な Base64 文字列\n");
    }
    
    free(encoded);
    
    return 0;
}
// Rust Base64 エンコーディング/デコーディング
use base64::{encode, decode};
use std::str;

fn encode_to_base64(text: &str) -> String {
    encode(text)
}

fn decode_from_base64(base64_string: &str) -> Result<String, String> {
    match decode(base64_string) {
        Ok(bytes) => {
            match str::from_utf8(&bytes) {
                Ok(text) => Ok(text.to_string()),
                Err(e) => Err(format!("無効な UTF-8 シーケンス: {}", e))
            }
        },
        Err(e) => Err(format!("無効な Base64 文字列: {}", e))
    }
}

fn main() {
    let original_text = "Hello, World!";
    let encoded = encode_to_base64(original_text);
    println!("エンコードされた: {}", encoded);  // SGVsbG8sIFdvcmxkIQ==
    
    match decode_from_base64(&encoded) {
        Ok(decoded) => println!("デコードされた: {}", decoded),  // Hello, World!
        Err(e) => println!("エラー: {}", e)
    }
}

エッジケースと考慮事項

Base64 エンコーディングとデコーディングに取り組む際は、次の重要な考慮事項に注意してください:

  1. Unicode および非 ASCII 文字:非 ASCII 文字を含むテキストをエンコードする場合、Base64 エンコーディングの前に適切な文字エンコーディング(通常は UTF-8)を確保してください。

  2. パディング:標準の Base64 は、出力の長さが 4 の倍数になるように「=」文字でパディングを使用します。一部の実装ではパディングを省略することが許可されており、互換性の問題を引き起こす可能性があります。

  3. 改行:従来の Base64 実装は、可読性のために改行を挿入しますが、現代のアプリケーションではこれを省略することがよくあります。

  4. URL セーフ Base64:標準の Base64 は「+」および「/」文字を使用しており、これらは URL で特別な意味を持ちます。URL コンテキストでは、URL セーフ Base64 を使用してこれらを「-」および「_」に置き換えます。

  5. 空白:デコーディング時、一部の実装は寛容で空白を無視しますが、他の実装は正確な入力を要求します。

  6. サイズの増加:Base64 エンコーディングはデータのサイズを約 33% 増加させます(3 バイトの入力に対して 4 バイトの出力)。

  7. パフォーマンス:非常に大きなデータに対して Base64 エンコーディング/デコーディングは計算集約的になる可能性があります。大きなファイルの場合はストリーミングアプローチを検討してください。

参考文献

  1. RFC 4648 - Base16、Base32、および Base64 データエンコーディング
  2. RFC 2045 - MIME パート 1: インターネットメッセージボディの形式
  3. MDN Web Docs: Base64 エンコーディングとデコーディング
  4. Base64 - Wikipedia
  5. MIME - Wikipedia
Feedback