如何获得代表文件集合的校验和?
How to get a checksum that represents a collection of files?
我想知道如果给定一组文件,这些文件中的任何一个是否发生了变化。
我知道对于单个文件,您可以使用这种方法获取校验和值,您可以使用该值来检查是否发生了更改。 IE。这个 returns 给定文件的相同值,直到该文件中的某些内容发生更改,然后它将生成不同的哈希值:
byte[] hashBytes;
using(var inputFileStream = File.Open(filePath))
{
var md5 = MD5.Create();
hashBytes = md5.ComputeHash(inputFileStream);
}
string s = Convert.ToBase64String(hashBytes);
有没有办法获取哈希值集合并从该集合中获取哈希值?
List<byte[]> hashCollection = SomeFunctionThatReturnsListByteArray();
//some approach that can create a hash of this
我的主要目标是检测是否发生了变化。我不关心更改了哪个文件。
散列哈希不是最优的。但是,如果您不想将所有文件散列在一起,您可以轻松地将散列添加到内存流并对其进行散列。
忽略任何其他概念性或其他方面的问题。
public static byte[] Hash(IEnumerable<byte[]> source)
{
using var hash = SHA256.Create();
var ms = new MemoryStream();
foreach (var bytes in source)
ms.Write(bytes, 0, bytes.Length);
ms.Seek(0, SeekOrigin.Begin);
return hash.ComputeHash(ms);
}
注意 : 我并不是说这是最好的解决方案,它只是解决您眼前问题的方法
稍微少一点的分配方法
public static byte[] Hash(IList<byte[]> source)
{
using var hash = SHA256.Create();
var ms = new MemoryStream(source.Sum(x =>x.Length));
foreach (var bytes in source)
ms.Write(bytes, 0, bytes.Length);
ms.Seek(0, SeekOrigin.Begin);
return hash.ComputeHash(ms);
}
对于多文件哈希(未测试)
public static byte[] Hash(IEnumerable<string> source)
{
using var hash = SHA256.Create();
hash.Initialize();
// adjust to what is fastest for you, for hdd 4k to 10k might be appropriate.
// for ssd larger will likely help
// probably best to keep it under 80k so it doesn't end up on LOH (up to you)
const int bufferSize = 1024 * 50;
var buffer = new byte[bufferSize];
foreach (var file in source)
{
using var fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Delete, bufferSize, FileOptions.SequentialScan);
var bytesRead = 0;
while ((bytesRead = fs.Read(buffer, 0, bufferSize)) != 0)
hash.TransformBlock(buffer, 0, bytesRead, buffer, 0);
hash.TransformFinalBlock(buffer, 0, 0);
}
return hash.Hash;
}
我想知道如果给定一组文件,这些文件中的任何一个是否发生了变化。
我知道对于单个文件,您可以使用这种方法获取校验和值,您可以使用该值来检查是否发生了更改。 IE。这个 returns 给定文件的相同值,直到该文件中的某些内容发生更改,然后它将生成不同的哈希值:
byte[] hashBytes;
using(var inputFileStream = File.Open(filePath))
{
var md5 = MD5.Create();
hashBytes = md5.ComputeHash(inputFileStream);
}
string s = Convert.ToBase64String(hashBytes);
有没有办法获取哈希值集合并从该集合中获取哈希值?
List<byte[]> hashCollection = SomeFunctionThatReturnsListByteArray();
//some approach that can create a hash of this
我的主要目标是检测是否发生了变化。我不关心更改了哪个文件。
散列哈希不是最优的。但是,如果您不想将所有文件散列在一起,您可以轻松地将散列添加到内存流并对其进行散列。
忽略任何其他概念性或其他方面的问题。
public static byte[] Hash(IEnumerable<byte[]> source)
{
using var hash = SHA256.Create();
var ms = new MemoryStream();
foreach (var bytes in source)
ms.Write(bytes, 0, bytes.Length);
ms.Seek(0, SeekOrigin.Begin);
return hash.ComputeHash(ms);
}
注意 : 我并不是说这是最好的解决方案,它只是解决您眼前问题的方法
稍微少一点的分配方法
public static byte[] Hash(IList<byte[]> source)
{
using var hash = SHA256.Create();
var ms = new MemoryStream(source.Sum(x =>x.Length));
foreach (var bytes in source)
ms.Write(bytes, 0, bytes.Length);
ms.Seek(0, SeekOrigin.Begin);
return hash.ComputeHash(ms);
}
对于多文件哈希(未测试)
public static byte[] Hash(IEnumerable<string> source)
{
using var hash = SHA256.Create();
hash.Initialize();
// adjust to what is fastest for you, for hdd 4k to 10k might be appropriate.
// for ssd larger will likely help
// probably best to keep it under 80k so it doesn't end up on LOH (up to you)
const int bufferSize = 1024 * 50;
var buffer = new byte[bufferSize];
foreach (var file in source)
{
using var fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Delete, bufferSize, FileOptions.SequentialScan);
var bytesRead = 0;
while ((bytesRead = fs.Read(buffer, 0, bufferSize)) != 0)
hash.TransformBlock(buffer, 0, bytesRead, buffer, 0);
hash.TransformFinalBlock(buffer, 0, 0);
}
return hash.Hash;
}