private Task <string> StartDecryptionAsync(string hash, int maxTextLength, string chars, CancellationToken token) { var hashDecryption = _runningDecryptions.GetOrAdd(hash, _ => new HashDecryption()); return(hashDecryption.GetOrAdd(maxTextLength, chars, async _ => { using var linkedCts = hashDecryption.CreateLinkedTokenSource(token); Func <Task <string> > decryption = async() => { try { var text = await DesDecryptor.DecryptAsync(hash, maxTextLength, chars, linkedCts.Token); _runningDecryptions.TryRemove(hash, out var _); _logger.LogInformation($"Decryption of the {nameof(hash)} '{hash}' with " + $"{nameof(maxTextLength)} = {maxTextLength} and {nameof(chars)} = '{chars}' succeeded. " + $"The {nameof(hash)} '{hash}' corresponds to '{text}'."); return text; } catch (OperationCanceledException) { if (_cache.TryGetValue(hash, out string text)) { _logger.LogInformation($"Another task successfully decrypted " + $"the {nameof(hash)} '{hash}' and it corresponds to '{text}'."); return text; } throw; } finally { hashDecryption.TryRemove(maxTextLength, chars, out var _); } }; var text = await _cache.GetOrCreateAsync(hash, async cacheEntry => { var text = await decryption(); cacheEntry.Size = text.Length; return text; }); hashDecryption.CancelAll(); return text; })); }
static async Task <int> Main(string[] args) { if (args.Length != 1) { Console.WriteLine("Usage: ./crack hash\n"); return(1); } try { Console.WriteLine($"{await DesDecryptor.DecryptAsync(args[0], MaxWordLength, Chars)}\n"); return(0); } catch (Exception e) { Console.WriteLine(e.Message); } return(1); }