Kavita/Kavita.Common/HashUtil.cs
Joe Milazzo ed4f9e0144
Preparation for Release (#2135)
* Don't allow Comic libraries to do any scrobbling as there aren't any Comic scrobbling providers yet.

* Fixed a bug where if you have multiple libraries pointing the same folder (for whatever reason), the Scan Folder api could be rejected.

* Handle if publication from an epub is empty to avoid a bad parse error

* Cleaned up some hardcoded default strings.

* Fixed up some defaulting code for the cache size.

* Changed how moving something back to on deck works after it's been removed. Now any progress will trigger it, as epubs don't have chapters.

* Ignore .caltrash, which is a Calibre managed folder, when scanning.

* Added the ability to see Volume Last Read Date (or individual chapter) in details drawer. Hover over the clock for the full timestamp.
2023-07-17 06:48:15 -07:00

110 lines
3.2 KiB
C#

using System;
using System.Diagnostics;
using System.Text;
using System.Text.RegularExpressions;
using DeviceId;
using DeviceId.Components;
using Kavita.Common.EnvironmentInfo;
namespace Kavita.Common;
public static class HashUtil
{
private static string CalculateCrc(string input)
{
var mCrc = 0xffffffff;
var bytes = Encoding.UTF8.GetBytes(input);
foreach (var myByte in bytes)
{
mCrc ^= (uint)myByte << 24;
for (var i = 0; i < 8; i++)
{
if ((Convert.ToUInt32(mCrc) & 0x80000000) == 0x80000000)
{
mCrc = (mCrc << 1) ^ 0x04C11DB7;
}
else
{
mCrc <<= 1;
}
}
}
return $"{mCrc:x8}";
}
/// <summary>
/// Calculates a unique, Anonymous Token that will represent this unique Kavita installation.
/// </summary>
/// <returns></returns>
public static string AnonymousToken()
{
var seed = $"{Environment.ProcessorCount}_{Environment.OSVersion.Platform}_{Configuration.JwtToken}_{Environment.UserName}";
return CalculateCrc(seed);
}
public static string ServerToken()
{
var seed = new DeviceIdBuilder()
.AddMacAddress()
.AddUserName()
.AddComponent("ProcessorCount", new DeviceIdComponent($"{Environment.ProcessorCount}"))
.AddComponent("OSPlatform", new DeviceIdComponent($"{Environment.OSVersion.Platform}"))
.OnWindows(windows => windows
.AddProcessorId())
.OnLinux(linux =>
{
var osInfo = RunAndCapture("uname", "-a");
if (Regex.IsMatch(osInfo, @"\bUnraid\b"))
{
var cpuModel = RunAndCapture("lscpu", string.Empty);
var match = Regex.Match(cpuModel, @"Model name:\s+(.+)");
linux.AddComponent("CPUModel", new DeviceIdComponent($"{match.Groups[1].Value.Trim()}"));
return;
}
linux.AddMotherboardSerialNumber();
})
.OnMac(mac => mac.AddSystemDriveSerialNumber())
.ToString();
return CalculateCrc(seed);
}
/// <summary>
/// Generates a unique API key to this server instance
/// </summary>
/// <returns></returns>
public static string ApiKey()
{
var id = Guid.NewGuid();
if (id.Equals(Guid.Empty))
{
id = Guid.NewGuid();
}
return id.ToString();
}
private static string RunAndCapture(string filename, string args)
{
var p = new Process
{
StartInfo =
{
FileName = filename,
Arguments = args,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true
}
};
p.Start();
// To avoid deadlocks, always read the output stream first and then wait.
var output = p.StandardOutput.ReadToEnd();
p.WaitForExit(1000);
return output;
}
}