假设我将字符串转换为字节数组。
byte[] byte sUserID.getBytes(“UTF-8”); //Convert User ID String to byte array
现在我需要在 Shell 上编写一个脚本,该脚本与我的 Java 代码具有完全相同的功能。在某个阶段,我必须对字节数组进行哈希处理(MessageDigest.getInstance(“SHA-256”)
在 Java 和openssl dgst -sha256 –binary
Shell 中使用),但由于 Java 代码中的摘要是从字节数组生成的,因此它们与我在 Shell 中得到的结果不匹配(在 Shell 中,我现在只是对字符串进行哈希处理) ,因此输入格式不匹配)。
因为我在 shell 中的输入openssl
应该与 Java 输入类似,所以我想知道是否有办法getBytes()
在 Shell 中“模拟”方法?我在 Shell 方面没有太多经验,所以我不知道在这种情况下最好的方法是什么。有任何想法吗?干杯!
答案1
openssl
的标准输入是字节流。
的内容$user
是非 0 字节序列(可能会也可能不会形成 UTF-8 或其他字符集/编码中的有效字符)。
printf %s "$user"
的标准输出是字节流。
printf %s "$user" | openssl dgst -sha256 –binary
将连接printf
的标准输出与openssl
的标准输入。openssl
的标准输出是另一个字节流。
现在,如果您从终端从用户输入$user
,用户将通过按下键盘上的按键来输入。终端将发送以其配置的字符集编码的相应字符(如按键标签上所写)。通常,该字符集将基于当前区域设置中的字符集。你可以找到那是什么locale charmap
。
例如,如果语言环境为fr_FR.iso885915@euro
,并且xterm
在该语言环境中启动,locale charmap
则将返回ISO-8859-15
。如果用户输入的stéphane
是用户名,则该用户名é
可能会被编码为0xe9
字节,因为这是字符集中的定义方式ISO-8859-15
。
如果您希望é
在传递给 之前将其编码为 UTF-8 openssl
,则可以在此处iconv
将该字节转换0xe9
为 UTF-8 中相应的编码(两个字节0xc3
0xa9
:):
IFS= read -r user # read username from stdin as a sequence of bytes
# assumed to be encoded from characters as per the
# locale's encoding
printf %s "$user" |
iconv -t utf-8 | # convert from locale encoding to UTF-8
openssl dgst -sha256 –binary