using pkNXHashDecoder; using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; namespace pkNX.Containers; public class FnvHashDecoder { public const string AllowedChars = "etaoinshrdlcumw_0123456789fgypbvkjxqz/."; // Sorted by most common first public HashSet HashesToTest = new() { 9252365659083253459, 17205188591700921149, 1234775724179408742 }; // 64 bit implementation private const ulong kFnvPrime_64 = 0x00000100000001b3; private const ulong kOffsetBasis_64 = 0xCBF29CE484222645; public Dictionary FoundKeys = new(); public Dictionary Run(int minLength, int maxLength) { Debug.Assert(FnvHash.HashFnv1a_64("stickyball") == 0x15cb1f582d2b05ab); Debug.Assert(FnvHash.HashFnv1a_64("enigma") == 0xC75DDBE25402B11C); var tasks = new List(); for (int i = 0; i < FnvHashDecoderLib.AllowedCharCount; ++i) { int startChar = i; tasks.Add(Task.Run(() => { var dict = FnvHashDecoderLib.StartDecoding(15, startChar, "pm0025_"); if (dict.Count != 0) { foreach (var x in dict) { FoundKeys.TryAdd(x.Key, x.Value); Debug.WriteLine($"{x.Key} {x.Value}"); } } //StartLoop(length, startChar); })); } Task t = Task.WhenAll(tasks); try { t.Wait(); } catch { } return FoundKeys; } /*private void StartLoop(int length, int startChar) { Span chars = stackalloc char[length]; Span allowedCharIndex = stackalloc byte[length]; // Current AllowedChar // Reset all chars to starting point chars[0] = AllowedChars[startChar]; allowedCharIndex[0] = (byte)startChar; for (int i = 1; i < length; i++) chars[i] = AllowedChars[0]; while (allowedCharIndex[0] == startChar) { // Build the hash of all chars except the last one ulong hashBase = kOffsetBasis_64; for (int i = 0; i < length - 1; ++i) { hashBase ^= chars[i]; hashBase *= kFnvPrime_64; // Automatically test for shorter length strings if (hashBase == 9252365659083253459) { FoundKeys.Add(hashBase, new string(chars[0..i])); } } // Loop through all AllowedChars for (int j = 0; j < AllowedChars.Length; ++j) { ulong hash = hashBase; hash ^= AllowedChars[j]; hash *= kFnvPrime_64; if (hash == 9252365659083253459) { chars[length - 1] = AllowedChars[j]; FoundKeys.Add(hash, new string(chars)); } } int carry = 0; int c = length - 2; for (; c >= 0; c--) { ++allowedCharIndex[c]; carry = allowedCharIndex[c] / AllowedChars.Length; allowedCharIndex[c] %= (byte)AllowedChars.Length; chars[c] = AllowedChars[allowedCharIndex[c]]; if (carry == 0) break; } // Reached the end if (carry != 0 && c == 0) break; // Already found all keys if (FoundKeys.Count != 0) return; } }*/ }