在 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)
}
}
这里是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)
}
}