118 lines
3.4 KiB
C#
118 lines
3.4 KiB
C#
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Security.Cryptography;
|
|
using SptCommon.Annotations;
|
|
|
|
namespace Core.Utils;
|
|
|
|
[Injectable(InjectionType.Singleton)]
|
|
public class HashUtil
|
|
{
|
|
protected Regex MongoIdRegex = new("^[a-fA-F0-9]{24}$");
|
|
|
|
protected RandomUtil _randomUtil;
|
|
|
|
public HashUtil(RandomUtil randomUtil)
|
|
{
|
|
_randomUtil = randomUtil;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a 24 character MongoId
|
|
/// </summary>
|
|
/// <returns>24 character objectId</returns>
|
|
public string Generate()
|
|
{
|
|
var objectId = new byte[12];
|
|
|
|
// Time stamp (4 bytes)
|
|
var timestamp = BitConverter.GetBytes((int)DateTimeOffset.UtcNow.ToUnixTimeSeconds());
|
|
// Convert to big-endian
|
|
Array.Reverse(timestamp);
|
|
Array.Copy(timestamp, 0, objectId, 0, 4);
|
|
|
|
// Random value (5 bytes)
|
|
var randomValue = new byte[5];
|
|
_randomUtil.Random.NextBytes(randomValue);
|
|
Array.Copy(randomValue, 0, objectId, 4, 5);
|
|
|
|
// Incrementing counter (3 bytes)
|
|
// 24-bit counter
|
|
var counter = BitConverter.GetBytes(_randomUtil.GetInt(0, 16777215));
|
|
Array.Reverse(counter);
|
|
Array.Copy(counter, 0, objectId, 9, 3);
|
|
|
|
return Convert.ToHexStringLower(objectId);
|
|
}
|
|
|
|
/// <summary>
|
|
/// is the passed in string a valid mongo id
|
|
/// </summary>
|
|
/// <param name="stringToCheck">String to check</param>
|
|
/// <returns>True when string is a valid mongo id</returns>
|
|
public bool IsValidMongoId(string stringToCheck)
|
|
{
|
|
return MongoIdRegex.IsMatch(stringToCheck);
|
|
}
|
|
|
|
public string GenerateMd5ForData(string data)
|
|
{
|
|
return GenerateHashForData(HashingAlgorithm.MD5, data);
|
|
}
|
|
|
|
public string GenerateSha1ForData(string data)
|
|
{
|
|
return GenerateHashForData(HashingAlgorithm.SHA1, data);
|
|
}
|
|
|
|
public string GenerateCrc32ForData(string data)
|
|
{
|
|
// TODO: Could not find a ms way of doing this.
|
|
// May need a custom impl to avoid an external lib. - CJ
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a hash for the data parameter
|
|
/// </summary>
|
|
/// <param name="algorithm">algorithm to use to hash</param>
|
|
/// <param name="data">data to be hashed</param>
|
|
/// <returns>hash value</returns>
|
|
/// <exception cref="NotImplementedException">thrown if the provided algorithm is not implemented</exception>>
|
|
public string GenerateHashForData(HashingAlgorithm algorithm, string data)
|
|
{
|
|
switch (algorithm)
|
|
{
|
|
case HashingAlgorithm.MD5:
|
|
var md5HashData = MD5.HashData(Encoding.UTF8.GetBytes(data));
|
|
return Convert.ToHexString(md5HashData).Replace("-", string.Empty);
|
|
|
|
case HashingAlgorithm.SHA1:
|
|
var sha1HashData = SHA1.HashData(Encoding.UTF8.GetBytes(data));
|
|
return Convert.ToHexString(sha1HashData).Replace("-", string.Empty);
|
|
}
|
|
|
|
throw new NotImplementedException($"Provided hash algorithm: {algorithm} is not supported.");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generates an account ID for a profile
|
|
/// </summary>
|
|
/// <returns>Generated account ID</returns>
|
|
public int GenerateAccountId()
|
|
{
|
|
const int min = 1000000;
|
|
const int max = 1999999;
|
|
|
|
var random = new Random();
|
|
|
|
return random.Next(min, max + 1);
|
|
}
|
|
}
|
|
|
|
public enum HashingAlgorithm
|
|
{
|
|
MD5,
|
|
SHA1
|
|
}
|