I've created the following module to allow me to generate a SHA256 signature for a file. (In real life this is used to verify an image file hasn't been amended). The cut down code looks like this:
open System.IO
open System.Text
open System.Security.Cryptography;
// Get the SHA256 hash of a file
let SHA256 (file:FileInfo) =
let FileSHA256Wrap (hashFile : FileStream) (sha256Hash : SHA256) : byte[] =
sha256Hash.ComputeHash(hashFile)
let FileWrap (hashFile : FileStream) : byte[] =
using (SHA256Managed.Create()) (FileSHA256Wrap hashFile)
using (file.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) FileWrap
// Convert the byte[] version of the hash to a printable encoded HEX string
let HexEncoded (hash:byte[]) :string =
let sb = new StringBuilder(hash.Length * 2)
hash |> Array.map (fun c -> sb.AppendFormat("{0:X2}",c)) |> ignore
sb.ToString()
// Get the file hash and convert it to a HEX string
let HexEncodedSHA256 (file:FileInfo) =
file |> SHA256 |> HexEncoded
let fi = new FileInfo("somefile.tif")
HexEncodedSHA256 fi
I've two questions here, with the double using
statements I find the wrap functions help me work out what is going on - but is there a neater and more succinct way to write this without making it hard to work out what is happening?
The implementation of HexEncoded uses a string builder, is there a more functional way to do this.