F# wrapper to generate SHA256 signature for a fileSimple wrapper for LocalReportLooking for identical files (or directories) in a filesystemHashing a SecureString using Cryptography Next GenerationEncryption wrapperWrapper class for adding elements to HashSetA hash-signature-type which tests on comparing against normal stringsRead through a log file to find “Fail” linesReading bytes from file to compute its SHA256 hashC++ syslog wrapperEncrypted safebox

Can't delete OU from AD, IsCriticalSystemObject attribute TRUE - cannot change

Can the Tidal Wave spell trigger a vampire's weakness to running water?

GitLab account hacked and repo wiped

Which "exotic salt" can lower water's freezing point by –70 °C?

What do you call a painting on a wall?

Where did Lovecraft write about Carcosa?

How do I, as a DM, handle a party that decides to set up an ambush in a dungeon?

Who filmed the Apollo 11 trans-lunar injection?

Is throwing dice a stochastic or a deterministic process?

Should I simplify my writing in a foreign country?

My first C++ game (snake console game)

Looking for sci-fi book based on Hinduism/Buddhism

Which US defense organization would respond to an invasion like this?

Is the book wrong about the Nyquist Sampling Criterion?

In "Avengers: Endgame", what does this name refer to?

How can a hefty sand storm happen in a thin atmosphere like Martian?

Game artist computer workstation set-up – is this overkill?

How do I allocate more memory to an app on Sheepshaver running Mac OS 9?

Is there a closed form, or cleaner way of writing this function?

Is any special diet an effective treatment of autism?

Constitutional limitation of criminalizing behavior in US law?

What happens if I accidentally leave an app running and click "Install Now" in Software Updater?

Counting the Number of Real Roots of A Polynomial

Is space itself expanding or is it just momentum from the Big Bang carrying things apart?



F# wrapper to generate SHA256 signature for a file


Simple wrapper for LocalReportLooking for identical files (or directories) in a filesystemHashing a SecureString using Cryptography Next GenerationEncryption wrapperWrapper class for adding elements to HashSetA hash-signature-type which tests on comparing against normal stringsRead through a log file to find “Fail” linesReading bytes from file to compute its SHA256 hashC++ syslog wrapperEncrypted safebox






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








4












$begingroup$


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.










share|improve this question











$endgroup$


















    4












    $begingroup$


    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.










    share|improve this question











    $endgroup$














      4












      4








      4





      $begingroup$


      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.










      share|improve this question











      $endgroup$




      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.







      file cryptography f# wrapper hashcode






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited May 1 at 16:07









      200_success

      132k20159424




      132k20159424










      asked May 1 at 15:01









      JacksonJackson

      270210




      270210




















          2 Answers
          2






          active

          oldest

          votes


















          4












          $begingroup$

          The use binding is usually better than the using function. The object is disposed when leaving the scope of the use binding (when leaving the SHA256 function).



          let SHA256 (file:FileInfo) =
          use hashFile = file.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
          use sha256Hash = SHA256Managed.Create()
          sha256Hash.ComputeHash(hashFile)


          You can avoid the use of a string builder by using String.concat. You can also use the F# sprintf function, which has slightly different format specifier syntax.



          let HexEncoded (hash:byte[]) :string =
          hash
          |> Array.map (sprintf "%02X")
          |> String.concat ""


          This might be slightly slower than your string builder because it requires an intermediate array. (Note that your implementation could remove the intermediate array by using Array.iter instead of Array.map and moving the ignore to inside the lambda.)






          share|improve this answer









          $endgroup$












          • $begingroup$
            The use binding is clearer, I was sort of trying to re-invent it with my wrap functions.
            $endgroup$
            – Jackson
            2 days ago


















          3












          $begingroup$

          I can only agree with TheQuickBrownFox.



          You can make even more dedicated functions and then compose them like:



          let computeHash (dataStream: Stream) (hasher: HashAlgorithm) = hasher.ComputeHash(dataStream)
          let openFile (fileInfo: FileInfo) = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)

          let getHash algorithmFactory fileInfo =
          use hasher = algorithmFactory()
          use stream = openFile fileInfo
          computeHash stream hasher

          let hexEncode hash = String.Join ("", hash |> Array.map (sprintf "%02X"))

          let fromAlgorithm algorithmFactory fileInfo = fileInfo |> getHash algorithmFactory |> hexEncode

          let fromSHA256 = fromAlgorithm SHA256Managed.Create
          let fromSHA512 = fromAlgorithm SHA512Managed.Create
          let fromMD5 = fromAlgorithm MD5.Create


          As shown, in this way it's easy to change the hash algorithm.



          let test () =
          let fi = new FileInfo(fileName)
          printfn "%A" (fromSHA256 fi)
          printfn "%A" (fromSHA512 fi)
          printfn "%A" (fromMD5 fi)





          share|improve this answer











          $endgroup$








          • 1




            $begingroup$
            Note that F#'s String.concat calls .NET's String.Join, so you can use String.concat and maintain the pipeline style like in my answer, without changing behaviour or performance 🙂
            $endgroup$
            – TheQuickBrownFox
            2 days ago











          • $begingroup$
            @TheQuickBrownFox: OK, thanks. I just thought I had to do something different than you :-)
            $endgroup$
            – Henrik Hansen
            2 days ago












          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f219505%2ff-wrapper-to-generate-sha256-signature-for-a-file%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          4












          $begingroup$

          The use binding is usually better than the using function. The object is disposed when leaving the scope of the use binding (when leaving the SHA256 function).



          let SHA256 (file:FileInfo) =
          use hashFile = file.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
          use sha256Hash = SHA256Managed.Create()
          sha256Hash.ComputeHash(hashFile)


          You can avoid the use of a string builder by using String.concat. You can also use the F# sprintf function, which has slightly different format specifier syntax.



          let HexEncoded (hash:byte[]) :string =
          hash
          |> Array.map (sprintf "%02X")
          |> String.concat ""


          This might be slightly slower than your string builder because it requires an intermediate array. (Note that your implementation could remove the intermediate array by using Array.iter instead of Array.map and moving the ignore to inside the lambda.)






          share|improve this answer









          $endgroup$












          • $begingroup$
            The use binding is clearer, I was sort of trying to re-invent it with my wrap functions.
            $endgroup$
            – Jackson
            2 days ago















          4












          $begingroup$

          The use binding is usually better than the using function. The object is disposed when leaving the scope of the use binding (when leaving the SHA256 function).



          let SHA256 (file:FileInfo) =
          use hashFile = file.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
          use sha256Hash = SHA256Managed.Create()
          sha256Hash.ComputeHash(hashFile)


          You can avoid the use of a string builder by using String.concat. You can also use the F# sprintf function, which has slightly different format specifier syntax.



          let HexEncoded (hash:byte[]) :string =
          hash
          |> Array.map (sprintf "%02X")
          |> String.concat ""


          This might be slightly slower than your string builder because it requires an intermediate array. (Note that your implementation could remove the intermediate array by using Array.iter instead of Array.map and moving the ignore to inside the lambda.)






          share|improve this answer









          $endgroup$












          • $begingroup$
            The use binding is clearer, I was sort of trying to re-invent it with my wrap functions.
            $endgroup$
            – Jackson
            2 days ago













          4












          4








          4





          $begingroup$

          The use binding is usually better than the using function. The object is disposed when leaving the scope of the use binding (when leaving the SHA256 function).



          let SHA256 (file:FileInfo) =
          use hashFile = file.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
          use sha256Hash = SHA256Managed.Create()
          sha256Hash.ComputeHash(hashFile)


          You can avoid the use of a string builder by using String.concat. You can also use the F# sprintf function, which has slightly different format specifier syntax.



          let HexEncoded (hash:byte[]) :string =
          hash
          |> Array.map (sprintf "%02X")
          |> String.concat ""


          This might be slightly slower than your string builder because it requires an intermediate array. (Note that your implementation could remove the intermediate array by using Array.iter instead of Array.map and moving the ignore to inside the lambda.)






          share|improve this answer









          $endgroup$



          The use binding is usually better than the using function. The object is disposed when leaving the scope of the use binding (when leaving the SHA256 function).



          let SHA256 (file:FileInfo) =
          use hashFile = file.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
          use sha256Hash = SHA256Managed.Create()
          sha256Hash.ComputeHash(hashFile)


          You can avoid the use of a string builder by using String.concat. You can also use the F# sprintf function, which has slightly different format specifier syntax.



          let HexEncoded (hash:byte[]) :string =
          hash
          |> Array.map (sprintf "%02X")
          |> String.concat ""


          This might be slightly slower than your string builder because it requires an intermediate array. (Note that your implementation could remove the intermediate array by using Array.iter instead of Array.map and moving the ignore to inside the lambda.)







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered May 1 at 16:05









          TheQuickBrownFoxTheQuickBrownFox

          52626




          52626











          • $begingroup$
            The use binding is clearer, I was sort of trying to re-invent it with my wrap functions.
            $endgroup$
            – Jackson
            2 days ago
















          • $begingroup$
            The use binding is clearer, I was sort of trying to re-invent it with my wrap functions.
            $endgroup$
            – Jackson
            2 days ago















          $begingroup$
          The use binding is clearer, I was sort of trying to re-invent it with my wrap functions.
          $endgroup$
          – Jackson
          2 days ago




          $begingroup$
          The use binding is clearer, I was sort of trying to re-invent it with my wrap functions.
          $endgroup$
          – Jackson
          2 days ago













          3












          $begingroup$

          I can only agree with TheQuickBrownFox.



          You can make even more dedicated functions and then compose them like:



          let computeHash (dataStream: Stream) (hasher: HashAlgorithm) = hasher.ComputeHash(dataStream)
          let openFile (fileInfo: FileInfo) = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)

          let getHash algorithmFactory fileInfo =
          use hasher = algorithmFactory()
          use stream = openFile fileInfo
          computeHash stream hasher

          let hexEncode hash = String.Join ("", hash |> Array.map (sprintf "%02X"))

          let fromAlgorithm algorithmFactory fileInfo = fileInfo |> getHash algorithmFactory |> hexEncode

          let fromSHA256 = fromAlgorithm SHA256Managed.Create
          let fromSHA512 = fromAlgorithm SHA512Managed.Create
          let fromMD5 = fromAlgorithm MD5.Create


          As shown, in this way it's easy to change the hash algorithm.



          let test () =
          let fi = new FileInfo(fileName)
          printfn "%A" (fromSHA256 fi)
          printfn "%A" (fromSHA512 fi)
          printfn "%A" (fromMD5 fi)





          share|improve this answer











          $endgroup$








          • 1




            $begingroup$
            Note that F#'s String.concat calls .NET's String.Join, so you can use String.concat and maintain the pipeline style like in my answer, without changing behaviour or performance 🙂
            $endgroup$
            – TheQuickBrownFox
            2 days ago











          • $begingroup$
            @TheQuickBrownFox: OK, thanks. I just thought I had to do something different than you :-)
            $endgroup$
            – Henrik Hansen
            2 days ago
















          3












          $begingroup$

          I can only agree with TheQuickBrownFox.



          You can make even more dedicated functions and then compose them like:



          let computeHash (dataStream: Stream) (hasher: HashAlgorithm) = hasher.ComputeHash(dataStream)
          let openFile (fileInfo: FileInfo) = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)

          let getHash algorithmFactory fileInfo =
          use hasher = algorithmFactory()
          use stream = openFile fileInfo
          computeHash stream hasher

          let hexEncode hash = String.Join ("", hash |> Array.map (sprintf "%02X"))

          let fromAlgorithm algorithmFactory fileInfo = fileInfo |> getHash algorithmFactory |> hexEncode

          let fromSHA256 = fromAlgorithm SHA256Managed.Create
          let fromSHA512 = fromAlgorithm SHA512Managed.Create
          let fromMD5 = fromAlgorithm MD5.Create


          As shown, in this way it's easy to change the hash algorithm.



          let test () =
          let fi = new FileInfo(fileName)
          printfn "%A" (fromSHA256 fi)
          printfn "%A" (fromSHA512 fi)
          printfn "%A" (fromMD5 fi)





          share|improve this answer











          $endgroup$








          • 1




            $begingroup$
            Note that F#'s String.concat calls .NET's String.Join, so you can use String.concat and maintain the pipeline style like in my answer, without changing behaviour or performance 🙂
            $endgroup$
            – TheQuickBrownFox
            2 days ago











          • $begingroup$
            @TheQuickBrownFox: OK, thanks. I just thought I had to do something different than you :-)
            $endgroup$
            – Henrik Hansen
            2 days ago














          3












          3








          3





          $begingroup$

          I can only agree with TheQuickBrownFox.



          You can make even more dedicated functions and then compose them like:



          let computeHash (dataStream: Stream) (hasher: HashAlgorithm) = hasher.ComputeHash(dataStream)
          let openFile (fileInfo: FileInfo) = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)

          let getHash algorithmFactory fileInfo =
          use hasher = algorithmFactory()
          use stream = openFile fileInfo
          computeHash stream hasher

          let hexEncode hash = String.Join ("", hash |> Array.map (sprintf "%02X"))

          let fromAlgorithm algorithmFactory fileInfo = fileInfo |> getHash algorithmFactory |> hexEncode

          let fromSHA256 = fromAlgorithm SHA256Managed.Create
          let fromSHA512 = fromAlgorithm SHA512Managed.Create
          let fromMD5 = fromAlgorithm MD5.Create


          As shown, in this way it's easy to change the hash algorithm.



          let test () =
          let fi = new FileInfo(fileName)
          printfn "%A" (fromSHA256 fi)
          printfn "%A" (fromSHA512 fi)
          printfn "%A" (fromMD5 fi)





          share|improve this answer











          $endgroup$



          I can only agree with TheQuickBrownFox.



          You can make even more dedicated functions and then compose them like:



          let computeHash (dataStream: Stream) (hasher: HashAlgorithm) = hasher.ComputeHash(dataStream)
          let openFile (fileInfo: FileInfo) = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)

          let getHash algorithmFactory fileInfo =
          use hasher = algorithmFactory()
          use stream = openFile fileInfo
          computeHash stream hasher

          let hexEncode hash = String.Join ("", hash |> Array.map (sprintf "%02X"))

          let fromAlgorithm algorithmFactory fileInfo = fileInfo |> getHash algorithmFactory |> hexEncode

          let fromSHA256 = fromAlgorithm SHA256Managed.Create
          let fromSHA512 = fromAlgorithm SHA512Managed.Create
          let fromMD5 = fromAlgorithm MD5.Create


          As shown, in this way it's easy to change the hash algorithm.



          let test () =
          let fi = new FileInfo(fileName)
          printfn "%A" (fromSHA256 fi)
          printfn "%A" (fromSHA512 fi)
          printfn "%A" (fromMD5 fi)






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 2 days ago

























          answered May 1 at 19:57









          Henrik HansenHenrik Hansen

          8,57211231




          8,57211231







          • 1




            $begingroup$
            Note that F#'s String.concat calls .NET's String.Join, so you can use String.concat and maintain the pipeline style like in my answer, without changing behaviour or performance 🙂
            $endgroup$
            – TheQuickBrownFox
            2 days ago











          • $begingroup$
            @TheQuickBrownFox: OK, thanks. I just thought I had to do something different than you :-)
            $endgroup$
            – Henrik Hansen
            2 days ago













          • 1




            $begingroup$
            Note that F#'s String.concat calls .NET's String.Join, so you can use String.concat and maintain the pipeline style like in my answer, without changing behaviour or performance 🙂
            $endgroup$
            – TheQuickBrownFox
            2 days ago











          • $begingroup$
            @TheQuickBrownFox: OK, thanks. I just thought I had to do something different than you :-)
            $endgroup$
            – Henrik Hansen
            2 days ago








          1




          1




          $begingroup$
          Note that F#'s String.concat calls .NET's String.Join, so you can use String.concat and maintain the pipeline style like in my answer, without changing behaviour or performance 🙂
          $endgroup$
          – TheQuickBrownFox
          2 days ago





          $begingroup$
          Note that F#'s String.concat calls .NET's String.Join, so you can use String.concat and maintain the pipeline style like in my answer, without changing behaviour or performance 🙂
          $endgroup$
          – TheQuickBrownFox
          2 days ago













          $begingroup$
          @TheQuickBrownFox: OK, thanks. I just thought I had to do something different than you :-)
          $endgroup$
          – Henrik Hansen
          2 days ago





          $begingroup$
          @TheQuickBrownFox: OK, thanks. I just thought I had to do something different than you :-)
          $endgroup$
          – Henrik Hansen
          2 days ago


















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f219505%2ff-wrapper-to-generate-sha256-signature-for-a-file%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Get product attribute by attribute group code in magento 2get product attribute by product attribute group in magento 2Magento 2 Log Bundle Product Data in List Page?How to get all product attribute of a attribute group of Default attribute set?Magento 2.1 Create a filter in the product grid by new attributeMagento 2 : Get Product Attribute values By GroupMagento 2 How to get all existing values for one attributeMagento 2 get custom attribute of a single product inside a pluginMagento 2.3 How to get all the Multi Source Inventory (MSI) locations collection in custom module?Magento2: how to develop rest API to get new productsGet product attribute by attribute group code ( [attribute_group_code] ) in magento 2

          Category:9 (number) SubcategoriesMedia in category "9 (number)"Navigation menuUpload mediaGND ID: 4485639-8Library of Congress authority ID: sh85091979ReasonatorScholiaStatistics

          Magento 2.3: How do i solve this, Not registered handle, on custom form?How can i rewrite TierPrice Block in Magento2magento 2 captcha not rendering if I override layout xmlmain.CRITICAL: Plugin class doesn't existMagento 2 : Problem while adding custom button order view page?Magento 2.2.5: Overriding Admin Controller sales/orderMagento 2.2.5: Add, Update and Delete existing products Custom OptionsMagento 2.3 : File Upload issue in UI Component FormMagento2 Not registered handleHow to configured Form Builder Js in my custom magento 2.3.0 module?Magento 2.3. How to create image upload field in an admin form