SHA256を適用し、Base64でシェルスクリプトの文字列をエンコードしようとしています。 PHPと連携させる:
php -r 'echo base64_encode(hash("sha256", "asdasd", false));'
しかし、私はPHPへの依存を取り除こうとしています。
次のコード行は端末で正常に実行されます(シェルを使用fish
)。
$ echo -n "asdasd" | shasum -a 256 | cut -d " " -f 1 | xxd -r -p | base64
X9kkYl9qsWoZzJgHx8UGrhgTSQ5LpnX4Q9WhDguqzbg=
ただし、これをシェルスクリプトに入れると結果が異なります。
$ cat foo.sh
#!/bin/sh
echo -n "asdasd" | shasum -a 256 | cut -d " " -f 1 | xxd -r -p | base64
$ ./foo.sh
IzoDcfWvzNTZi62OfVm7DBfYrU9WiSdNyZIQhb7vZ0w=
期待される結果を生成するにはどうすればよいですか?私の考えでは、これはバイナリ文字列がどのように処理されるのかということです。
答え1
問題は別のシェルを使用していることです。このecho
コマンドはほとんどのシェルに組み込まれたシェルであり、実装ごとに異なる動作をします。デフォルトのシェルは次のとおりですfish
。したがって、このコマンドを実行すると、次のようになります。
~> echo -n "asdasd" | shasum -a 256 | cut -d " " -f 1 | xxd -r -p | base64
X9kkYl9qsWoZzJgHx8UGrhgTSQ5LpnX4Q9WhDguqzbg=
上記のように出力が表示されます。これはサポートecho
によるものです。明らかにサポートされていないシステムがあります。わからない場合、実際に印刷されるものは何ですか?これを説明するために、次のように印刷してみましょう。fish
-n
/bin/sh
echo
-n
echo
-n
-n asdasd\n
printf
$ printf -- "-n asdasd\n"
-n asdasd
これをパイプラインに入れると、次のようになります。
$ printf -- "-n asdasd\n" | shasum -a 256 | cut -d " " -f 1 | xxd -r -p | base64
IzoDcfWvzNTZi62OfVm7DBfYrU9WiSdNyZIQhb7vZ0w=
これはスクリプトから得られる出力です。だから実際に起こるのは、echo -n "asdasd"
それが印刷されるということです。-n
そして末尾の改行文字。簡単な解決策はprintf
代わりに使用することですecho
。
$ printf "asdasd" | shasum -a 256 | cut -d " " -f 1 | xxd -r -p | base64
X9kkYl9qsWoZzJgHx8UGrhgTSQ5LpnX4Q9WhDguqzbg=
上記はコマンドラインのスクリプトと同じように機能し、試みるすべてのシェルで機能する必要があります。別の理由がありますprintf
比較するecho
。