Generate Running Hash (or Checksum) in C#?

淺唱寂寞╮ 提交于 2019-12-05 16:17:38

Hashes have a build and a finalization phase. You can shove arbitrary amounts of data in during the build phase. The data can be split up as you like. Finally, you finish the hash operation and get your hash.

You can use a writable CryptoStream to write your data. This is the easiest way.

You can call HashAlgorithm.TransformBlock multiple times, and then calling TransformFinalBlock will give you the result of all blocks.

Chunk up your input (by reading x amount of bytes from a steam) and call TransformBlock with each chunk.

EDIT (from the msdn example):

public static void PrintHashMultiBlock(byte[] input, int size)
{
    SHA256Managed sha = new SHA256Managed();
    int offset = 0;

    while (input.Length - offset >= size)
        offset += sha.TransformBlock(input, offset, size, input, offset);

    sha.TransformFinalBlock(input, offset, input.Length - offset);
    Console.WriteLine("MultiBlock {0:00}: {1}", size, BytesToStr(sha.Hash));
}

Sorry I don't have any example readily available, though for you, you're basically replacing input with your own chunk, then the size would be the number of bytes in that chunk. You will have to keep track of the offset yourself.

You can generate an MD5 hash using the MD5CryptoServiceProvider's ComputeHash method. It takes a stream as input.

Create a memory or file stream, write your hash inputs to that, and then call the ComputeHash method when you are done.

var myStream = new MemoryStream();

// Blah blah, write to the stream...

myStream.Position = 0;

using (var csp = new MD5CryptoServiceProvider()) {
    var myHash = csp.ComputeHash(myStream);
}

EDIT: One possibility to avoid building up massive Streams is calling this over and over in a loop and XORing the results:

// Assuming we had this somewhere:
Byte[] myRunningHash = new Byte[16];

// Later on, from above:
for (var i = 0; i < 16; i++) // I believe MD5 are 16-byte arrays.  Edit accordingly.
    myRunningHash[i] = myRunningHash[i] ^ [myHash[i];

EDIT #2: Finally, building on @usr's answer below, you can probably use HashCore and HashFinal:

using (var csp = new MD5CryptoServiceProvider()) {

    // My example here uses a foreach loop, but an 
    // event-driven stream-like approach is 
    // probably more what you are doing here.
    foreach (byte[] someData in myDataThings)
        csp.HashCore(someData, 0, someData.Length);

    var myHash = csp.HashFinal();
}

this is the canonical way:

using System;
using System.Security.Cryptography;
using System.Text;

public void CreateHash(string sSourceData)
{
    byte[] sourceBytes;
    byte[] hashBytes;

    //create Bytearray from source data
    sourceBytes = ASCIIEncoding.ASCII.GetBytes(sSourceData);

    // calculate 16 Byte Hashcode
    hashBytes = new MD5CryptoServiceProvider().ComputeHash(sourceBytes);
    string sOutput = ByteArrayToHexString(hashBytes);
 }

static string ByteArrayToHexString(byte[] arrInput)
{
    int i;
    StringBuilder sOutput = new StringBuilder(arrInput.Length);
    for (i = 0; i < arrInput.Length - 1; i++)
    {
        sOutput.Append(arrInput[i].ToString("X2"));
    }
    return sOutput.ToString();
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!