public string MaskSecrets(string input) { if (string.IsNullOrEmpty(input)) { return(string.Empty); } // get indexes and lengths of all substrings that will be replaced var positionsToReplace = new List <ReplacementPosition>(); foreach (KeyValuePair <string, RegexSecret> pair in _regexSecrets) // This is faster than calling .Values. { positionsToReplace.AddRange(pair.Value.GetPositions(input)); } foreach (KeyValuePair <string, ValueSecret> pair in _valueSecrets) // This is faster than calling .Values. { positionsToReplace.AddRange(pair.Value.GetPositions(input)); } // short-circuit if nothing to replace if (positionsToReplace.Count == 0) { return(input); } // merge positions into ranges of characters to replace List <ReplacementPosition> replacementPositions = new List <ReplacementPosition>(); ReplacementPosition currentReplacement = null; foreach (var substring in positionsToReplace.OrderBy(t => t.Start)) { if (currentReplacement == null) { currentReplacement = new ReplacementPosition(substring.Start, substring.Length); replacementPositions.Add(currentReplacement); } else { if (substring.Start <= currentReplacement.End) { // overlap currentReplacement.Length = Math.Max(currentReplacement.End, substring.Start + substring.Length) - currentReplacement.Start; } else { // no overlap currentReplacement = new ReplacementPosition(substring.Start, substring.Length); replacementPositions.Add(currentReplacement); } } } // replace var stringBuilder = new StringBuilder(); int startIndex = 0; foreach (var replacement in replacementPositions) { stringBuilder.Append(input.Substring(startIndex, replacement.Start - startIndex)); stringBuilder.Append(Mask); startIndex = replacement.Start + replacement.Length; } if (startIndex < input.Length) { stringBuilder.Append(input.Substring(startIndex)); } return(stringBuilder.ToString()); }
public string MaskSecrets(string input) { if (string.IsNullOrEmpty(input)) { return string.Empty; } // get indexes and lengths of all substrings that will be replaced var positionsToReplace = new List<ReplacementPosition>(); foreach (KeyValuePair<string, RegexSecret> pair in _regexSecrets) // This is faster than calling .Values. { positionsToReplace.AddRange(pair.Value.GetPositions(input)); } foreach (KeyValuePair<string, ValueSecret> pair in _valueSecrets) // This is faster than calling .Values. { positionsToReplace.AddRange(pair.Value.GetPositions(input)); } // short-circuit if nothing to replace if (positionsToReplace.Count == 0) { return input; } // merge positions into ranges of characters to replace List<ReplacementPosition> replacementPositions = new List<ReplacementPosition>(); ReplacementPosition currentReplacement = null; foreach (var substring in positionsToReplace.OrderBy(t => t.Start)) { if (currentReplacement == null) { currentReplacement = new ReplacementPosition(substring.Start, substring.Length); replacementPositions.Add(currentReplacement); } else { if (substring.Start <= currentReplacement.End) { // overlap currentReplacement.Length = Math.Max(currentReplacement.End, substring.Start + substring.Length) - currentReplacement.Start; } else { // no overlap currentReplacement = new ReplacementPosition(substring.Start, substring.Length); replacementPositions.Add(currentReplacement); } } } // replace var stringBuilder = new StringBuilder(); int startIndex = 0; foreach (var replacement in replacementPositions) { stringBuilder.Append(input.Substring(startIndex, replacement.Start - startIndex)); stringBuilder.Append(Constants.SecretMask); startIndex = replacement.Start + replacement.Length; } if (startIndex < input.Length) { stringBuilder.Append(input.Substring(startIndex)); } return stringBuilder.ToString(); }