在 Scala 中,如何像 Ruby 的 .pack(“N”) 那样打包将四个字符视为无符号长整数的 BigInt?

How can I pack a BigInt treating four characters as an unsigned long in network byte order as Ruby's .pack(“N”) does, in Scala?

这里是Ruby等价物

[Digest::MD5.hexdigest("Data to pack").to_i(16)].pack("N")

输出:"\x1AP0\"

生成的大整数为(md5 hash);

321255238386231367014342192054081171548

在 Scala 中,我按如下方式获得了 BigInt;

def md5Hash(input: String): String = md5HashArr(input.getBytes(StandardCharsets.UTF_8))
def md5HashArr(bytes: Array[Byte]): String = {
    val digest = java.security.MessageDigest.getInstance("MD5")
    digest.reset()
    digest.update(bytes)
    digest.digest().map(0xFF & _).map {
      "%02x".format(_)
    }.foldLeft("") {
      _ + _
    }
  }

def hex2dec(hex: String): BigInt = {
    hex.toLowerCase().toList.map(
      "0123456789abcdef".indexOf(_)).map(
      BigInt(_)).reduceLeft(_ * 16 + _)
 }

def bytes2hexStr(bytes: Array[Byte], sep: String = ""): String = bytes.map("0x%02x".format(_)).mkString(sep)


val result: BigInt = hex2dec(md5Hash("Data to pack"))
val resultAsByteArray: Array[Byte] = result.toByteArray

在转换为十六进制 str 之前;

val hexStr:String = bytes2hexStr(resultAsByteArray)

我如何在 Scala 中做同样的事情?

感谢您的帮助。

Ruby 中的 BigNum 的打包方法似乎只会打包最后的 32 位(4 字节)。所以,对于这个散列 f1af822290cfcac4ce476a691a50305c

[Digest::MD5.hexdigest("Data to pack").to_i(16)]
.pack("N")
.each_byte.map { |b| sprintf("0x%02X ",b) }.join

显示 0x1A 0x50 0x30 0x5C,这是最后 4 个字节

具有相同行为的 Scala 实现:

import java.security.MessageDigest
import java.nio._
import java.io._

import scala.annotation.tailrec

object MD5 {
  def main(args: Array[String]) =  {
    val str = "Data to pack"
    val md5Bytes = calcMd5(str)
    val md5Str = md5Bytes.map(b => "%02x".format(b)).mkString
    println(s"$str => $md5Str")

    // Get last 4-bytes
    val byteArr = md5Bytes.slice(12, 16)

    // Print it
    print(s"Last 4-bytes => ")
    byteArr.foreach { r =>
      print("%02X ".format(r))
    }
    println

  }  

  def calcMd5(str: String): Array[Byte] = {
    MessageDigest.getInstance("MD5")
    .digest(str.getBytes)
  }
}