SHA-1 哈希字节数组与文件流
SHA-1 Hash a byte array vs a file stream
我正在编写一个允许用户上传文件(图片、视频等)的 API。我使用 SHA-1 哈希来确保同一文件不会被多次上传。以前我们只允许较小的文件,所以我将它们读入字节数组并对其进行哈希处理,但现在我们允许较大的文件,所以我使用的是文件流。问题是 SHA-1 算法 returns 不同的散列。我需要弄清楚如何获得相同的散列而不管方法如何,即使我必须将字节数组转换为文件流或其他东西。但是,我已经尝试将字节数组写入临时文件并将其读入,并且它 returns 与字节数组具有相同的哈希值。这是一个示例控制台应用程序,显示了我在做什么:
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));
}
我什至尝试过将字节数组放入 MemoryStream
和 new MemoryStream(bytes)
中,但这也没有用。似乎一旦我将文件放在字节数组中,它就无法放回原处。
编辑:
我从示例中删除了一些代码,因为我认为 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));
}
请参阅下面的答案以了解问题的解释。
问题是在用第一种方法散列时,流被读取到末尾。这导致第二个散列错误。因此,我需要为第二个哈希重新打开一个流,或者在以第二种方式进行哈希之前将流倒回开头。这是解决方案:
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));
}
我正在编写一个允许用户上传文件(图片、视频等)的 API。我使用 SHA-1 哈希来确保同一文件不会被多次上传。以前我们只允许较小的文件,所以我将它们读入字节数组并对其进行哈希处理,但现在我们允许较大的文件,所以我使用的是文件流。问题是 SHA-1 算法 returns 不同的散列。我需要弄清楚如何获得相同的散列而不管方法如何,即使我必须将字节数组转换为文件流或其他东西。但是,我已经尝试将字节数组写入临时文件并将其读入,并且它 returns 与字节数组具有相同的哈希值。这是一个示例控制台应用程序,显示了我在做什么:
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));
}
我什至尝试过将字节数组放入 MemoryStream
和 new MemoryStream(bytes)
中,但这也没有用。似乎一旦我将文件放在字节数组中,它就无法放回原处。
编辑:
我从示例中删除了一些代码,因为我认为 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));
}
请参阅下面的答案以了解问题的解释。
问题是在用第一种方法散列时,流被读取到末尾。这导致第二个散列错误。因此,我需要为第二个哈希重新打开一个流,或者在以第二种方式进行哈希之前将流倒回开头。这是解决方案:
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));
}