Scala一行代码生成字符串的MD5哈希值

6

我是Scala的新手,我发现了这个有趣的一行代码可以从字符串生成十六进制编码的MD5哈希值。我希望有人可以帮助我更好地理解它。

private def getMd5(inputStr: String): String = {
  val md: MessageDigest = MessageDigest.getInstance("MD5")
  md.digest(inputStr.getBytes()).map(0xFF & _).map { "%02x".format(_) }.foldLeft("") {_ + _}
}

感谢您的选择。

1
最好的理解方法是从REPL中的输入字符串开始,跟随每行或操作并检查输出。假设 val inputStr = "foo"map 调用使用给定操作转换左侧的值。foldLeft 将连接作为输入给定的字符串集合。例如,["foo", "bar", "baz"] 变成 "foobarbaz" - Brian
使用两个 map 和一个 foldLeft 来完成可以用单个 foldLeft 完成的任务似乎相当低效。 - jwvh
@jwvh - 你会如何改进它? - AngryPanda
md.digest(inputStr.getBytes()).foldLeft("")(_+"%02x".format(_)) - jwvh
1个回答

2

这只是一个类似于Java代码的模拟,但没有使用StringBuilder(由您决定)。

    MessageDigest messageDigest = MessageDigest.getInstance("SHA-512");
    String password = "secret";
    messageDigest.update(password.getBytes());
    byte[] bytes = messageDigest.digest();
    StringBuilder stringBuilder = new StringBuilder();
    for (byte aByte : bytes) {
        stringBuilder.append(Integer.toString((aByte & 0xff) + 0x100, 16).substring(1));
    }
    System.out.println(stringBuilder.toString());

让我们考虑第二行:

md.digest(inputStr.getBytes()).map(0xFF & _).map { "%02x".format(_) }.foldLeft("") {_ + _}
  1. md.digest(inputStr.getBytes()) ---- 从字符串中获取字节
  2. md.digest(inputStr.getBytes()).map(0xFF & _) --- 将位与数组的每个项 (map返回新数组)
  3. md.digest(inputStr.getBytes()).map(0xFF & ).map { "%02x".format() } 使用格式化格式映射每个项
  4. md.digest(inputStr.getBytes()).map(0xFF & ).map { "%02x".format() }.foldLeft("") {_ + _} 这是典型的折叠函数,在我们的例子中,从左侧开始并初始化值为"",(如果您觉得很容易,它就类似于在上面的示例中表现为StringBuilder)。我建议您阅读有关scala中折叠、缩减等操作的文章。例如:https://coderwall.com/p/4l73-a/scala-fold-foldleft-and-foldright

仅澄清上述内容:步骤2将Byte转换为Int(实际上并不必要,因为"%02x".format(_)也可以转换字节)。步骤3只是将Int转换为该数字的十六进制表示(也适用于字节)。 实际上,所有MD5工作都由digest函数完成。Scala在这里没有做任何特殊处理。 - handler
步骤2将数组的每个项目转换为字节,并使用按位&(0xFF-因为它是十六进制中的字节大小),步骤3将该值转换为十六进制。也许更清楚了。 - pacman
如果这篇文章有帮助,请标记为已回答。 - pacman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接