Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#中生成运行哈希(或校验和)?_C#_Hash_Checksum - Fatal编程技术网

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

在C#中生成运行哈希(或校验和)?,c#,hash,checksum,C#,Hash,Checksum,前言: 我正在做一个数据导入,它有一个验证提交阶段。其思想是:第一阶段允许从各种来源获取数据,然后在数据库上运行各种插入/更新/验证操作。提交会回滚,但会生成“验证哈希/校验和”。提交阶段相同,但是,如果“验证哈希/校验和”相同,则将提交操作。(数据库将在适当的隔离级别下运行。) 限制: 输入读取和操作仅向前读取一次 不希望预创建流(例如,不希望写入MemoryStream),因为可能存在大量数据。(它可以在我们的服务器/负载上工作,但假设内存有限。) 不想“创造我自己”。(我知道可以使用/修

前言:

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

限制:

  • 输入读取和操作仅向前读取一次
  • 不希望预创建流(例如,不希望写入MemoryStream),因为可能存在大量数据。(它可以在我们的服务器/负载上工作,但假设内存有限。)
  • 不想“创造我自己”。(我知道可以使用/修改的可用代码,但更喜欢“标准”代码。)
我(认为我)在寻找什么:

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

因此,问题是:

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

另外,虽然有一些CRC32实现可以针对运行的操作进行修改,但运行SHAx或MD5哈希又如何呢

我是否缺少了一些可以用作适配器的便捷流方法

(欢迎评论,但也请回答上述问题。此外,我不希望处理线程。;-

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

将您的输入分块(通过从steam读取x个字节),并使用每个分块调用
TransformBlock

编辑(来自msdn示例):


很抱歉,我没有现成的示例,不过对于您来说,您基本上是用自己的块替换
input
,那么
size
就是该块中的字节数。您必须自己跟踪偏移量。

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

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

var myStream = new MemoryStream();

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

myStream.Position = 0;

using (var csp = new MD5CryptoServiceProvider()) {
    var myHash = csp.ComputeHash(myStream);
}
编辑:避免建立大量流的一种可能性是在循环中反复调用此函数并对结果进行XORing:

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

哈希有一个构建和最终确定阶段。您可以在构建阶段插入任意数量的数据。数据可以根据需要进行拆分。最后,完成散列操作并获取散列


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

这是标准方法:

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();
}
使用系统;
使用System.Security.Cryptography;
使用系统文本;
public void CreateHash(字符串sSourceData)
{
字节[]源字节;
字节[]哈希字节;
//从源数据创建Bytearray
sourceBytes=ascienceoding.ASCII.GetBytes(sSourceData);
//计算16字节哈希码
hashBytes=新的MD5CryptoServiceProvider().ComputeHash(sourceBytes);
字符串sOutput=byteArrayTohextString(hashBytes);
}
静态字符串ByteArrayToHexString(字节[]arrInput)
{
int i;
StringBuilder sOutput=新的StringBuilder(arrInput.Length);
对于(i=0;i
如何运行导入两次,同时只读取一次输入而不进行缓冲?@usr我的意思是每次运行“读取一次”。也就是说,不要先在输入流上运行散列。好吧,“运行散列”有什么属性呢?@usr最好是一个可以用作流式方式的属性(在这种方式中,我不断地插入数据,并在所有内容写入数据后得到结果)。然而,实际的“实力”要求有些模糊;CRC32可能足够了,但是。。。这没那么有趣:-)@pst,就我自己的教育而言,验证/提交这个东西是用来做什么的(它解决了什么问题)?为什么同样的事情要做两次,但只在第二次运行时提交?你能发布一个代码示例和解释吗?我认为这是一种方法,但很难理解它是如何工作的。谢谢你的例子,我现在可以理解它(+1)。问题是我不想要中间(内存中)流(或额外的物化IO),除非我无法正确使用流……如果你已经有了流,就使用那个流。否则,您可能需要一个中间流,因为大多数真正的哈希算法都使用一个中间流作为输入。如果你有字节数组,那么按照上面@Matthew的答案使用TransformBlock方法。我有一个我使用的输入流(前向只读)。不幸的是,我没有[另一条]要分发的信息流。我还需要能够将“操作”写入流,因为知道将发生什么是重要的。我可以使用MemoryStream,例如写入,然后用作计算Hash的提要,但我希望它能够“运行”计算,而不会堆积中间数据。@pst为HashCore和HashFinal添加了示例,这可能是最好的方法。它的名称听起来好像走对了轨道。有文档的链接吗?(我已经在看了,但这是一个答案;-)@pst我认为这是HashCore和HashFinal。请看,是的,我以前使用过这种方法,但它要求在调用
ComputeHash
函数时所有数据都存在:(好的,我知道了。然后任何TransformBlock实现都可以,MD5、SHA256等等。
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();
}
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();
}