首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C#中生成正在运行的哈希(或校验和)?

在C#中生成正在运行的哈希(或校验和)?
EN

Stack Overflow用户
提问于 2012-06-11 18:08:06
回答 4查看 5.3K关注 0票数 5

前言:

我正在执行一个具有验证提交阶段的数据导入。其思想是:第一阶段允许从各种来源获取数据,然后在数据库上运行各种insert/update/validate操作。提交将回滚,但将生成“验证散列/校验和”。提交阶段是相同的,但是,如果“验证散列/校验和”是相同的,那么操作将被提交。(数据库将在适当的隔离级别下运行。)

限制:

  • 输入读取和操作仅为前读一次。
  • 不想预先创建一个流(例如,写入MemoryStream不可取),因为可能有很多数据。(它可以在我们的服务器/负载上工作,但假装内存有限。)
  • 不想“创造自己”。(我知道Damien的CRC-32这样的可用代码,我可以使用/修改这些代码,但更喜欢“标准”代码。)

我(认为我)想要的是:

生成哈希的一种方法(例如SHA1或MD5?)或者基于输入+操作的校验和(例如CRC32,但希望更多)。(输入/操作本身可以散列为更适合校验和生成的值,但只要能够“写到蒸汽”就好了)。

因此,问题是:

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

另外,虽然可以为运行中的操作修改CRC32实现,但是运行SHAx或MD5哈希怎么办?

我是不是错过了一种可以用作适配器的方便的流方法?

(欢迎批评,但请在适用时也回答上述问题。另外,我不想处理线程。;-)

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-06-11 18:15:17

散列有一个构建阶段和一个最后阶段。在构建阶段,您可以插入任意数量的数据。数据可以根据您的喜好进行分割。最后,完成哈希操作并获得哈希。

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

票数 5
EN

Stack Overflow用户

发布于 2012-06-11 18:13:44

您可以多次调用HashAlgorithm.TransformBlock,然后调用TransformFinalBlock将给出所有块的结果。

将输入分块(从蒸汽中读取x个字节),并使用每个块调用TransformBlock

编辑(来自msdn示例):

代码语言:javascript
复制
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就是这个块中的字节数。你必须自己跟踪偏移量。

票数 9
EN

Stack Overflow用户

发布于 2012-06-11 18:14:39

您可以使用MD5的ComputeHash方法生成一个ComputeHash哈希,它接受一个流作为输入。

创建内存或文件流,将哈希输入写入其中,然后在完成后调用ComputeHash方法。

代码语言:javascript
复制
var myStream = new MemoryStream();

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

myStream.Position = 0;

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

编辑:避免建立大量流的一种可能是在循环中反复调用它,并将结果XORing:

代码语言:javascript
复制
// 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:

代码语言:javascript
复制
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();
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10985282

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档