LoginSignup
3
3

More than 1 year has passed since last update.

Windows Powershell にて base64コマンドを実現する

Last updated at Posted at 2021-06-30

結論

以下の関数をpowershell profileに登録すると、あたかもLinuxのbase64コマンドのようになります

function base64(){
    Param([switch]$encode=$true, [switch]$decode=$false, [Parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$input)
    Begin{}
    Process{
        if($decode){
            $byte = [System.Convert]::FromBase64String($input)
            $txt = [System.Text.Encoding]::Default.GetString($byte)
            echo $txt
        }
        elseif($encode){
            $byte = ([System.Text.Encoding]::Default).GetBytes($input)
            $b64enc = [Convert]::ToBase64String($byte)
            echo $b64enc
        }
    }
    End{}
}

使い方

# encodeオプションは省略可
echo "text here" | base64 -encode
# -> "dGV4dCBoZXJl"
echo "dGV4dCBoZXJl" | base64 -decode
# -> "text here"

# 複数の入力も可
echo "text here", "sample text" | base64 -encode
# -> "dGV4dCBoZXJl"
# -> "c2FtcGxlIHRleHQ="
echo "dGV4dCBoZXJl", "c2FtcGxlIHRleHQ=" | base64 -decode
# -> "text here"
# -> "sample text"

イントロ

WebサービスでAPIを使用する際やKubernetesの設定などで、Base64でエンコードされた文字列をデコードしたい場面がちょくちょくあります
Linuxの場合、以下のようにパイプラインをつないで一発でデコードできるのですが、Windowsの場合これが一発でできないので非常に不便でした

echo "dGV4dCBoZXJl" | base64 --decode

そこでWindows Powershellのプロファイルに関数を作って疑似的に作ってやろうというのが今回の試みです
提供した関数ではオプションのハイフンの数が1個少ないので、ハイフン1個の時は省略形というこだわりがある方は好みで引数名を変更してください

関数の解説

関数の名前が疑似的なコマンドとなるので、今回はbase64という名前の関数を作ります

Process部分

エンコード、デコード機能としての肝となる部分はProcessブロック内にあります
decodeオプションがついていればif($decode)内のブロックが、
encodeオプションがついていればelseif($encode)内のブロックが実行されます
実行内容については以下のページのコードを用いています
PowerShellでBase64のエンコードとデコード

Param部分

本来のbase64は encode,decodeのオプションがあり、引数としてエンコード/デコードするテキストが入ります
今回これを疑似的に再現するにあたって、オプション含めてすべてpowershell関数の引数(パラメータ)として扱います

具体的なオプションの扱い方
powershellでは引数の型を指定でき、[switch]というのはbool型を意味します
powershellでこのbool型の引数をトリガーするには-引数名という形になるため、Linuxのオプションのような表記になります
つまり、[switch]$encode=$true はデフォルトでtrueencodeという名前の引数をとる、ということを定義しています

パイプラインからの入力を受け取る引数の指定
[string]$inputだけを定義して終わってしまうと、実はパイプラインからの入力を引数として受け取らないという問題が発生します
そこで[Parameter(ValueFromPipeline=$true)]を追加することで、パイプラインからの入力を受け付けるようにします

あとは必須の引数であることを宣言するため、Mandatory=$trueを追加しています

複数の入力に対応

Processブロックの中身がそのまま記載された関数を作ってしまうと、最初の1つのみがパイプラインからの入力として認識されてしまいます
Beginブロック、Processブロック、Endブロックの3つで構成することにより、パイプラインから複数の入力が受け取れるようになります
参考: PowerShell: Creating Functions that accept Pipeline Input (ByValue)

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3