Java 在Scala中,如何像Ruby的.pack(“N”)一样,将四个字符按网络字节顺序作为无符号长字符来打包?

Java 在Scala中,如何像Ruby的.pack(“N”)一样,将四个字符按网络字节顺序作为无符号长字符来打包?,java,ruby,scala,endianness,Java,Ruby,Scala,Endianness,这是Ruby等价物 [Digest::MD5.hexdigest("Data to pack").to_i(16)].pack("N") 输出:\x1AP0\\ 生成的大整数为md5哈希 321255238386231367014342192054081171548 在Scala中,我得到了BigInt,如下所示 def md5Hash(input: String): String = md5HashArr(input.getBytes(StandardCharsets.UTF_8)) de

这是Ruby等价物

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

生成的大整数为md5哈希

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
val hexStr:String = bytes2hexStr(resultAsByteArray)
在转换为十六进制str之前,如下所示

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
val hexStr:String = bytes2hexStr(resultAsByteArray)
我如何在Scala中执行同样的操作


感谢您的帮助。

对于Ruby中的BigNum,似乎pack方法只能打包最后32位4字节。因此,对于这个散列f1af822290cfcac4ce476a691a5035c

显示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)
  }
}

我认为scala没有数组的直接等价物。packA bigint可能有8字节长,64位,所以您打算在这里只取一半的值吗?谢谢@ArtavazdBalayan的回答,很抱歉造成混淆,我更新了这个问题。实际上,我需要的是Ruby Array.pack'N所做的工作,例如\x1AP0\\。这是repl.it中的在线示例https://repl.it/@ziyasal/differentitupsethanumankey,@ziyasal,根据您的需要进行了修复谢谢,这很清楚,但是我如何获得像Ruby这样的位字符串表示;例如,此示例中的输出lorem ipsum dolor sit生成\xD1\xDF\x03[并包含类似于[这是我正在努力解决的问题。对于示例repl:repl.it/@ziyasal/DifferentUpsetHanumanmonkey@ziyasal.它只是字节,用字符串表示。下面是一个如何用UTF-8字符表示字节的示例。它显示了�' 如果UTF-8=>不存在这个字符代码,但我真的不明白为什么需要使用字符串而不是字节。