前回、気象庁のWebページから現在の東京都の気温を取得し、そのデータをGoogle Chartでレンダリングできる形に加工するPowerShellスクリプトを作成した。グラフはBase64にエンコードした状態であればデータが取り出せることはわかったので、今回はそのBase64のデータをデコードする処理方法を取り上げる。
→連載「PowerShell Core入門 - 基本コマンドの使い方」の過去回はこちらを参照。
Base64
歴史的に、メールはバイナリデータを直接送信することができなかった。このため、バイナリデータをメールで送信したい場合はメールで送信できる形式に変換する必要があった。こうした変換に使われる方式はいくつか存在しており、「Base64」という仕組みもその1つだ。
Base64では3バイトのバイナリデータを6ビットごとにASCII文字へ変換する。変換先文字は大文字「A~Z」、小文字「a~z」、数字「0~9」、プラス記号「+」、スラッシュ記号「/」の64個。データ末尾には端数を埋めるためにイコール記号「=」も使われる。3バイト(24ビット)を6ビットごとASCII文字へ変換するので、結果として4文字のASCII文字に変換されることになる。
こうした変換方式はいくつか存在しているのだが、Base64はそうした変換方式の中でも人気があるというか、メール以外のシーンでもしばしば使われている。今回のケースでいえばHTMLに画像データを組み込む目的で、PNG画像をBase64でエンコードしたデータが使われている。
なお、Base64に変換すると3バイトごとのブロックが4バイトになるわけなので、エンコード後のデータは代替元データの133%のサイズになる。データが増えてしまうので、変換する理由がない限りはあまり使ったりはしない。
PowerShellとBase64
Base64はよく使われるエンコード形式なので、MacやLinuxといったOSには変換用のコマンドが用意されていることが多い。
ではWindowsはどうかと言うと、Windowsにはそうしたコマンドは用意されていない。さらに、PowerShellにもそういったコマンドレットは用意されていない。しかし、当然ながらWindowsでもBase64は利用しているわけで、エンコード/デコード処理は.NETに機能として用意されている。APIを叩けば使える状態だ。
PowerShellのコマンドレットとしてBase64の機能は用意されていないわけだが、.NETに用意されているということはPowerShellでも使えるということを意味している。PowerShellが強力なのはここだ。.NETで使える機能は基本的にPowerShellからも利用できる。これはWindowsの機能のかなりの部分がPowerShellから利用できることを意味している。PowerShellがWindowsにおいて重要なスクリプトであるのには、こういった理由がある。
PowerShellからBase64エンコード/デコードを行う方法
Base64のエンコード処理とデコード処理については詳しく取り上げても仕方ないので、ここではその使い方だけを簡単に説明しておく。
まず、データをBase64でエンコードするには「[Convert]::ToBase64String()」を使用する。このメソッドにはバイト配列を指定するので、エンコードしたいデータを先にバイト配列に変換しておく必要がある。例えば、文字列をバイト配列に変換するなら「[Text.Encoding]::Default.GetBytes()」を使用する。この2つのメソッドを使えば文字列をBase64エンコードに変換することができる。簡単なサンプルは次の通りだ。
PS C:\Users\daichi> $bytes = [Text.Encoding]::Default.GetBytes('Welcome')
PS C:\Users\daichi> $base64 = [Convert]::ToBase64String($bytes)
PS C:\Users\daichi> $bytes
87
101
108
99
111
109
101
PS C:\Users\daichi> $base64
V2VsY29tZQ==
PS C:\Users\daichi>
今度は逆にBase64エンコードをデコードする方法を説明しよう。Base64文字列は「[Convert]::FromBase64String()」でデコードできる。返り値はバイト配列だ。これを、例えば文字列として扱いたい場合は、さらにこのデータを文字列に変換する必要がある。バイト配列を文字列に変換するには「[Text.Encoding]::Default.GetString()」などを使えばよい。簡単なサンプルは次のようになる。
PS C:\Users\daichi> $base64
V2VsY29tZQ==
PS C:\Users\daichi> $bytes = [Convert]::FromBase64String($base64)
PS C:\Users\daichi> $string = [Text.Encoding]::Default.GetString($bytes)
PS C:\Users\daichi> $bytes
87
101
108
99
111
109
101
PS C:\Users\daichi> $string
Welcome
PS C:\Users\daichi>
要するに、Base64のエンコードとデコード処理は「[Convert]::ToBase64String()」および「[Convert]::FromBase64String()」が本体処理で、後はバイト配列を状況に応じてほかのデータ型に変換して使うといった感じになる。