You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
TrustPilotChallenge/dotnet/WhiteRabbit/PhraseSet.cs

62 lines
2.2 KiB

namespace WhiteRabbit
{
// Anagram representation optimized for MD5
internal unsafe struct PhraseSet
{
public fixed uint Buffer[8 * Constants.PhrasesPerSet];
public PhraseSet(byte[][] words, int[][] permutations, int offset, int numberOfCharacters)
{
fixed (uint* bufferPointer = this.Buffer)
{
var length = numberOfCharacters + words.Length - 1;
for (var i = 0; i < Constants.PhrasesPerSet; i++)
{
var permutation = permutations[offset + i];
var startPointer = bufferPointer + i * 8;
byte[] currentWord;
var j = 0;
var wordIndex = 0;
var currentPointer = (byte*)startPointer;
byte* lastPointer = currentPointer + length;
for (; currentPointer < lastPointer; currentPointer++)
{
currentWord = words[permutation[wordIndex]];
*currentPointer = currentWord[j];
j++;
// 0xffffffff if greater than or equal, 0 if less than
var comparisonResult = unchecked((int)((((uint)j - (uint)currentWord.Length) >> 31) - 1));
j = (comparisonResult & 0) | (~comparisonResult & j);
wordIndex = (comparisonResult & (wordIndex + 1)) | (~comparisonResult & wordIndex);
}
*currentPointer = 128;
startPointer[7] = (uint)(length << 3);
}
}
}
public byte[] GetBytes(int number)
{
System.Diagnostics.Debug.Assert(number < Constants.PhrasesPerSet);
fixed(uint* bufferPointer = this.Buffer)
{
var phrasePointer = bufferPointer + 8 * number;
var length = phrasePointer[7] >> 3;
var result = new byte[length];
for (var i = 0; i < length; i++)
{
result[i] = ((byte*)phrasePointer)[i];
}
return result;
}
}
}
}