mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 12:16:30 +00:00
add MediaHash. Step1
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
using System.IO;
|
||||
using System.IO.Hashing;
|
||||
using System.Text;
|
||||
|
||||
namespace Azaion.Common.Services;
|
||||
|
||||
public static class HashExtensions
|
||||
{
|
||||
private const int SampleSize = 1024;
|
||||
private const int HashLength = 9;
|
||||
private const string VirtualHashPrefix = "V";
|
||||
|
||||
public static string CalcHash(this FileInfo file)
|
||||
{
|
||||
if (!file.Exists)
|
||||
return CalcVirtualHash(file.Name);
|
||||
|
||||
var fileSize = file.Length;
|
||||
if (fileSize < SampleSize * 8)
|
||||
return CalcHashInner(File.ReadAllBytes(file.FullName));
|
||||
|
||||
var combinedData = new byte[8 + SampleSize * 3];
|
||||
var offset = 0;
|
||||
|
||||
var fileSizeBytes = BitConverter.GetBytes(fileSize);
|
||||
Array.Copy(fileSizeBytes, 0, combinedData, offset, 8);
|
||||
offset += 8;
|
||||
|
||||
using var stream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
|
||||
stream.ReadExactly(combinedData, offset, SampleSize);
|
||||
offset += SampleSize;
|
||||
|
||||
stream.Position = (fileSize - SampleSize) / 2;
|
||||
stream.ReadExactly(combinedData, offset, SampleSize);
|
||||
offset += SampleSize;
|
||||
|
||||
stream.Position = fileSize - SampleSize;
|
||||
stream.ReadExactly(combinedData, offset, SampleSize);
|
||||
|
||||
return CalcHashInner(combinedData);
|
||||
}
|
||||
|
||||
public static string CalcVirtualHash(string filename)
|
||||
{
|
||||
var bytes = Encoding.UTF8.GetBytes($"VIRTUAL:{filename}");
|
||||
var hash = XxHash64.HashToUInt64(bytes);
|
||||
var hashBytes = BitConverter.GetBytes(hash);
|
||||
var base64 = Convert.ToBase64String(hashBytes);
|
||||
return VirtualHashPrefix + base64[..HashLength];
|
||||
}
|
||||
|
||||
public static bool IsVirtualHash(this string? hash) =>
|
||||
!string.IsNullOrEmpty(hash) && hash.StartsWith(VirtualHashPrefix);
|
||||
|
||||
private static string CalcHashInner(byte[] data)
|
||||
{
|
||||
var hash = XxHash64.HashToUInt64(data);
|
||||
var hashBytes = BitConverter.GetBytes(hash);
|
||||
var base64 = Convert.ToBase64String(hashBytes);
|
||||
return base64[..HashLength];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user