我们有一个进程散列映像,并希望能够在其他服务器上部署相同的进程。如何跨不同服务器为映像获取相同的哈希值。这是我们的代码
static void Main(string[] args)
{
byte[] imageBytes;
string imagePath = @"C:\Work\Projects\test.jpg";
System.Drawing.Image image = System.Drawing.Image.FromFile(imagePath);
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
imageBytes = ms.ToArray();
}
string photoCheckSumSha256 = ComputeSha256Checksum(imageBytes);
Console.WriteLine(photoCheckSumSha256);
Console.ReadKey();
}
static string ComputeSha256Checksum(byte[] data)
{
using (System.IO.MemoryStream stream = new System.IO.MemoryStream(data))
{
System.Security.Cryptography.SHA256 sha256 = new System.Security.Cryptography.SHA256CryptoServiceProvider();
byte[] sha256Ret = sha256.ComputeHash(stream);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < sha256Ret.Length; i++)
{
sb.Append(sha256Ret[i].ToString("x2"));
}
return sb.ToString();
}
}
答案 0 :(得分:1)
甚至不能保证在同一台机器上从一次运行到另一次运行的方式相同,因为一些JPEG编码实现是非确定性的。
到目前为止,您的算法是:
您的算法应该是:
您甚至不需要关心它是否是JPEG文件。一个可能的优点是,如果.NET无法将其作为图像处理,那么您的代码会抛出异常(在大多数情况下这是一个缺点,但如果现在最好失败而不是线下,则会有一个优势) 。如果有必要,您可以与散列分开调用Image.FromFile()
。
答案 1 :(得分:0)
尝试将文件直接传输到SHA256提供程序,而不是读取图像并保存到内存流:
/* using declarations:
using System;
using System.IO;
using System.Security.Cryptography;
*/
static string ComputeFileChecksum(string filePath)
{
if (File.Exists(filePath))
{
using (var fileStream = File.OpenRead(filePath))
using (var sha256 = new SHA256CryptoServiceProvider())
{
var hashBytes = sha256.ComputeHash(fileStream);
return Convert.ToBase64String(hashBytes);
}
}
else
{
// TODO: handle non-existent file
return string.Empty;
}
}