Base64とは、任意のバイト列を「A〜Z・a〜z・0〜9・+・/」の64種類の文字だけで表す符号化(エンコード)方式です。SHA-256は、任意のデータから256ビット(16進数で64文字)の固定長の値を作るハッシュ関数です。 どちらも「バイト列を扱う」点が共通しており、文字コードや改行の違いで結果が変わるという同じつまずきがあります。

この記事では、同じ入力「タスク完了?」から、8つの言語・コマンドで同じBase64とSHA-256が出ることを実際に実行して確認した早見表をまとめました。オンライン変換ツールでは分からない「btoaが日本語でエラーになる理由」「echo だとハッシュが変わる理由」「CRLF・BOMでの不一致」も、実行結果つきで再現して直し方を示します。

Base64・sha256の早見表

確認環境:Python 3.11 / Node.js 22.22.2 / Chromium 141 / Go 1.27.1 / Java 21.0.10 / PHP 8.4.21 / Ruby 3.3.6 / .NET SDK 8.0.131 / PowerShell 7.6.6 / GNU coreutils 9.4 / OpenSSL 3.0.13。

入力「タスク完了?」(UTF-8で18バイト)の正解値

種類 値
Base64(標準) 44K/44K544Kv5a6M5LqGPw==
Base64URL(パディングなし) 44K_44K544Kv5a6M5LqGPw
SHA-256(hex) 1a6ca68b0a2a05b88a0c60dbb91e75caa7e564a919e0b5e17145f0cd3e92a115
SHA-256(Base64) GmymiwoqBbiKDGDbuR51yqflZKkZ4LXhcUXwzT6SoRU=

言語別のエンコード・デコード・URLセーフ・SHA-256

言語 エンコード デコード URLセーフ SHA-256(hex)
JS(ブラウザ) u8.toBase64() / btoa(バイナリ文字列) Uint8Array.fromBase64(s) / atob(s) toBase64({alphabet:"base64url"}) crypto.subtle.digest("SHA-256", u8)
Node.js Buffer.from(s).toString("base64") Buffer.from(b,"base64") toString("base64url") createHash("sha256").update(s).digest("hex")
Python base64.b64encode(b) base64.b64decode(s) base64.urlsafe_b64encode(b) hashlib.sha256(b).hexdigest()
Go base64.StdEncoding.EncodeToString(b) StdEncoding.DecodeString(s) base64.RawURLEncoding sha256.Sum256(b)
Java Base64.getEncoder().encodeToString(b) Base64.getDecoder().decode(s) getUrlEncoder().withoutPadding() MessageDigest.getInstance("SHA-256")
PHP base64_encode($s) base64_decode($s, true) strtr で +/→-_ hash('sha256', $s)
Ruby Base64.strict_encode64(s) Base64.strict_decode64(s) Base64.urlsafe_encode64(s, padding: false) Digest::SHA256.hexdigest(s)
C# Convert.ToBase64String(b) Convert.FromBase64String(s) Replace('+','-') 等 SHA256.HashData(b)
シェル base64 / openssl base64 -A base64 -d basenc --base64url sha256sum / shasum -a 256
PowerShell [Convert]::ToBase64String($b) [Convert]::FromBase64String($s) -replace で置換 Get-FileHash

どの言語でも「文字列をUTF-8のバイト列にしてから」処理すれば、結果は一致します。 一致しないときは、ほぼ「文字コード」「改行」「BOM」「標準とURLセーフの取り違え」のどれかです。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Base64エンコード各言語コード一覧|sha256ハッシュのコマンド早見表」

Base64の仕組み:3バイトを4文字にする

Base64は、入力を3バイト(24ビット)ずつ区切り、6ビットずつ4つに分けて、それぞれを64種類の文字に置き換えます。 6ビットは0〜63の64通りなので、64文字で表せます。

flowchart LR
    A["入力 3バイト<br>M a n"] --> B["24ビット<br>010011 010110 000101 101110"]
    B --> C["6ビット×4<br>19 22 5 46"]
    C --> D["4文字<br>T W F u"]
入力 バイト数 出力 説明
Man 3 TWFu ちょうど3バイト→4文字
Ma 2 TWE= 1バイト足りない→ = 1つ
M 1 TQ== 2バイト足りない→ = 2つ

= はパディング(詰め物)で、「最後のブロックが何バイトだったか」を表します。 出力は必ず4の倍数の文字数になります。

サイズが約1.33倍になる理由

3バイトが4文字(4バイト)になるので、サイズは4/3 ≒ 1.333倍です。短いデータではパディング分だけ比率が大きくなります。Python で確かめた結果です。

import base64
for n in [1, 2, 3, 4, 100, 1000, 1048576]:
    e = base64.b64encode(b"a" * n)
    print(n, len(e), round(len(e) / n, 3))
1 4 4.0
2 4 2.0
3 4 1.333
4 8 2.0
100 136 1.36
1000 1336 1.336
1048576 1398104 1.333

出力の長さは「ceil(入力バイト数 ÷ 3) × 4」で計算できます。1MBの画像をBase64にしてJSONに埋め込むと約1.33MBになるので、大きなファイルはマルチパート送信やURL参照のほうが軽くなります。さらに、メール(MIME)形式では76文字ごとに改行が入るため、その分も増えます。

標準とURLセーフの違い

種類 62・63番目の文字 パディング 使われる場所
Base64(標準、RFC 4648 §4) + / あり メール添付、data URL、一般的なAPI
Base64URL(RFC 4648 §5) - _ 省略が多い JWT、URLのクエリ、ファイル名

+ / = はURLの中で特別な意味を持つため、URLやファイル名に入れるならBase64URLを使います。

言語別コード(コピペ用・実行結果つき)

すべて入力は「タスク完了?」、ファイルはUTF-8(BOMなし)で保存しています。

JavaScript(ブラウザ):btoaの日本語エラーと直し方

btoa() は「1文字=1バイト(Latin1)」の文字列しか受け付けないため、日本語をそのまま渡すとエラーになります。 Chromium 141 で実行したエラー文です。

InvalidCharacterError: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.

直し方は2つです。 新しいブラウザなら Uint8Array.prototype.toBase64()、広い環境で動かすなら TextEncoder でUTF-8のバイト列にしてから btoa() に渡します。

// 方法1:Uint8Array.toBase64 / fromBase64(Baseline 2025)
const u8 = new TextEncoder().encode("タスク完了?");
console.log(u8.toBase64());                                              // 標準
console.log(u8.toBase64({ alphabet: "base64url", omitPadding: true }));  // URLセーフ
const back = Uint8Array.fromBase64("44K_44K544Kv5a6M5LqGPw", { alphabet: "base64url" });
console.log(new TextDecoder().decode(back));
44K/44K544Kv5a6M5LqGPw==
44K_44K544Kv5a6M5LqGPw
タスク完了?
// 方法2:TextEncoder + btoa(対応ブラウザが広い)
const text = "タスク完了?";
const bytes = new TextEncoder().encode(text);
const bin = Array.from(bytes, (b) => String.fromCharCode(b)).join("");
const std = btoa(bin);
const url = std.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
console.log(std, url);

// デコード
const decoded = Uint8Array.from(atob(std), (c) => c.charCodeAt(0));
console.log(new TextDecoder().decode(decoded));

// SHA-256(Web Crypto API。HTTPS か localhost のページで使う)
const buf = await crypto.subtle.digest("SHA-256", bytes);
const hex = Array.from(new Uint8Array(buf), (b) => b.toString(16).padStart(2, "0")).join("");
console.log(hex);
44K/44K544Kv5a6M5LqGPw== 44K_44K544Kv5a6M5LqGPw
タスク完了?
1a6ca68b0a2a05b88a0c60dbb91e75caa7e564a919e0b5e17145f0cd3e92a115
API 対応状況(2026年10月時点で確認)
btoa / atob すべての主要ブラウザ・Node.js 16以降
Uint8Array.toBase64 / fromBase64 / toHex MDNで Baseline 2025(2025年9月〜)。Chromium 141で動作を確認。Node.js 22.22.2 では undefined でした
crypto.subtle 安全なコンテキスト(HTTPS・localhost)でのみ利用可。about:blank で試すと undefined でした

方法2は Node.js 22.22.2 のグローバルAPIで実行して確認しました。

Node.js(Buffer・crypto)

// b64.mjs  実行: node b64.mjs
import { createHash } from "node:crypto";

const text = "タスク完了?";
const buf = Buffer.from(text, "utf8");

console.log("std :", buf.toString("base64"));
console.log("url :", buf.toString("base64url"));
console.log("dec :", Buffer.from("44K/44K544Kv5a6M5LqGPw==", "base64").toString("utf8"));
console.log("dec2:", Buffer.from("44K_44K544Kv5a6M5LqGPw", "base64url").toString("utf8"));

const d = createHash("sha256").update(text, "utf8").digest();
console.log("hex :", d.toString("hex"));
console.log("b64 :", d.toString("base64"));
std : 44K/44K544Kv5a6M5LqGPw==
url : 44K_44K544Kv5a6M5LqGPw
dec : タスク完了?
dec2: タスク完了?
hex : 1a6ca68b0a2a05b88a0c60dbb91e75caa7e564a919e0b5e17145f0cd3e92a115
b64 : GmymiwoqBbiKDGDbuR51yqflZKkZ4LXhcUXwzT6SoRU=

Node.jsの "base64url" はパディングなしで出力します。

Python

# b64.py  実行: python3 b64.py
import base64, hashlib

text = "タスク完了?"
data = text.encode("utf-8")

std = base64.b64encode(data).decode("ascii")
url = base64.urlsafe_b64encode(data).decode("ascii").rstrip("=")
print("std :", std)
print("url :", url)
print("dec :", base64.b64decode(std).decode("utf-8"))
# URLセーフ版は = を戻してからデコード
print("dec2:", base64.urlsafe_b64decode(url + "=" * (-len(url) % 4)).decode("utf-8"))

digest = hashlib.sha256(data)
print("hex :", digest.hexdigest())
print("b64 :", base64.b64encode(digest.digest()).decode("ascii"))
std : 44K/44K544Kv5a6M5LqGPw==
url : 44K_44K544Kv5a6M5LqGPw
dec : タスク完了?
dec2: タスク完了?
hex : 1a6ca68b0a2a05b88a0c60dbb91e75caa7e564a919e0b5e17145f0cd3e92a115
b64 : GmymiwoqBbiKDGDbuR51yqflZKkZ4LXhcUXwzT6SoRU=

ファイルのハッシュは hashlib.file_digest(f, "sha256")(Python 3.11以降)で、大きなファイルも少しずつ読み込んで計算できます。

Go(標準ライブラリのみ)

// main.go  実行: go run main.go
package main

import (
    "crypto/sha256"
    "encoding/base64"
    "encoding/hex"
    "fmt"
)

func main() {
    data := []byte("タスク完了?")

    std := base64.StdEncoding.EncodeToString(data)
    url := base64.RawURLEncoding.EncodeToString(data) // Raw = パディングなし
    fmt.Println("std :", std)
    fmt.Println("url :", url)

    dec, err := base64.StdEncoding.DecodeString(std)
    if err != nil {
        panic(err)
    }
    fmt.Println("dec :", string(dec))

    sum := sha256.Sum256(data)
    fmt.Println("hex :", hex.EncodeToString(sum[:]))
    fmt.Println("b64 :", base64.StdEncoding.EncodeToString(sum[:]))
}

出力は Node.js・Python と同じ5行(std / url / dec / hex / b64)になることを確認しました。Goは StdEncoding・URLEncoding(パディングあり)・RawStdEncoding・RawURLEncoding(なし)の4種類から選びます。

Java(Java 21、単一ファイル実行)

// B64.java  実行: java -Dstdout.encoding=UTF-8 B64.java
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Base64;
import java.util.HexFormat;

public class B64 {
    public static void main(String[] args) throws Exception {
        byte[] data = "タスク完了?".getBytes(StandardCharsets.UTF_8);

        String std = Base64.getEncoder().encodeToString(data);
        String url = Base64.getUrlEncoder().withoutPadding().encodeToString(data);
        System.out.println("std : " + std);
        System.out.println("url : " + url);
        System.out.println("dec : " + new String(Base64.getDecoder().decode(std), StandardCharsets.UTF_8));

        byte[] sum = MessageDigest.getInstance("SHA-256").digest(data);
        System.out.println("hex : " + HexFormat.of().formatHex(sum));   // Java 17+
        System.out.println("b64 : " + Base64.getEncoder().encodeToString(sum));
    }
}

つまずきポイント: ロケール未設定(LANG= が空)の端末で -Dstdout.encoding=UTF-8 を付けずに実行すると、エンコード結果やハッシュは正しいのに、dec : ?????? と表示だけが文字化けしました。値の問題ではなく標準出力の文字コードの問題です。getBytes() には必ず StandardCharsets.UTF_8 を渡します。

PHP(8.4)

<?php
// b64.php  実行: php b64.php
$data = "タスク完了?";

$std = base64_encode($data);
$url = rtrim(strtr($std, '+/', '-_'), '=');
echo "std : $std\n";
echo "url : $url\n";
echo "dec : " . base64_decode($std, true) . "\n";  // true = 不正な文字があれば false を返す

echo "hex : " . hash('sha256', $data) . "\n";
echo "b64 : " . base64_encode(hash('sha256', $data, true)) . "\n";  // true = 生バイト

出力は他の言語と同じ値でした。hash() の第3引数 true で生のバイト列が返り、それをBase64にするのがポイントです(hex文字列をBase64にすると別の値になります)。

Ruby(3.3)

# b64.rb  実行: ruby b64.rb
require "base64"   # Ruby 3.4 以降は bundled gem(Bundler 利用時は Gemfile に追加)
require "digest"

data = "タスク完了?"

std = Base64.strict_encode64(data)
url = Base64.urlsafe_encode64(data, padding: false)
puts "std : #{std}"
puts "url : #{url}"
puts "dec : #{Base64.strict_decode64(std).force_encoding('UTF-8')}"
puts "enc64: #{Base64.encode64(data).inspect}"

puts "hex : #{Digest::SHA256.hexdigest(data)}"
puts "b64 : #{Digest::SHA256.base64digest(data)}"
std : 44K/44K544Kv5a6M5LqGPw==
url : 44K_44K544Kv5a6M5LqGPw
dec : タスク完了?
enc64: "44K/44K544Kv5a6M5LqGPw==\n"
hex : 1a6ca68b0a2a05b88a0c60dbb91e75caa7e564a919e0b5e17145f0cd3e92a115
b64 : GmymiwoqBbiKDGDbuR51yqflZKkZ4LXhcUXwzT6SoRU=

Base64.encode64 は60文字ごとと末尾に改行が入ります。 APIやJSONに入れるなら strict_encode64 を使います。

C#(.NET 8)

// Program.cs(dotnet new console で作成)  実行: dotnet run
using System.Security.Cryptography;
using System.Text;

Console.OutputEncoding = Encoding.UTF8;
byte[] data = Encoding.UTF8.GetBytes("タスク完了?");

string std = Convert.ToBase64String(data);
string url = std.TrimEnd('=').Replace('+', '-').Replace('/', '_');
Console.WriteLine($"std : {std}");
Console.WriteLine($"url : {url}");
Console.WriteLine($"dec : {Encoding.UTF8.GetString(Convert.FromBase64String(std))}");

byte[] sum = SHA256.HashData(data);
Console.WriteLine($"hex : {Convert.ToHexString(sum).ToLowerInvariant()}");
Console.WriteLine($"b64 : {Convert.ToBase64String(sum)}");

.NET SDK 8.0.131 で他の言語と同じ値を確認しました。Convert.ToHexString は大文字で返すので、小文字のhexと比べるときは ToLowerInvariant() を付けます。.NET 9以降は System.Buffers.Text.Base64Url クラスでURLセーフ版を直接扱えます(公式ドキュメントで確認、本記事では未実行)。

コマンドでBase64・sha256を求める

Linux・macOS

# Base64(GNU coreutils 9.4)
printf '%s' 'タスク完了?' | base64                       # 44K/44K544Kv5a6M5LqGPw==
printf '%s' 'タスク完了?' | base64 | tr '+/' '-_' | tr -d '='   # 44K_44K544Kv5a6M5LqGPw
printf '%s' 'タスク完了?' | basenc --base64url           # 44K_44K544Kv5a6M5LqGPw==
printf '%s' '44K/44K544Kv5a6M5LqGPw==' | base64 -d       # タスク完了?
printf '%s' 'タスク完了?' | openssl base64 -A            # 44K/44K544Kv5a6M5LqGPw==

# SHA-256
printf '%s' 'タスク完了?' | sha256sum                    # 1a6ca68b...3e92a115  -
printf '%s' 'タスク完了?' | shasum -a 256                # 1a6ca68b...3e92a115  -
printf '%s' 'タスク完了?' | openssl dgst -sha256         # SHA2-256(stdin)= 1a6ca68b...
printf '%s' 'タスク完了?' | openssl dgst -sha256 -binary | base64   # GmymiwoqBbiKDGDbuR51yqflZKkZ4LXhcUXwzT6SoRU=

# ファイルの検証
sha256sum lf.txt > SHA256SUMS
sha256sum -c SHA256SUMS                                   # lf.txt: OK
コマンド 押さえどころ
base64 GNU版は76文字ごとに改行。1行で欲しいときは base64 -w 0(macOS版は改行しない、デコードは -d または -D)
openssl base64 64文字ごとに改行。-A で1行
sha256sum Linux(coreutils)。-c でチェックサムファイルを検証
shasum -a 256 macOS標準(Perl製)。Linuxにもあることが多い
openssl dgst -sha256 どの環境でもほぼ使える。-binary で生バイト

GNU版 base64 で100バイトをエンコードすると、76文字+改行+残り60文字の2行に分かれ、-w 0 では136文字1行になることを確認しました。macOS版の挙動は公式のmanページの記載に基づいています(本記事では未実行)。

Windows(PowerShell・certutil)

# PowerShell 7.6.6 で実行
$text  = "タスク完了?"
$bytes = [System.Text.Encoding]::UTF8.GetBytes($text)

# Base64
$std = [Convert]::ToBase64String($bytes)
"std : $std"
"dec : " + [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($std))

# 文字列の SHA-256(Get-FileHash に -InputStream で渡す)
$stream = [System.IO.MemoryStream]::new($bytes)
(Get-FileHash -InputStream $stream -Algorithm SHA256).Hash

# ファイルの SHA-256(小文字で比べたいとき)
(Get-FileHash .\lf.txt -Algorithm SHA256).Hash.ToLower()
std : 44K/44K544Kv5a6M5LqGPw==
dec : タスク完了?
1A6CA68B0A2A05B88A0C60DBB91E75CAA7E564A919E0B5E17145F0CD3E92A115
5e974a5fe99c3a52053d8b30be6ba912b332db596e9e7ae58a148918795585e8

Get-FileHash は大文字のhexを返します。 値は同じなので、比較するときは大文字・小文字をそろえます(PowerShellの -eq は大文字・小文字を区別しません)。

コマンドプロンプトでは次のコマンドが使えます(Windows固有のため本記事では未実行。Microsoft公式ドキュメントの書式です)。

certutil -hashfile lf.txt SHA256
certutil -encode input.bin output.b64
certutil -decode output.b64 input.bin

certutil -encode は出力ファイルの先頭と末尾に -----BEGIN CERTIFICATE----- 形式の行を付けるため、純粋なBase64だけが欲しいときはPowerShellの [Convert] を使うほうが扱いやすくなります。

hexとBase64の違い:同じハッシュの別表記

SHA-256の結果は32バイトのバイナリで、hexとBase64はその「見せ方」の違いです。

表記 長さ 例(「タスク完了?」) よく使う場所
hex(16進数) 64文字 1a6ca68b0a2a…3e92a115 sha256sum、ダウンロードページのチェックサム、Gitなど
Base64 44文字(=含む) GmymiwoqBbiKDGDbuR51yqflZKkZ4LXhcUXwzT6SoRU= Subresource Integrity(sha256-…)、CSPのハッシュ、HTTPの Digest 系ヘッダー

よくある取り違え:hex文字列(64文字のテキスト)をさらにBase64にすると、別の値(88文字)になります。 Base64にするのは「生のダイジェスト(32バイト)」です。シェルなら openssl dgst -sha256 -binary | base64、PHPなら hash(..., true)、Pythonなら .digest() を使います。

ハッシュが一致しない原因と直し方(改行・CRLF・BOM)

echoは末尾に改行を足す

echo 'タスク完了?' | sha256sum
echo -n 'タスク完了?' | sha256sum
printf '%s' 'タスク完了?' | sha256sum
5e974a5fe99c3a52053d8b30be6ba912b332db596e9e7ae58a148918795585e8  -
1a6ca68b0a2a05b88a0c60dbb91e75caa7e564a919e0b5e17145f0cd3e92a115  -
1a6ca68b0a2a05b88a0c60dbb91e75caa7e564a919e0b5e17145f0cd3e92a115  -

echo は末尾に改行(\n)を付けるため、1バイト多い入力のハッシュになります。 Base64でも同様で、echo だと 44K/44K544Kv5a6M5LqGPwo=(末尾の Pwo= が改行入り)になりました。echo -n はシェルによって挙動が違うことがあるので、スクリプトでは printf '%s' を使うのが確実です。

改行コード(CRLF)とBOMで値が変わる

見た目が同じ3つのファイルを作ってハッシュを比べました。

printf 'タスク完了?\n'   > lf.txt
printf 'タスク完了?\r\n' > crlf.txt
printf '\xef\xbb\xbfタスク完了?\n' > bom.txt
sha256sum lf.txt crlf.txt bom.txt
file lf.txt crlf.txt bom.txt
5e974a5fe99c3a52053d8b30be6ba912b332db596e9e7ae58a148918795585e8  lf.txt
7e50e446ca4a9cee41e99c20df1f40de70ea59700f8413acfbfde49b54e2046d  crlf.txt
3197a739d67a5bf2b1f5da4dfebde5c92b6e5d5f531bf4e2abfd9ccf549abb00  bom.txt
lf.txt:   Unicode text, UTF-8 text
crlf.txt: Unicode text, UTF-8 text, with CRLF line terminators
bom.txt:  Unicode text, UTF-8 (with BOM) text

直し方:比べる前にCRLFやBOMを取り除くと、LFのファイルと同じ値に戻りました。

tr -d '\r' < crlf.txt | sha256sum               # 5e974a5f...795585e8  -
sed '1s/^\xEF\xBB\xBF//' bom.txt | sha256sum    # 5e974a5f...795585e8  -
原因 見分け方 直し方
echo の改行 Base64の末尾が o= や Cg== printf '%s' を使う
CRLF file で with CRLF line terminators tr -d '\r'、.gitattributes で eol=lf
BOM 先頭3バイトが ef bb bf エディタで「UTF-8(BOMなし)」で保存
文字コード違い Shift_JISとUTF-8で同じ文字でもバイト列が違う すべてUTF-8にそろえる

デコード時のエラー文

import base64
base64.b64decode("44K/44K544Kv5a6M5LqGPw")                  # パディングなし
base64.b64decode("44K_44K544Kv5a6M5LqGPw==", validate=True)  # URLセーフ文字
binascii.Error: Incorrect padding
binascii.Error: Only base64 data is allowed

validate=False(既定)でURLセーフ文字を渡すと、_ が読み飛ばされて number of data characters (21) cannot be 1 more than a multiple of 4 というエラーになりました。GNU base64 -d にURLセーフ文字を渡すと base64: invalid input で終了コード1です。一方 Node.js の Buffer.from(s, "base64") は両方の文字セットを受け付け、エラーになりません。言語によって寛容さが違うので、URLセーフかどうかを送る側と受ける側で決めておくのが確実です。

Base64は暗号化ではない・ハッシュ単体はパスワード保存に向かない

処理 元に戻せるか 鍵 主な用途
Base64(エンコード) 誰でも戻せる なし テキストしか通らない経路でバイナリを運ぶ
暗号化(AES など) 鍵があれば戻せる あり 内容を秘密にする
ハッシュ(SHA-256) 戻せない(一方向) なし 改ざん検知、同一性の確認
  • Base64は誰でもデコードできる「表記の変換」です。秘密にしたい値は暗号化し、通信はHTTPSで保護します。
  • SHA-256は高速に計算できるよう設計されているため、パスワード保存には bcrypt・Argon2 などの専用関数を使います。 詳しくは別記事「パスワードのハッシュ化|bcrypt・Argon2の推奨値と実測・移行コード」で解説しています。
  • 鍵つきで改ざんを検知したいときは、SHA-256単体ではなく HMAC-SHA256 を使います(例:Pythonの hmac.new(key, msg, hashlib.sha256))。

よくある質問

Q. Base64の末尾の「=」は削ってもよいですか? A. 受け取る側がパディングなしに対応していれば削れます。 JWTなどBase64URLでは省略が一般的です。Pythonの b64decode のように = が必要な実装では、"=" * (-len(s) % 4) を足してからデコードします。

Q. 同じ文字列なのに、言語によってsha256が違います。 A. ほとんどが入力のバイト列の違いです。 末尾の改行、CRLF、BOM、文字コード(UTF-8かどうか)を確認してください。本記事の8環境では、UTF-8・改行なしでそろえるとすべて 1a6ca68b…3e92a115 になりました。

Q. JavaScriptで日本語をBase64にするとエラーになります。 A. btoa() はLatin1の範囲の文字しか扱えません。new TextEncoder().encode(文字列) でUTF-8のバイト列にしてから、toBase64() か btoa() に渡します。

まとめ

  • Base64は3バイトを4文字にする符号化で、サイズは約1.33倍。= は最後のブロックの不足分を表します。
  • URLやJWTにはBase64URL(- _、パディング省略)を使い、標準版と取り違えないようにします。
  • どの言語でも「UTF-8のバイト列」にそろえれば同じ結果になることを8環境で確認しました。
  • ブラウザの btoa は日本語を直接扱えないので、TextEncoder を通すか Uint8Array.toBase64() を使います。
  • ハッシュが合わないときは、echoの改行・CRLF・BOMを疑い、printf '%s' や tr -d '\r' で直します。
  • hexとBase64は同じダイジェストの別表記。Base64にするのは生の32バイトです。
  • Base64は暗号化ではなく、パスワード保存にはbcrypt・Argon2を使います。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Base64エンコード各言語コード一覧|sha256ハッシュのコマンド早見表」

株式会社RJCでは、言語をまたいでデータを正しく扱う知識を仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?