生成C#运行哈希(或校验)?(Generate Running Hash (or Checksum)

2019-09-18 00:18发布

前言:

我做一个数据导入具有验证提交阶段。 其思想是:第一阶段允许采取来自各种源的数据,然后运行的各种插入/更新/验证数据库的操作。 提交回滚,但产生“验证哈希/校验”。 提交阶段是相同的,但是,如果“验证哈希/校验”是相同的,则操作将被提交。 (该数据库将在适当的隔离级别上运行。)

限制:

  • 输入阅读和操作前阅读,仅一次
  • 不想预先创建一个流(例如写的MemoryStream不可取的),因为可能会有大量的数据。 (它的工作对我们的服务器/负载,但假装记忆是有限的。)
  • 不要想“创造我自己的”。 (我知道喜欢使用的码的达米安CRC-32 ,我可以使用/修改,但会喜欢的东西“标准”)。

而我(觉得我)寻找:

一种方法来生成基于输入+操作的哈希(如SHA1或MD5?)或校验和(例如CRC32但希望更多)。 (输入/操作可以自己来散列到值更贴合的校验和生成,但它会很美好,只是为了能够“写蒸”。)

所以,问题是:

如何生成在C#中运行哈希(或校验)?

此外,虽然有CRC32实现,可以为运行的操作进行修改,有关运行SHAx或MD5哈希值是什么?

我缺少某种得心应手流方法的比可以作为一个适配器?

(批判的欢迎,也请回答上述适用的。另外,我宁愿不处理线程。;-)

Answer 1:

哈希有一个建立和确定阶段。 您可以在构建阶段推数据的任意金额。 只要你喜欢的数据可以被分解。 最后,完成了哈希运算,让你的哈希值。

您可以使用一个可写的CryptoStream来写你的数据。 这是最简单的方法。



Answer 2:

您可以拨打HashAlgorithm.TransformBlock多次,然后调用TransformFinalBlock会给你所有块的结果。

块您的输入(通过从蒸汽中读取字节的x量),并调用TransformBlock与每个组块。

编辑(从MSDN示例):

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));
}

对不起,我没有任何例子随手可得,但对你来说,你基本上更换input用自己的一块,那么size将是该块的字节数。 你必须保持轨道的偏置自己。



Answer 3:

您可以生成使用MD5哈希MD5CryptoServiceProvider的ComputeHash方法。 它需要一个流作为输入。

创建一个内存或文件流,写你的哈希输入到,然后调用ComputeHash方法,当你完成。

var myStream = new MemoryStream();

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

myStream.Position = 0;

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

编辑:一种可能性,以避免建立大规模流调用此遍地在环和异或结果:

// 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];

编辑#2:最后,下面的基础上@ USR的回答,您可以可能使用HashCore和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();
}


Answer 4:

这是规范的方法:

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();
}


文章来源: Generate Running Hash (or Checksum) in C#?
标签: c# hash checksum