2012-01-10 4 views
3

내 웹 응용 프로그램에서 사용자가 업로드 한 이미지의 바이트 배열에서 md5 문자열을 만들려고합니다. 이미지가 다른 폴더에 분산되기를 원하기 때문입니다. 그리고 폴더 이름으로 userID를 사용하지 않아도됩니다. 더 전문적으로 보입니다.업로드 된 이미지의 md5 해시 만들기

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

좋은 솔루션으로이 소리가 이미지를 처리하는 않는다 :

결과는 다음과 같을 것이다?

So. 내 코드 (인터넷에서 물건.) :

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 만 가능합니다.

답변

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 명의 사용자가 동일한 이미지를 업로드하면 동일한 해시가 발생하지만 충분해야합니다. 이것을 줄이기 위해 사용자 이름과 타임 스탬프를 사용하여 데이터를 소금으로 처리 할 수 ​​있습니다.

확률이 극히 적을지라도 다른 이미지/사용자에 대해 동일한 해시 ('충돌')를 생성 할 수 있고 사용자가 다른 사용자의 이미지를 덮어 쓰지 않기를 바랍니다. 영상. 이미지의 해시를 생성하여 이미 존재하는지 확인하고 해시가 사전에 해시 된 데이터에 일부 바이트를 추가하고 해시가 고유 할 때까지 반복하여이를 방지 할 수 있습니다.

+0

감사합니다. 같은 이미지를 가진 2 명의 사용자에 대해 제 생각에는 비어있는 (소금기가있는) _emptybuffer 바이트 []에 userID를 추가하여 소금을 추가 할 수 있다고 생각합니까 ?? – Easyrider

+1

예, 작동합니다. MD5는 체크섬을 사용하여 최종 해시를 계산합니다. 'TransformFinalBlock'은 '여기가 데이터의 마지막이며 해시 작업을 마무리합니다'라고 말하는 방법입니다. 또는,'CalculateMD5'에 전달한 스트림의 끝 부분에 추가 데이터를 쓸 수 있습니다 (이미지 데이터를 중간의'MemoryStream'으로 먼저 읽어서 여분의 데이터를 추가하고'MemoryStream'을'CalculateMD5'에 전달할 수 있습니다).). – mdm

2

바이트 배열이므로 적절한 인코딩을 사용하여 읽을 수있는 문자열로 변환해야하므로 읽을 수 없습니다.

해시 생성하는 SHA256 클래스의 예를 들어

:

물론 있습니다
string hashValue = Convert.ToBase64String(hash); 

other 알고리즘 : 당신은 문자열로 원하는 경우

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

다음 읽을 수있는 형태로 볼 수 SHA256 및 MD5 이외에 해시 생성 (소금 포함 또는 제외).

0

CalculateMD5 (theStream) .ToString()을 사용해 보셨나요? 그것이 도움이 될지 확실하지 않지만 시도 할만한 가치가있을 것입니다.

또한 CalculateMD5 (theStream)의 결과를 로컬 변수에 저장하고 .ToString()을 사용하는 것이 좋습니다.

GL, 희망이 도움이되었습니다.

+0

아니요, 작동하지 않습니다. 'Console.WriteLine ((new byte [] {1, 2, 3}) .ToString()); 원하는 출력이 아닌 System.Byte []'를 출력합니다. – mdm

3

바이트 배열을 16 진수 문자열 표현으로 변환 할 수있는 ToString() 메서드가있는 BitConverter 클래스가 있습니다.

그래서 뭔가 같은 :

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

당신에게 그 MD5 해시의 전형적인 진수 문자열 표현을 얻을 것이다.