Base64 を UTF-16 にデコードする手順
- Base64 を 入力 · Base64 に貼り付けます。文字コード はあらかじめ UTF-16LE に設定されています。
- 出力 · テキスト でテキストを確認します。検出器はゼロバイトをバイナリデータの兆候とみなすため、推定形式 欄はたいてい「バイナリ」と表示されますが、テキスト出力そのものは正しく表示されます。
- 結果が漢字のような文字の並びになったら、文字コード を UTF-16BE に切り替えます。
- データの先頭にバイト順マークがある場合は、自動検出 が正しいバイト順を選び、マークを取り除きます。
- 出力をコピー でテキストをコピーし、ダウンロード で生のバイト列を保存します。
逆方向の変換は UTF-16 から Base64 へ を使ってください。
Base64 に含まれる UTF-16 の見分け方
UTF-16 の Base64 には目に見えるリズムがあります。UTF-16 の ASCII テキストでは文字のバイトとゼロバイトが交互に並び、ゼロのビットは Base64 のアルファベットで A に対応するため、数文字おきに A が現れます。
| Base64 | バイト順 | デコード結果 |
|---|---|---|
SABlAGwAbABvAA== | LE、BOM なし | Hello |
AEgAZQBsAGwAbw== | BE、BOM なし | Hello |
//5IAGkA | LE、BOM FF FE あり | Hi |
/v8ASABp | BE、BOM FE FF あり | Hi |
RwBlAHQALQBEAGEAdABlAA== | LE、BOM なし | Get-Date |
ビッグエンディアンの ASCII テキストは最初のバイトがゼロなので、必ず A で始まります。//4 または /v8 で始まる文字列は、先頭にバイト順マークがあります。
バイト順、BOM と自動検出
バイト順を間違えて読むと、2 バイトの組がすべて入れ替わり、英語が CJK の漢字に化けます。AEgAZQBsAGwAbw== を UTF-16LE としてデコードすると 䠀攀氀氀漀 になります。データは何も失われていないので、文字コード を切り替えれば元に戻ります。
自動検出 は、データが BOM で始まっていれば UTF-16 を確実に判定します。BOM がない場合、UTF-16 の ASCII テキストは UTF-8 としても有効なため(UTF-8 でもゼロバイトは正当です)、自動検出が見えない文字を含む UTF-8 と誤認することがあります。このページでは、先頭に //4 や /v8 が見えない限り、UTF-16LE か UTF-16BE を手動で選んだままにしておいてください。
バイト数が奇数なら、どこかがおかしいということです。SABpAAA= は 5 バイトで、UTF-16LE としてデコードすると Hi の後ろに � が付きます。値が途中で切れているか、そもそも UTF-16 ではありません。
UTF-16 の Base64 が使われる場面
最もよく見かけるのは PowerShell です。powershell -enc SQBFAFgA... のようなエンコード済みコマンドはタスクスケジューラ、インストーラーのスクリプト、セキュリティログに現れ、その Base64 は常に UTF-16LE です。PowerShell EncodedCommand デコーダー は、コマンドライン全体から値を取り出し、スクリプト内にさらに Base64 がないかも調べます。
ほかには、Convert.ToBase64String(Encoding.Unicode.GetBytes(...)) を呼ぶ .NET プログラム、Windows のレジストリやイベントのデータ、バイナリとしてエクスポートされた SQL Server の NVARCHAR の値などがあります。
コードで UTF-16 の Base64 をデコードする
import base64
raw = base64.b64decode("SABlAGwAbABvAA==")
raw.decode("utf-16-le") # 'Hello'
base64.b64decode("/v8ASABp").decode("utf-16") # 'Hi', byte order taken from the BOM
バイト数が奇数の場合、Python は UnicodeDecodeError: truncated data を送出します。
// Node.js: little-endian only
Buffer.from("SABlAGwAbABvAA==", "base64").toString("utf16le"); // "Hello"
// Browsers and Node.js: either order
new TextDecoder("utf-16be").decode(Uint8Array.from(atob("AEgAZQBsAGwAbw=="), c => c.charCodeAt(0))); // "Hello"
C# では、Encoding.Unicode.GetString(Convert.FromBase64String(s)) で UTF-16LE を、Encoding.BigEndianUnicode でビッグエンディアンを読み取れます。Python と Node.js のページもあわせてご覧ください。
よくある質問
Base64 の中身が UTF-16 かどうかはどう見分けますか?
SABlAGwAbABvAA== のように、A が規則的に何度も現れていないかを見てください。UTF-16 では ASCII の各文字の隣にゼロバイトが並びます。先頭が //4 または /v8 なら、UTF-16 のバイト順マーク(BOM)です。
デコードすると中国語のような文字が出るのはなぜですか?
バイト順が逆になっています。ビッグエンディアンの Hello をリトルエンディアンとして読むと 䠀攀氀氀漀 になります。文字コード を UTF-16LE と UTF-16BE の間で切り替えてください。
テキストの末尾に � が付くのはなぜですか?
UTF-16 のバイト数は偶数でなければなりません。奇数の場合、Base64 が途中で切れているか UTF-16 ではなく、余った 1 バイトが置換文字になります。
PowerShell の -EncodedCommand はどうデコードしますか?
-EncodedCommand(または -enc)の後ろの値は UTF-16LE の Base64 なので、このページでデコードできます。PowerShell デコーダー ならコマンドライン全体を貼り付けても動作し、入れ子になったペイロードも見つけます。