public byte[] HashImage(string fileName)
{
using (var image = new Bitmap(fileName))
{
var sha256 = SHA256.Create();
var rect = new Rectangle(0, 0, image.Width, image.Height);
var data = image.LockBits(rect, ImageLockMode.ReadOnly, image.PixelFormat);
var dataPtr = data.Scan0;
var totalBytes = (int)Math.Abs(data.Stride) * data.Height;
var rawData = new byte[totalBytes];
System.Runtime.InteropServices.Marshal.Copy(dataPtr, rawData, 0, totalBytes);
image.UnlockBits(data);
return sha256.ComputeHash(rawData);
}
}
private Tuple<int, string> GetIndexedImage(string fileName)
{
var baseFileName = Path.GetFileNameWithoutExtension(fileName);
int index;
if (int.TryParse(baseFileName, out index))
{
return Tuple.Create(index, fileName);
}
return null;
}
private string HashToString(byte[] hash)
{
var builder = new StringBuilder();
foreach (var b in hash)
{
builder.AppendFormat("{0:x2}", b);
}
return builder.ToString();
}
HashImage()
以字節形式獲取圖像的SHA256哈希值。 GetFileIndex()
返回索引和文件名的元組。 HashToString()
是一個將散列轉換爲字符串的字符串生成器。如何分組我的重複散列?
private void button1_Click(object sender, EventArgs e)
{
string original = @"C:\Users\user\Documents\CaptchaCollection\";
var equivalentImages = Directory.GetFiles(original)
.Select(f => GetIndexedImage(f)) // build tuples (index, fileName) or null if parsing failed
.Where(t => t != null) // ignore all invalid ones
.OrderBy(t => t.Item1) // order by index
.Select(t => Tuple.Create(HashImage(t.Item2), t.Item2)) // create new tuple (hash, fileName)
.GroupBy(t => t.Item1); // group by Hash
// print groups
foreach (var group in equivalentImages)
{
Console.WriteLine("All images with hash: {0}", HashToString(group.Key));
foreach (var t in group)
{
Console.WriteLine("\t{0}", t.Item2);
}
}
}
現在,這是一個像我主要的方法,當我點擊按鈕,我開始獲取圖像文件的哈希值。
不過,現在的主要問題是,它似乎當我收集的文件的哈希值的output喜歡,他們不分組,而是它們的順序進行打印。相反,它們分散在輸出文件中。
如何將任何組和重複元素用相同散列分組?
您對LINQ和功能組合的使用非常好。 – usr
@usr所有的LINQ代碼都不是我的。我很少知道它是誠實的 – puretppc
GetIndexedImage可以作爲方法組調用。 – Magus