因此,我想知道如何使用java.security.MessageDigest来生成文件摘要?
我希望使用常量内存缓冲区大小(例如,4KB)来完成此操作。我想我知道如何从读取文件开始,但我很难理解如何:
1)对每个4KB调用digest.update(buf),这实际上是对MessageDigest实例的一个副作用,我猜这应该发生在stream框架中。
2)最后调用digest.digest()从scalaz流框架内接收计算出的摘要有哪些?
我想我知道该怎么开始了:
import scalaz.stream._
import java.security.MessageDigest
val f = "/a/b/myfile.bin"
val bufSize = 4096
val digest = MessageDigest.getInstance("SHA-256")
Process.constant(bufSize).toSource
.through(io.fileChunkR(f, bufSize))但我被卡住了!有什么提示吗?我想它也必须能够包装创建,更新,检索(实际摘要计算)和破坏摘要对象在一个黄曲柳水槽或什么,然后调用.to()传入那个水槽?对不起,如果我使用了错误的术语,我是全新的使用黄曲柳。我已经看过几个例子,但仍在挣扎。
发布于 2014-08-20 18:54:17
从0.4版开始,scalaz流包含计算摘要的进程。它们可以在hash模块中使用,并在引擎盖下使用java.security.MessageDigest。下面是一个最低限度的示例,说明如何使用它们:
import scalaz.concurrent.Task
import scalaz.stream._
object Sha1Sum extends App {
val fileName = "testdata/celsius.txt"
val bufferSize = 4096
val sha1sum: Task[Option[String]] =
Process.constant(bufferSize)
.toSource
.through(io.fileChunkR(fileName, bufferSize))
.pipe(hash.sha1)
.map(sum => s"${sum.toHex} $fileName")
.runLast
sha1sum.run.foreach(println)
}update()和digest()调用都包含在hash.sha1 Process1中。
发布于 2014-08-20 08:50:56
所以我有一些有用的东西,但是它可能会被改进:
import java.io._
import java.security.MessageDigest
import resource._
import scodec.bits.ByteVector
import scalaz._, Scalaz._
import scalaz.concurrent.Task
import scalaz.stream._
import scalaz.stream.io._
val f = "/a/b/myfile.bin"
val bufSize = 4096
val md = MessageDigest.getInstance("SHA-256")
def _digestResource(md: => MessageDigest): Sink[Task,ByteVector] =
resource(Task.delay(md))(md => Task.delay(()))(
md => Task.now((bytes: ByteVector) => Task.delay(md.update(bytes.toArray))))
Process.constant(4096).toSource
.through(fileChunkR(f.getAbsolutePath, 4096))
.to(_digestResource(md))
.run
.run
md.digest()然而,在我看来,应该有一种更干净的方法来做到这一点,方法是将MessageDigest的创建移到黄曲柳中,并让最终的.run产生md.digest()。
更好的答案欢迎..。
https://stackoverflow.com/questions/25394515
复制相似问题