需要为内存中的System.Drawing.Image生成MD5哈希值

8

需要对内存中的System.Drawing.Image进行MD5哈希。


你卡在哪里了?这个相对来说很简单。 - µBio
1
标题并不能说明一切...为什么需要哈希?它需要与等效的磁盘文件的哈希完全相同吗?大概你会在某个时候将哈希与某些东西进行比较... - JaredReisinger
@Jared - http://uploadscreenshot.com/api-documentation#variables 现在,你知道我知道的:我有一个存储在内存中的System.Drawing.Image对象,并且需要将Image对象的MD5哈希发送到该API。 - Ronnie Overby
好的...所以API应该真正称之为“正在上传的文件的MD5哈希”,而不是图像的哈希。无论如何,您都必须将图像(转换为流或文件)序列化以进行POST,因此那就是您需要使用以下任何一个答案对其进行哈希处理的数据。 - JaredReisinger
3个回答

7

这里是基础代码片段。另请参考@JaredReisinger的评论,其中提出了一些问题。

using System.Security.Cryptography;
using System.Text;
using System.Drawing.Imaging;
// ...

// get the bytes from the image
byte[] bytes = null;
using( MemoryStream ms = new MemoryStream() )
{
    image.Save(ms,ImageFormat.Gif); // gif for example
    bytes =  ms.ToArray();
}

// hash the bytes
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] hash = md5.ComputeHash(bytes);

// make a hex string of the hash for display or whatever
StringBuilder sb = new StringBuilder();
foreach (byte b in hash)
{
   sb.Append(b.ToString("x2").ToLower());
} 

1
谢谢你只回答问题,而不浪费精力担心我为什么需要知道。我希望更多的人在SO上像你一样。另外,你可以避免使用StringBuilder和foreach循环。请看我的答案。 - Ronnie Overby
这种方法的不好之处在于,image.Save()不能提供统一的结果,即使是通过编程方式创建图像(使用Graphics.FromImage和绘制几条线来创建两个完全相同的实例),哈希值也会不同。 - olegz

3

这是一个基于MSDN中的示例的简单样本;请注意,此哈希值取决于图像的内部表示,因此不会对应于从文件创建的哈希值。

using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Security.Cryptography;
using System.Text;

class Program
{
    static string getMd5Hash(byte[] buffer)
    {
        MD5 md5Hasher = MD5.Create();

        byte[] data = md5Hasher.ComputeHash(buffer);

        StringBuilder sBuilder = new StringBuilder();
        for (int i = 0; i < data.Length; i++)
        {
            sBuilder.Append(data[i].ToString("x2"));
        }
        return sBuilder.ToString();
    }

    static byte[] imageToByteArray(Image image)
    {
        MemoryStream ms = new MemoryStream();
        image.Save(ms, ImageFormat.Bmp);
        return ms.ToArray();
    }

    static void Main(string[] args)
    {
        Image image = Image.FromFile(@"C:\tmp\Jellyfish.jpg");
        byte[] buffer = imageToByteArray(image);
        string md5 = getMd5Hash(buffer);
    }
}

要使用MD5类,您需要添加对System.Security的引用。
根据您将使用哈希的目的,您应该考虑到MD5不再是最先进的哈希函数,如果您需要强大的哈希,则有更好的哈希函数可用。

我必须说这很好地组合在一起了...与教科书所教的内容相符,也适用于考试者。 - IbrarMumtaz

1
感谢其他回答的朋友们。这是我最终采取的做法:
MemoryStream ms = new MemoryStream()
image.Save(ms, ImageFormat.Png);
byte[] imgBytes = ms.ToArray();

MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] hash = md5.ComputeHash(imgBytes);
string imageMD5 = BitConverter.ToString(hash).Replace("-", "").ToLower();
ms.Dispose();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接