diff --git a/README.md b/README.md index cf791e3..f6dc6e9 100644 --- a/README.md +++ b/README.md @@ -47,10 +47,10 @@ Number of words|Time to check all anagrams no longer than that|Time to solve "ea ---------------|----------------------------------------------|-------------------------|-----------------------------------|-------------------------|--------------------------------------------- 3|0.04s||||4560 4|0.45s|||0.08s|7,431,984 -5|10.4s|0.15s|0.06s|0.3s|1,347,437,484 -6|5.5 minutes|1s|0.2s|2.5s|58,405,904,844 -7|81 minutes|5.7s|0.8s|16.1s|1,070,307,744,114 -8|21.5 hours|21s|2.3s|65s|10,893,594,396,594 +5|10s|0.15s|0.06s|0.29s|1,347,437,484 +6|5 minutes|0.9s|0.2s|2.3s|58,405,904,844 +7|81 minutes|5.1s|0.7s|14.5s|1,070,307,744,114 +8|21.5 hours|19s|2s|59s|10,893,594,396,594 9||2.5 minutes|13s|9.5 minutes|70,596,864,409,954 10||5 minutes|21s|17.5 minutes|314,972,701,475,754 diff --git a/dotnet/WhiteRabbit/PhraseSet.cs b/dotnet/WhiteRabbit/PhraseSet.cs index 7c8dab8..ee0e3cc 100644 --- a/dotnet/WhiteRabbit/PhraseSet.cs +++ b/dotnet/WhiteRabbit/PhraseSet.cs @@ -1,7 +1,9 @@ namespace WhiteRabbit { + using System; using System.Diagnostics; using System.Linq; + using System.Numerics; using System.Runtime.CompilerServices; using WhiteRabbitUnmanagedBridge; @@ -29,9 +31,9 @@ } } - public unsafe void FillPhraseSet(PhraseSet initial, Word[] allWords, int[] wordIndexes, ulong[] permutations, int permutationOffset) + public unsafe void ProcessPermutations(PhraseSet initialPhraseSet, Word[] allWords, int[] wordIndexes, ulong[] permutations, Vector expectedHashes, Action action) { - fixed (uint* bufferPointer = this.Buffer, initialBufferPointer = initial.Buffer) + fixed (uint* bufferPointer = this.Buffer, initialBufferPointer = initialPhraseSet.Buffer) { fixed (ulong* permutationsPointer = permutations) { @@ -39,33 +41,32 @@ { fixed (Word* allWordsPointer = allWords) { - MD5Unmanaged.FillPhraseSet( - (ulong*)initialBufferPointer, - (ulong*)bufferPointer, - (ulong*)allWordsPointer, - wordIndexesPointer, - permutationsPointer + permutationOffset, - wordIndexes.Length); + for (var i = 0; i < permutations.Length; i += Constants.PhrasesPerSet) + { + MD5Unmanaged.FillPhraseSet( + (ulong*)initialBufferPointer, + (ulong*)bufferPointer, + (ulong*)allWordsPointer, + wordIndexesPointer, + permutationsPointer + i, + wordIndexes.Length); + + MD5Unmanaged.ComputeMD5(bufferPointer); + + for (var j = 0; j < Constants.PhrasesPerSet; j++) + { + if (Vector.EqualsAny(expectedHashes, new Vector(bufferPointer[j * 8 + 7]))) + { + action(this.GetBytes(j), bufferPointer[j * 8 + 7]); + } + } + } } } } } } - public unsafe void ComputeMD5() - { - fixed (uint* inputBuffer = this.Buffer) - { - MD5Unmanaged.ComputeMD5(inputBuffer); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public uint GetMD5(int number) - { - return this.Buffer[number * 8 + 7]; - } - public unsafe byte[] GetBytes(int number) { Debug.Assert(number < Constants.PhrasesPerSet); diff --git a/dotnet/WhiteRabbit/StringsProcessor.cs b/dotnet/WhiteRabbit/StringsProcessor.cs index 974ba53..1b01936 100644 --- a/dotnet/WhiteRabbit/StringsProcessor.cs +++ b/dotnet/WhiteRabbit/StringsProcessor.cs @@ -130,21 +130,13 @@ var wordsVariants = this.ConvertVectorsToWordIndexes(sum); foreach (var wordsArray in Flattener.Flatten(wordsVariants)) { - //Console.WriteLine(new string(wordsArray.SelectMany(wordIndex => this.AllWords[wordIndex].Original).Select(b => (char)b).ToArray())); - - var permutations = PrecomputedPermutationsGenerator.HamiltonianPermutations(wordsArray.Length, permutationsFilter); - for (var i = 0; i < permutations.Length; i += Constants.PhrasesPerSet) - { - phraseSet.FillPhraseSet(initialPhraseSet, this.AllWords, wordsArray, permutations, i); - phraseSet.ComputeMD5(); - for (var j = 0; j < Constants.PhrasesPerSet; j++) - { - if (Vector.EqualsAny(expectedHashes, new Vector(phraseSet.GetMD5(j)))) - { - action(phraseSet.GetBytes(j), phraseSet.GetMD5(j)); - } - } - } + phraseSet.ProcessPermutations( + initialPhraseSet, + this.AllWords, + wordsArray, + PrecomputedPermutationsGenerator.HamiltonianPermutations(wordsArray.Length, permutationsFilter), + expectedHashes, + action); } } }