SHA256 data stream

I have a use case where I download a file from a URL using a GET request. Is it possible to compute the SHA256 of a file stream without saving to disk or storing the entire object in memory?

+4


source to share


3 answers


This can be done with and U): akka.stream.scaladsl.Sink [T, scala.concurrent.Future [U]] rel = "nofollow noreferrer"> . MessageDigest

Sink.fold

First, we need a function to create an empty digest and a function to update the digest with : ByteBuffer

import java.security.MessageDigest
import java.nio.ByteBuffer

def emptySHA256Digest : MessageDigest = MessageDigest getInstance "SHA-256" 

val updateDigest : (MessageDigest, ByteBuffer) => MessageDigest = 
  (messageDigest, byteBuffer) => {
    messageDigest update byteBuffer
    messageDigest
  }

      



These two functions can then be used in a fold that is applied to entity

HttpResponse

to update the digest with all values ByteString

in the object:

import akka.http.scaladsl.model.HttpResponse

val responseBodyToDigest : HttpResponse => Future[MessageDigest] = 
  (_ : HttpResponse)
    .entity
    .dataBytes
    .map(_.asByteBuffer)
    .runFold(emptySHA256Digest)(updateDigest)

      

+3


source


You will need Flow

one that converts the data to other data. In your case, you want to convert text to sha256 text.

 def digest(algorithm: String = "SHA-256"): Flow[ByteString, ByteString, NotUsed] = {
Flow[ByteString].fold(MessageDigest.getInstance(algorithm)){
  case (digest: MessageDigest, bytes:ByteString) => {digest.update(bytes.asByteBuffer); digest}}
  .map {case md: MessageDigest => ByteString(md.digest())}

      



}

+2


source


Use one of the methods MessageDigest.getInstance("SHA-256").update

.

Transfer your file piece by piece.

Then call digest()

Sample code:

    MessageDigest instance = MessageDigest.getInstance("SHA-256");
    for(byte[] arr: source){
        instance.update(arr);
    }
    byte[] result = instance.digest();

      

+1


source







All Articles