web-dev-qa-db-ja.com

スクリプトの文字列にSHA256とBase64を適用する

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
Niklas Berglund

問題は、異なるシェルを使用していることです。 echoコマンドは、ほとんどのシェルに組み込まれているシェルであり、実装ごとに動作が異なります。ここで、デフォルトのシェルはfishであると言いました。したがって、このコマンドを実行すると、次のようになります。

~> echo -n "asdasd" | shasum -a 256 | cut -d " " -f 1 | xxd -r -p | base64
X9kkYl9qsWoZzJgHx8UGrhgTSQ5LpnX4Q9WhDguqzbg=

上記の出力が得られます。これは、echofish-nをサポートしているためです。どうやら、あなたのシステムでは、/bin/shecho-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=

上記はコマンドラインとスクリプトで同じように機能し、試してみたいシェルでも同じように機能するはずです。 printfecho よりも優れているもう1つの理由。

1
terdon