/// <summary> /// Record a hash new hash entry in the hash table. /// </summary> /// <param name="hashCodeA"> /// Hash Code for Board position A /// </param> /// <param name="hashCodeB"> /// Hash Code for Board position B /// </param> /// <param name="depth"> /// The search depth. /// </param> /// <param name="val"> /// The score of the position to record. /// </param> /// <param name="type"> /// The position type: alpha, beta or exact value. /// </param> /// <param name="from"> /// From square ordinal. /// </param> /// <param name="to"> /// To square ordinal. /// </param> /// <param name="moveName"> /// The move name. /// </param> /// <param name="colour"> /// The player colour. /// </param> public static unsafe void RecordHash( ulong hashCodeA, ulong hashCodeB, int depth, int val, HashTypeNames type, int from, int to, Move.MoveNames moveName, Player.PlayerColourNames colour) { Writes++; fixed (HashEntry* phashBase = &hashTableEntries[0]) { HashEntry* phashEntry = phashBase; phashEntry += (uint)(hashCodeA % hashTableSize); int intAttempt = 0; while (phashEntry >= phashBase && phashEntry->HashCodeA != 0 && phashEntry->Depth > depth) { phashEntry--; intAttempt++; if (intAttempt == HashTableSlotDepth) { break; } } if (phashEntry < phashBase) { phashEntry = phashBase; } if (phashEntry->HashCodeA != 0) { Collisions++; if (phashEntry->HashCodeA != hashCodeA || phashEntry->HashCodeB != hashCodeB) { Overwrites++; phashEntry->WhiteFrom = -1; phashEntry->BlackFrom = -1; } } phashEntry->HashCodeA = hashCodeA; phashEntry->HashCodeB = hashCodeB; phashEntry->Result = val; phashEntry->Type = type; phashEntry->Depth = (sbyte)depth; phashEntry->Colour = colour; if (from > -1) { if (colour == Player.PlayerColourNames.White) { phashEntry->WhiteMoveName = moveName; phashEntry->WhiteFrom = (sbyte)from; phashEntry->WhiteTo = (sbyte)to; } else { phashEntry->BlackMoveName = moveName; phashEntry->BlackFrom = (sbyte)from; phashEntry->BlackTo = (sbyte)to; } } } }
/// <summary> /// Record a hash new hash entry in the hash table. /// </summary> /// <param name="hashCodeA"> /// Hash Code for Board position A /// </param> /// <param name="hashCodeB"> /// Hash Code for Board position B /// </param> /// <param name="depth"> /// The search depth. /// </param> /// <param name="val"> /// The score of the position to record. /// </param> /// <param name="type"> /// The position type: alpha, beta or exact value. /// </param> /// <param name="from"> /// From square ordinal. /// </param> /// <param name="to"> /// To square ordinal. /// </param> /// <param name="moveName"> /// The move name. /// </param> /// <param name="colour"> /// The player colour. /// </param> public static unsafe void RecordHash( ulong hashCodeA, ulong hashCodeB, int depth, int val, HashTypeNames type, int from, int to, Move.MoveNames moveName, Player.PlayerColourNames colour) { Writes++; fixed(HashEntry *phashBase = &hashTableEntries[0]) { HashEntry *phashEntry = phashBase; phashEntry += (uint)(hashCodeA % hashTableSize); int intAttempt = 0; while (phashEntry >= phashBase && phashEntry->HashCodeA != 0 && phashEntry->Depth > depth) { phashEntry--; intAttempt++; if (intAttempt == HashTableSlotDepth) { break; } } if (phashEntry < phashBase) { phashEntry = phashBase; } if (phashEntry->HashCodeA != 0) { Collisions++; if (phashEntry->HashCodeA != hashCodeA || phashEntry->HashCodeB != hashCodeB) { Overwrites++; phashEntry->WhiteFrom = -1; phashEntry->BlackFrom = -1; } } phashEntry->HashCodeA = hashCodeA; phashEntry->HashCodeB = hashCodeB; phashEntry->Result = val; phashEntry->Type = type; phashEntry->Depth = (sbyte)depth; phashEntry->Colour = colour; if (from > -1) { if (colour == Player.PlayerColourNames.White) { phashEntry->WhiteMoveName = moveName; phashEntry->WhiteFrom = (sbyte)from; phashEntry->WhiteTo = (sbyte)to; } else { phashEntry->BlackMoveName = moveName; phashEntry->BlackFrom = (sbyte)from; phashEntry->BlackTo = (sbyte)to; } } } }
static void Main(string[] args) { string filePath = null; string hashToTestAgainst = null; HashType hashType = HashType.Unknown; string hashTypeName = null; bool readFromStandardInput = false; int ignoredArgsCount = 0; consoleInputStreamReference = Console.OpenStandardInput(); // arguments detection foreach (var argument in args) { var comparer = StringComparer.OrdinalIgnoreCase; if (comparer.Equals(argument, "/?") || comparer.Equals(argument, "/help") || comparer.Equals(argument, "-h") || comparer.Equals(argument, "--help")) { DisplayHelp(); return; } if (HashTypeNames.Any(x => StringComparer.OrdinalIgnoreCase.Equals(x.Value, argument))) { // the user requested a specific algorithm by its name hashTypeName = argument; } else { // check for a hash string // for md5: 128 bits is 16 bytes. with 2 chars per byte in hexa. hence the "* 4" int hashTypeBits = argument.Length * 4; if (Enum.IsDefined(typeof(HashType), hashTypeBits) && //the length corresponds to a hash string Regex.IsMatch(argument, @"^[0-9A-F]*$", RegexOptions.IgnoreCase)) // the string is a valid hexadecimal number { hashToTestAgainst = argument; hashType = (HashType)hashTypeBits; } else { // check if it's a valid file string withoutQuotes = argument.Trim(new char[] { '"' }); if (File.Exists(withoutQuotes)) { filePath = withoutQuotes; } else { // if the arg is not an algorithm name, not a hash, and not a valid file, it is ignored. ignoredArgsCount++; Console.WriteLine($"Unexpected argument will be ignored: {argument}"); } } } } if (!Console.IsInputRedirected) // input directly from the user { if (args.Length - ignoredArgsCount == 0) { DisplayHelp(); return; } else { Console.CancelKeyPress += (o, e) => { e.Cancel = true; consoleInputStreamReference.Dispose(); }; } } if (filePath == null) // if the path is set, we already verified it's valid { readFromStandardInput = true; } else { if (Console.IsInputRedirected) { Console.WriteLine("WARNING: The standard input is redirected, but a file was also specified.\nIgnoring the standard input..."); } } if (hashType == HashType.Unknown) // meaning no hash string was provided { var match = HashTypeNames.FirstOrDefault(x => StringComparer.OrdinalIgnoreCase.Equals(x.Value, hashTypeName)); if (match.Key != HashType.Unknown) { hashType = match.Key; } else { hashType = DefaultAlgorithm; } } // let's hash! StreamHasher asyncHasher = new StreamHasher(HashAlgorithm.Create(HashTypeNames[hashType])); asyncHasher.FileHashingProgress += new EventHandler <FileHashingProgressArgs>(asyncHash_FileHashingProgress); if (readFromStandardInput) { using (var stdIn = consoleInputStreamReference) { asyncHasher.ComputeHash(stdIn); } } else { using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { asyncHasher.ComputeHash(fs); } } Console.WriteLine(); string resultHash = asyncHasher.GetHashString(); if (hashToTestAgainst == null) { Console.WriteLine($"\nResult: {resultHash}"); } else { bool isOk = StringComparer.OrdinalIgnoreCase.Equals(resultHash, hashToTestAgainst); Console.WriteLine($"\nReference: {hashToTestAgainst}\nCalculated: {resultHash}\n\nResult: {(isOk ? "OK" : "FAIL")}"); } }