2017-05-04 1 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が働いていたと思ったので

私は私の例からいくつかのコードを削除しました。ここでは、私がテストに使用していた元のコードです:

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)); 
     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)); 
} 

問題の説明については、以下の回答を参照してください。

+2

あなたの質問に提示されたコードは実際の実際のコードですか?ここに書かれているとおりにコードを実行しようとしましたか?なぜなら、あなたの質問のコード例はちょうど良いものであり、異なるハッシュを生成しないからです... – elgonzo

+1

また、リストする2番目のハッシュは空のストリームのものです。 –

+0

ストリームがいくつかのプリアンブルバイトをスキップしている可能性があります。それは起こりそうもないですが、これが私が思いつく最高のものです。配列の最初の3〜4バイトと比較して、最初の3〜4バイトのストリームを確認できますか?彼らは同じですか? – Amy

答えて

5

問題は、最初の方法でハッシュするときにストリームが最後まで読み込まれてしまうことです。これは、2番目のハッシュを間違っている原因になっています。そのため、2番目のハッシュのストリームを再オープンするか、2番目の方法をハッシュする前にストリームを先頭に巻き戻す必要があります。ここに解決策があります:

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)); 
} 
関連する問題