ᔕIᑎ*_*ᑎᗪI 6 c# mono checksum hashcode sha256
以前我问了一个关于组合SHA1 + MD5 的问题,但之后我理解计算SHA1然后延迟文件的MD5并不比SHA256快.在我的情况下,4.6 GB文件大约需要10分钟,在Linux系统中使用默认实现SHA256和(C#MONO).
public static string GetChecksum(string file)
{
using (FileStream stream = File.OpenRead(file))
{
var sha = new SHA256Managed();
byte[] checksum = sha.ComputeHash(stream);
return BitConverter.ToString(checksum).Replace("-", String.Empty);
}
}
Run Code Online (Sandbox Code Playgroud)
然后我读了这个主题,并以某种方式根据他们所说的改变我的代码:
public static string GetChecksumBuffered(Stream stream)
{
using (var bufferedStream = new BufferedStream(stream, 1024 * 32))
{
var sha = new SHA256Managed();
byte[] checksum = sha.ComputeHash(bufferedStream);
return BitConverter.ToString(checksum).Replace("-", String.Empty);
}
}
Run Code Online (Sandbox Code Playgroud)
但它没有这样的感情,需要大约9分钟.
然后我尝试通过sha256sumLinux中的命令测试我的文件中的相同文件,它需要大约28秒,上面的代码和Linux命令都给出相同的结果!
有人建议我阅读Hash Code和Checksum之间的区别,然后我会谈到这个解释差异的主题.
我的问题是:
是什么导致上述代码和Linux之间的这种不同sha256sum?
上面的代码是做什么的?(我的意思是它是哈希码计算还是校验和计算?因为如果你搜索一下文件的哈希码和C#中文件的校验和,它们都会到达上面的代码.)
sha256sum即使SHA256具有抗冲击性,是否有任何动机攻击?
如何sha256sum在C#中快速实现我的实现?
小智 16
public string SHA256CheckSum(string filePath)
{
using (SHA256 SHA256 = SHA256Managed.Create())
{
using (FileStream fileStream = File.OpenRead(filePath))
return Convert.ToBase64String(SHA256.ComputeHash(fileStream));
}
}
Run Code Online (Sandbox Code Playgroud)
我最好的猜测是,该File.Read操作的Mono实现中还有一些额外的缓冲。最近,我们在大型规格的Windows计算机上检查了大文件的校验和,如果一切运行顺利,则您应该期望每Gb大约6秒。
奇怪的是,在多个基准测试中已经报告SHA-512明显比SHA-256快(请参阅下面的3)。另一种可能性是问题不在于分配数据,而在于一旦读取就处置字节。您也许可以在单个数组上使用TransformBlock(和TransformFinalBlock),而不用大张旗鼓地读取流-我不知道这是否行得通,但值得我们研究。
哈希码和校验和之间的区别是(几乎)语义。它们都计算出较短的“魔术”数,该数字对于输入中的数据而言是相当独特的,尽管如果您有4.6GB的输入和64B的输出,则“相当”受到一定限制。
MD5易碎:您可以在PC上构造输入以产生任何给定的输出。SHA-256(可能)仍然是安全的,但不会在几年后—如果您的项目的寿命以几十年为单位,则假定您需要对其进行更改。SHA-512没有已知的攻击,并且可能不会持续很长时间,并且由于它比SHA-256快,因此无论如何我还是建议这样做。基准测试表明,计算SHA-512所需的时间比MD5长3倍左右,因此,如果可以解决速度问题,这就是解决之道。
除了上面提到的那些,别无所求。您做对了。
欲了解更多信息,请参阅Crypto.SE:SHA51比SHA256更快?
根据评论中的问题进行编辑
校验和的目的是使您可以检查文件在最初写入到使用之间的时间是否已更改。它通过产生一个较小的值(在SHA512情况下为512位)来实现此目的,原始文件的每一位至少对输出值有贡献。哈希码的目的是相同的,另外,通过对文件进行仔细管理的更改,其他人很难,真的很难获得相同的输出值。
前提是,如果开始时和检查时校验和相同,则文件是相同的;如果它们不同,则文件肯定已更改。上面的操作是通过滚动读取,折叠并旋转读取的位以产生较小值的算法来完整地馈送文件。
举个例子:在我当前正在编写的应用程序中,我需要知道文件大小的任何部分是否已更改。我将文件分成16K块,对每个块进行SHA-512哈希处理,然后将其存储在另一个驱动器上的单独数据库中。当我来看文件是否已更改时,我为每个块重现了哈希并将其与原始块进行比较。由于我使用的是SHA-512,因此具有相同哈希值的已更改文件的可能性非常小,因此我可以自信地检测出数百GB数据的变化,同时仅在数据库中存储几MB哈希值。我在进行散列的同时复制文件,整个过程完全是磁盘绑定的。将文件传输到USB驱动器大约需要5分钟,其中10秒可能与哈希相关。
缺少用于存储哈希的磁盘空间是我无法解决的问题-购买USB记忆棒?