Files
Pilz/Pilz.Cryptography/UniquieID.cs

173 lines
5.1 KiB
C#

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Management;
using System.Security.Cryptography;
using System.Text;
namespace Pilz.Cryptography
{
[JsonConverter(typeof(Json.Converters.UniquieIDStringJsonConverter))]
public class UniquieID : IUniquieID
{
protected static ulong currentSimpleID = 0;
[JsonProperty(nameof(ID))]
protected string _iD;
[JsonIgnore]
public virtual bool SimpleMode { get; }
[JsonIgnore]
public virtual bool GenerateOnGet { get; }
[JsonIgnore]
public virtual bool HasID => !string.IsNullOrEmpty(_iD);
[JsonIgnore]
public virtual string ID
{
get
{
if (GenerateOnGet)
GenerateIfNull();
return _iD;
}
internal set
=> _iD = value;
}
public UniquieID() : this(UniquieIDGenerationMode.None)
{
}
public UniquieID(UniquieIDGenerationMode mode) : this(mode, false)
{
}
public UniquieID(UniquieIDGenerationMode mode, bool simpleMode)
{
SimpleMode = simpleMode;
if (mode == UniquieIDGenerationMode.GenerateOnInit)
GenerateIfNull();
else if (mode == UniquieIDGenerationMode.GenerateOnGet)
GenerateOnGet = true;
}
[Obsolete]
public UniquieID(bool autoGenerate) : this(autoGenerate ? UniquieIDGenerationMode.GenerateOnInit : UniquieIDGenerationMode.None)
{
}
public virtual void Generate()
{
if (SimpleMode)
ID = GenerateSimple();
else
ID = GenerateDefault();
}
protected virtual string GenerateSimple()
{
return new Random().Next().ToString() + DateTime.Now.ToString("yyyyMMddHHmmssfffffff") + currentSimpleID++.ToString();
}
protected virtual string GenerateDefault()
{
return GenerateUniquieID<UniquieID>(currentSimpleID++.ToString());
}
public virtual void GenerateIfNull()
{
if (!HasID) Generate();
}
public override string ToString()
{
return ID;
}
public override int GetHashCode()
{
return -1430039477 + EqualityComparer<string>.Default.GetHashCode(_iD);
}
public override bool Equals(object obj)
{
if (obj is UniquieID iD)
{
if (ReferenceEquals(obj, iD))
return true;
else
{
var leftHasID = iD.HasID;
var rightHasID = HasID;
if (!leftHasID && iD.GenerateOnGet)
{
iD.Generate();
leftHasID = iD.HasID;
}
if (!rightHasID && GenerateOnGet)
{
Generate();
rightHasID = HasID;
}
if (leftHasID && rightHasID)
return _iD.Equals(iD._iD);
}
}
return base.Equals(obj);
}
#region Statics for Generation
protected static string GenerateUniquieID<T>(string var)
{
var sn = TryGetSerialNumberOfFirstHardDrive();
var dateTime = DateTime.UtcNow.ToString("yyyyMMddHHmmssfffffff");
var type = typeof(T).ToString();
var together = sn + dateTime + type + var;
var md5 = MD5.Create();
var hash = BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(together))).Replace("-", string.Empty);
md5.Dispose();
return hash;
}
private static string Win32_PhysicalMedia_SerialNumber = null;
private static string TryGetSerialNumberOfFirstHardDrive()
{
if (Win32_PhysicalMedia_SerialNumber == null)
{
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
var sn = string.Empty;
foreach (ManagementObject wmi_HD in searcher.Get())
{
if (string.IsNullOrEmpty(sn) && wmi_HD["SerialNumber"] != null)
sn = wmi_HD["SerialNumber"].ToString().Trim();
}
Win32_PhysicalMedia_SerialNumber = sn;
}
return Win32_PhysicalMedia_SerialNumber;
}
#endregion
public static implicit operator string(UniquieID id) => id.ID;
public static implicit operator UniquieID(string id) => new UniquieID() { ID = id };
public static implicit operator UniquieID(int id) => new UniquieID() { ID = Convert.ToString(id) };
public static bool operator ==(UniquieID left, UniquieID right) => left.ID.Equals(right.ID);
public static bool operator !=(UniquieID left, UniquieID right) => !left.ID.Equals(right.ID);
}
}