将 SHA256 和 Base64 应用于脚本中的字符串

将 SHA256 和 Base64 应用于脚本中的字符串

我正在尝试应用 SHA256,然后在 shell 脚本中对字符串进行 Base64 编码。让它与 PHP 一起工作: php -r 'echo base64_encode(hash("sha256", "asdasd", false));'.但我正在努力摆脱对 PHP 的依赖。

这行代码在终端中运行良好(使用 shell fish):

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

但是当我将它放入 shell 脚本中时,结果有所不同:

$ cat foo.sh
#!/bin/sh
echo -n "asdasd" | shasum -a 256 | cut -d " " -f 1 | xxd -r -p | base64
$ ./foo.sh
IzoDcfWvzNTZi62OfVm7DBfYrU9WiSdNyZIQhb7vZ0w=

我怎样才能让它产生预期的结果?我的猜测是这是因为二进制字符串的处理方式?

答案1

问题是您使用了不同的外壳。该echo命令是大多数 shell 的内置 shell,并且每个实现的行为都不同。现在,您说您的默认 shell 是fish.因此,当您运行此命令时:

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

您将得到如上所示的输出。这是因为echofish支持-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=

上面的内容在命令行和脚本中的工作方式相同,并且应该在您想尝试的任何 shell 中执行此操作。还有一个原因printfecho

相关内容