Beispiel #1
0
        public void MaskRandom()
        {
            //Arrange
            const String       TEXT             = "The cat is a good friend too.";
            const Single       COVERAGE         = 0.5f;
            const MaskTextMode MODE             = MaskTextMode.Random;
            const Int32        COUNT_MASK_CHARS = 12;

            //Act
            var result = StringHelpers.MaskText(TEXT, COVERAGE, MODE);

            //Assert
            Assert.AreEqual(COUNT_MASK_CHARS, result.Count(c => c == '*'));
        }
Beispiel #2
0
        public void MaskEnding1()
        {
            //Arrange
            const String       TEXT     = "The cat is a good friend too.";
            const Single       COVERAGE = 1f;
            const MaskTextMode MODE     = MaskTextMode.Ending;
            const String       EXPECTED = "*** *** ** * **** ****** ****";

            //Act
            var result = StringHelpers.MaskText(TEXT, COVERAGE, MODE);

            //Assert
            Assert.AreEqual(EXPECTED, result);
        }
Beispiel #3
0
        public void MaskIntervaled()
        {
            //Arrange
            const String       TEXT     = "The cat is a good friend too.";
            const Single       COVERAGE = 0.5f;
            const MaskTextMode MODE     = MaskTextMode.Intervaled;
            const String       EXPECTED = "**e *a* i* a *o*d *r*e*d *o*.";

            //Act
            var result = StringHelpers.MaskText(TEXT, COVERAGE, MODE);

            //Assert
            Assert.AreEqual(EXPECTED, result);
        }
Beispiel #4
0
        public void MaskSkipChars()
        {
            //Arrange
            const String       TEXT             = "111.111.111-00";
            const Single       COVERAGE         = 0.7f;
            const MaskTextMode MODE             = MaskTextMode.Intervaled;
            const Int32        COUNT_MASK_CHARS = 8;
            const Char         REPLACEMENT_CHAR = '°';

            //Act
            var result = StringHelpers.MaskText(TEXT, COVERAGE, MODE, REPLACEMENT_CHAR, new[] { '.', '-' });

            //Assert
            Assert.AreEqual(COUNT_MASK_CHARS, result.Count(c => c == REPLACEMENT_CHAR));
        }
        /// <summary>
        /// Mask text with a replacement char.
        /// </summary>
        /// <param name="text">Text to mask.</param>
        /// <param name="coverage">Coverage percentage, where 0 is no coverage and 1 is full coverage.</param>
        /// <param name="mode">Chosse between coverage styles to prevent the text to be guessable.</param>
        /// <param name="replacementChar">Char to use as the mask.</param>
        /// <param name="skipChars">Do not mask the char specified by this parameter.</param>
        /// <returns></returns>
        public static String MaskText(this String text, Single coverage, MaskTextMode mode, Char replacementChar, Char[] skipChars)
        {
            if (coverage < 0 || coverage > 1)
            {
                throw new ArgumentOutOfRangeException(nameof(coverage));
            }
            if (String.IsNullOrEmpty(text) || coverage == 0)
            {
                return(text);
            }

            var maskableChar = new Func <Char, Boolean>
                                   (c =>
                                   c.IsPrintableChar()
                                   &&
                                   (skipChars == null || !skipChars.Contains(c))
                                   );

            const Byte MASKABLE_CHAR = 0;
            const Byte JUMP_CHAR     = 1;
            const Byte MASKED_CHAR   = 2;

            var textMap = new Byte[text.Length];

            for (var i = 0; i < text.Length; i++)
            {
                textMap[i] = maskableChar(text[i]) ? MASKABLE_CHAR : JUMP_CHAR;
            }
            var maskableLength       = textMap.Count(t => t == MASKABLE_CHAR);
            var coverageTargetLength = (Int32)Math.Round(maskableLength * coverage);

            switch (mode)
            {
            case MaskTextMode.Begining:
                for (var i = 0; i < textMap.Length && coverageTargetLength > 0; i++)
                {
                    if (textMap[i] == MASKABLE_CHAR)
                    {
                        textMap[i] = MASKED_CHAR;
                        coverageTargetLength--;
                    }
                }
                break;

            case MaskTextMode.Ending:
                for (var i = textMap.Length - 1; i >= 0 && coverageTargetLength > 0; i--)
                {
                    if (textMap[i] == MASKABLE_CHAR)
                    {
                        textMap[i] = MASKED_CHAR;
                        coverageTargetLength--;
                    }
                }
                break;

            case MaskTextMode.Center:
                var diff_center  = maskableLength - coverageTargetLength;
                var countToStart = (Int32)Math.Round(diff_center / 2f);
                for (var i = 0; i < textMap.Length && coverageTargetLength > 0; i++)
                {
                    if (textMap[i] == MASKABLE_CHAR && countToStart-- <= 0)
                    {
                        textMap[i] = MASKED_CHAR;
                        coverageTargetLength--;
                    }
                }
                break;

            case MaskTextMode.Ends:
                var padding_start = (Int32)Math.Floor(coverageTargetLength / 2f);
                var padding_end   = padding_start;
                if (padding_start + padding_end < coverageTargetLength)
                {
                    padding_start++;
                }

                for (var i = 0; i < textMap.Length && padding_start > 0; i++)
                {
                    if (textMap[i] == MASKABLE_CHAR)
                    {
                        textMap[i] = MASKED_CHAR;
                        padding_start--;
                    }
                }
                for (var i = textMap.Length - 1; i >= 0 && padding_end > 0; i--)
                {
                    if (textMap[i] == MASKABLE_CHAR)
                    {
                        textMap[i] = MASKED_CHAR;
                        padding_end--;
                    }
                }
                break;

            case MaskTextMode.Intervaled:
                var interval = (Int32)Math.Round(maskableLength / (Single)coverageTargetLength);
                if (interval < 2)
                {
                    interval = 2;
                }
                var intervalCount = 0;

                while (coverageTargetLength > 0)
                {
                    for (var i = 0; i < textMap.Length; i++)
                    {
                        if (textMap[i] == MASKABLE_CHAR && ++intervalCount >= interval)
                        {
                            textMap[i] = MASKED_CHAR;
                            coverageTargetLength--;
                            intervalCount = 0;

                            if (coverageTargetLength == 0)
                            {
                                break;
                            }
                        }
                    }
                }
                break;

            case MaskTextMode.Random:
                var random = new Random();
                while (coverageTargetLength > 0)
                {
                    var index = random.Next(0, text.Length);
                    if (textMap[index] == MASKABLE_CHAR)
                    {
                        textMap[index] = MASKED_CHAR;
                        coverageTargetLength--;
                    }
                }
                break;
            }

            var result = new StringBuilder(text);

            for (var i = 0; i < text.Length; i++)
            {
                if (textMap[i] == MASKED_CHAR)
                {
                    result[i] = replacementChar;
                }
            }

            return(result.ToString());
        }
 /// <summary>
 /// Mask text with a replacement char.
 /// </summary>
 /// <param name="text">Text to mask.</param>
 /// <param name="coverage">Coverage percentage, where 0 is no coverage and 1 is full coverage.</param>
 /// <param name="mode">Chosse between coverage styles to prevent the text to be guessable.</param>
 /// <param name="replacementChar">Char to use as the mask.</param>
 /// <returns></returns>
 public static String MaskText(this String text, Single coverage, MaskTextMode mode, Char replacementChar)
 {
     return(MaskText(text, coverage, mode, replacementChar, null));
 }
 /// <summary>
 /// Mask text with a replacement char.
 /// </summary>
 /// <param name="text">Text to mask.</param>
 /// <param name="coverage">Coverage percentage, where 0 is no coverage and 1 is full coverage.</param>
 /// <param name="mode">Chosse between coverage styles to prevent the text to be guessable.</param>
 /// <returns></returns>
 public static String MaskText(this String text, Single coverage, MaskTextMode mode)
 {
     return(MaskText(text, coverage, mode, '*'));
 }