2017-05-04 2 views
4

사용자가 파일 (이미지, 비디오 등)을 업로드 할 수 있도록하는 API를 작성 중입니다. 나는 같은 파일이 여러 번 업로드되지 않도록 SHA-1 해시를 사용합니다. 이전에는 작은 파일 만 허용하여 바이트 배열을 읽고 해싱했지만 이제는 더 큰 파일을 허용하여 파일 스트림을 사용하고 있습니다. 문제는 SHA-1 알고리즘이 다른 해시를 반환한다는 것입니다. 바이트 배열을 파일 스트림이나 뭔가로 변환해야하는 경우에도 메서드에 관계없이 동일한 해시를 가져 오는 방법을 찾아야합니다. 그러나 바이트 배열을 임시 파일에 쓰려고 시도하고 바이트 배열과 동일한 해시를 반환합니다. 여기에 내가 뭐하는 거지 보여줍니다 예를 들어 콘솔 응용 프로그램입니다 : 심지어 단지 new MemoryStream(bytes)MemoryStream에 바이트 배열을 넣어 시도했지만 그 중 하나가 작동하지 않았다SHA-1 바이트 배열과 파일 스트림 비교 해시

static void Main(string[] args) 
{ 
    string file = "C:\\CUWCDFileStorage\\temp\\test.png"; 
    var bytes = File.ReadAllBytes(file); 
    using (var stream = File.Open(file, FileMode.Open)) 
    { 
     Console.WriteLine(Sha1HashFile(bytes)); // Returns B7F6D90C30233F91FCEFE05FB49679F8B26C9D80 
     Console.WriteLine(Sha1HashFile(stream)); // Returns DA39A3EE5E6B4B0D3255BFEF95601890AFD80709 
     Console.WriteLine(Sha1HashFile2(bytes)); // Returns B7F6D90C30233F91FCEFE05FB49679F8B26C9D80 
    } 

    Console.Read(); 
} 

public static string Sha1HashFile(byte[] file) 
{ 
    using (SHA1Managed sha1 = new SHA1Managed()) 
    { 
     return BitConverter.ToString(sha1.ComputeHash(file)).Replace("-", ""); 
    } 
} 

public static string Sha1HashFile(Stream stream) 
{ 
    using (SHA1Managed sha1 = new SHA1Managed()) 
    { 
     return BitConverter.ToString(sha1.ComputeHash(stream)).Replace("-", ""); 
    } 
} 

public static string Sha1HashFile2(byte[] bytes) 
{ 
    string file = "C:\\CUWCDFileStorage\\temp\\test2.png"; 
    File.WriteAllBytes(file, bytes); 
    return Sha1HashFile(File.OpenRead(file)); 
} 

. 한 번 바이트 배열에있는 파일을 다시 넣을 수없는 것 같습니다.

편집 : 내가 MD5가 작동 된 생각했기 때문에

나는 나의 예에서 일부 코드를 제거했습니다. 다음은 테스트 할 때 사용한 원래 코드입니다.

문제의 설명은 아래를 참조하십시오.

+2

코드에 실제 실제 코드가 있습니까? 여기에 쓰인 코드를 정확히 실행 해 보셨습니까? 때문에 귀하의 질문에 코드 예제는 그냥 괜찮아요 다른 해시를 생산하지 않습니다 ... – elgonzo

+1

또한 목록의 두 번째 해시는 빈 스트림의 목록입니다. –

+0

스트림이 일부 프리앰블 바이트를 건너 뛸 수 있습니다. 가능성은 낮지 만, 이것이 내가 생각할 수있는 최선입니다. 배열의 처음 3-4 바이트와 비교하여 스트림의 처음 3-4 바이트를 확인할 수 있습니까? 그들은 동일합니까? – Amy

답변

5

문제는 첫 번째 방법을 해싱 할 때 스트림이 끝까지 읽히는 것입니다. 즉, 두 번째 해시가 잘못되었습니다. 따라서 두 번째 해시를 위해 스트림을 다시 열거 나 두 번째 방법을 해싱하기 전에 스트림을 처음으로 되 감을 필요가 있습니다. 해결책은 다음과 같습니다.

static void Main(string[] args) 
{ 
    string file = "C:\\CUWCDFileStorage\\temp\\test.png"; 
    var bytes = File.ReadAllBytes(file); 
    using (var stream = File.Open(file, FileMode.Open)) 
    { 
     Console.WriteLine(Md5HashFile(bytes)); 
     Console.WriteLine(Md5HashFile(stream)); 
    } 

    using (var stream = File.Open(file, FileMode.Open)) 
    { 
     Console.WriteLine(Sha1HashFile(bytes)); 
     Console.WriteLine(Sha1HashFile(stream)); 
     Console.WriteLine(Sha1HashFile2(bytes)); 
    } 

    Console.Read(); 
} 

public static string Md5HashFile(byte[] file) 
{ 
    using (MD5 md5 = MD5.Create()) 
    { 
     return BitConverter.ToString(md5.ComputeHash(file)).Replace("-", ""); 
    } 
} 

public static string Sha1HashFile(byte[] file) 
{ 
    using (SHA1Managed sha1 = new SHA1Managed()) 
    { 
     return BitConverter.ToString(sha1.ComputeHash(file)).Replace("-", ""); 
    } 
} 

public static string Md5HashFile(Stream stream) 
{ 
    using (MD5 md5 = MD5.Create()) 
    { 
     return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", ""); 
    } 
} 

public static string Sha1HashFile(Stream stream) 
{ 
    using (SHA1Managed sha1 = new SHA1Managed()) 
    { 
     return BitConverter.ToString(sha1.ComputeHash(stream)).Replace("-", ""); 
    } 
} 

public static string Sha1HashFile2(byte[] bytes) 
{ 
    string file = "C:\\CUWCDFileStorage\\temp\\test2.png"; 
    File.WriteAllBytes(file, bytes); 
    return Sha1HashFile(File.OpenRead(file)); 
}