创建上传图片的md5哈希

时间:2012-01-10 11:18:39

标签: c# asp.net file-upload md5

我正在尝试从用户在我的Web应用程序上传的图像的字节数组中创建一个md5字符串。 这是因为我希望图像分散在不同的文件夹中。 而且我不必使用userID作为文件夹名称。看起来更专业。

结果如下:

/images/ 'first-two-char-of-md5' / 'the-complete-md5-string'.[jpg,png,bmp....]

这听起来是处理图像的好方法吗?

因此。 我的代码(来自互联网的东西。):

protected void btnUpload_Click(object sender, EventArgs e)
    {
        if (FileUpload1.HasFile)
        {
            if (CheckFileType(FileUpload1.FileName))
            {
                const int BUFFER_SIZE = 255;
                Byte[] Buffer = new Byte[BUFFER_SIZE];

                Stream theStream = FileUpload1.PostedFile.InputStream;
                nBytesRead = theStream.Read(Buffer, 0, BUFFER_SIZE);

                System.Text.ASCIIEncoding ASCIIEncoding = new ASCIIEncoding();
                System.Text.UTF8Encoding utf8 = new UTF8Encoding();
                //Just trying some stuff to see the output...
                Label1.Text =  ASCIIEncoding.GetString(CalculateMD5(theStream)) + "<br>" + utf8.GetString(CalculateMD5(theStream)) + "<br>" + Convert.ToBase64String(CalculateMD5(theStream));
             }
       }
  }


private static byte[] _emptyBuffer = new byte[0];

    public static byte[] CalculateMD5(Stream stream)
    {
        return CalculateMD5(stream, 64 * 1024);
    }

    public static byte[] CalculateMD5(Stream stream, int bufferSize)
    {
        MD5 md5Hasher = MD5.Create();

        byte[] buffer = new byte[bufferSize];
        int readBytes;

        while ((readBytes = stream.Read(buffer, 0, bufferSize)) > 0)
        {
            md5Hasher.TransformBlock(buffer, 0, readBytes, buffer, 0);
        }

        md5Hasher.TransformFinalBlock(_emptyBuffer, 0, 0);

        return md5Hasher.Hash;
    }

结果。我从“calculateMD5()”获得一些输出,但是当我试图将它放到label1时。看看发生了什么。只有一堆奇怪的角色。 我在这做错了什么?我希望它是htmlsafe ... a-z,A-Z,仅限0-9。

4 个答案:

答案 0 :(得分:7)

哈希作为字节数组返回。您需要将其转换为人类可读的形式,例如73868cb1848a216984dca1b6b0ee37bc。您可以使用以下内容:

var s = new StringBuilder();
foreach (byte b in md5Hasher.Hash)
    s.Append(b.ToString("x2").ToLower());
return s.ToString();

这将遍历从散列操作返回的字节列表,并将每个字节转换为十六进制。您可以在format strings you can use for the byte type on MSDN找到更多信息。

回答问题的第一部分:

  

这听起来是处理图像的好方法吗?

这应该足够了,但是如果2个用户上传相同的图像,那么它将导致相同的散列。您可以尝试使用用户名和可能的时间戳来缓存数据,以缓解此问题。

您还需要进行一些检查,因为即使概率极小,您也可能为不同的图像/用户生成相同的哈希(“碰撞”),并且您不希望用户覆盖其他用户的图像。您可以通过生成图像的哈希,检查它是否已存在来防止这种情况,如果存在,则向预先哈希的数据添加一些字节,重复直到哈希是唯一的。

答案 1 :(得分:3)

还有BitConverter类,它有一个ToString()方法,可以将字节数组转换为十六进制字符串表示形式。

类似于:

BitConverter.ToString(CalculateMD5(theStream)).Replace("-","");

将为您提供该MD5哈希的典型十六进制字符串表示形式。

答案 2 :(得分:2)

您无法读取它,因为它是一个字节数组,需要使用适当的编码将其转换为可读字符串。

例如在SHA256类中生成哈希:

using (System.Security.Cryptography.SHA256 sha = System.Security.Cryptography.SHA256.Create())
      return sha.ComputeHash(data);

然后如果你想把它变成一个字符串,把它看成可读的形式:

string hashValue = Convert.ToBase64String(hash);

除了SHA256和MD5之外,当然还有other种用于生成哈希(有或没有盐)的算法。

答案 3 :(得分:0)

您是否尝试过CalculateMD5(theStream).ToString()?不确定它是否会有所帮助,但可能值得一试。

另外我建议您将CalculateMD5(theStream)的结果保存在局部变量中,然后保存.ToString()它。

GL,希望有所帮助。