序:
我正在进行具有验证提交阶段的数据导入。我们的想法是:第一阶段允许从各种来源获取数据,然后在数据库上运行各种插入/更新/验证操作。提交将回滚,但会生成“验证哈希/校验和”。提交阶段是相同的,但是,如果“验证散列/校验和”相同,则将提交操作。 (数据库将在适当的隔离级别下运行。)
限制:
我(我想)正在寻找:
基于输入+操作生成哈希(例如SHA1或MD5?)或校验和(例如CRC32但希望更多)的方法。 (输入/操作本身可以被散列为更适合校验和生成的值,但是能够“写入steam”会很好。)
所以,问题是:
如何在C#中生成Running Hash(或Checksum)?
此外,虽然可以针对Running操作修改CRC32实现,但是运行SHAx或MD5哈希呢?
我是否缺少某种方便的Stream方法而不能用作适配器?
(欢迎批评,但也请在适用的情况下回答上述内容。另外,我不想处理线程。; - )
答案 0 :(得分:9)
您可以多次致电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
将是该块中的字节数。您必须自己跟踪偏移量。
答案 1 :(得分:4)
哈希有一个构建和完成阶段。您可以在构建阶段推送任意数量的数据。可以根据需要拆分数据。最后,完成哈希操作并获取哈希值。
您可以使用可写CryptoStream来编写数据。 这是最简单的方式。
答案 2 :(得分:2)
您可以使用MD5CryptoServiceProvider的ComputeHash方法生成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);
}
编辑:避免构建大量Streams的一种可能性是在循环中反复调用它并对结果进行异或运行:
// 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();
}
答案 3 :(得分:0)
这是规范的方式:
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();
}