【问题标题】:Mask out part first 12 characters of string with *?用 *? 屏蔽部分字符串的前 12 个字符?
【发布时间】:2012-02-20 13:18:07
【问题描述】:

如何获取1234567890123451234567890123456 的值并将其转换为:

************2345************3456

上面两个字符串的区别是一个包含15位数字,另一个包含16位。

我尝试了以下方法,但它不保留 15 位数字的最后 4 位数字,现在不管字符串的长度是多少,无论是 13、14、15 还是 16,我都想屏蔽所有开头带 * 的数字,但保留最后 4 位。这是我尝试过的:

String.Format("{0}{1}", "************", str.Substring(11, str.Length - 12))

【问题讨论】:

  • 您是否希望它屏蔽任意数量的数字但只显示最后四位?
  • @anjunatl - 是的,我想屏蔽除最后 4 位以外的所有数字,无论长度如何。
  • 你能发布那个String.Format电话的上下文吗?它在测试应用程序中对我来说很好,所以你的问题在其他地方。
  • 它可以工作,但是当我在一个 15 位数字上使用它时,它只显示最后 3 个字符,我现在想显示所有四个字符,不管字符串有多长。
  • 添加了我的功能,目标是灵活性。

标签: c# .net c#-4.0


【解决方案1】:

如何取值 123456789012345 或 1234567890123456 并将其转换为:

************2345 和 ************3456

另一种方法:

var result = new string('*',0,value.Length - 4) + new string(value.Skip(value.Length - 4).ToArray())

// 或使用 string.Join

【讨论】:

    【解决方案2】:

    从头到尾屏蔽发送字符

    public static string Maskwith(this string value, int fromStart, int fromEnd, char ch)
        {
            return (value?.Length >= fromStart + fromEnd) ?
                 string.Concat(Enumerable.Repeat(ch, fromStart)) + value.Substring(fromStart, value.Length - (fromStart + fromEnd)) + string.Concat(Enumerable.Repeat(ch, fromEnd))
                 : "";
        } //Console.WriteLine("mytestmask".Maskwith(2,3,'*')); **testm***
    

    通过传递值从开始和结束显示字符并屏蔽中间

     public static string MasktheMiddle(this string value, int visibleCharLength, char ch)
        {
            if (value?.Length <=  (visibleCharLength * 2))
                return string.Concat(Enumerable.Repeat(ch,value.Length));
            else
                return value.Substring(0, visibleCharLength) + string.Concat(Enumerable.Repeat(ch, value.Length - (visibleCharLength * 2))) + value.Substring(value.Length - visibleCharLength);
    
        } //Console.WriteLine("mytestmask".MasktheMiddle(2,'*')); Result: my******sk
    

    【讨论】:

      【解决方案3】:
      // "123456789".MaskFront results in "****56789"
      public static string MaskFront(this string str, int len, char c)
          {
              var strArray = str.ToCharArray();
      
              for (var i = 0; i < len; i++)
              {
                  if(i < strArray.Length)
                  {
                      strArray[i] = c;
                  }
                  else
                  {
                      break;
                  }
              }
      
              return string.Join("", strArray);
          }
      
      // "123456789".MaskBack results in "12345****"
      public static string MaskBack(this string str, int len, char c)
      {
          var strArray = str.ToCharArray();
      
          var tracker = strArray.Length - 1;
          for (var i = 0; i < len; i++)
          {
              if (tracker > -1)
              {
                  strArray[tracker] = c;
                  tracker--;
              }
              else
              {
                  break;
              }
          }
      
          return string.Join("", strArray);
      }
      

      【讨论】:

      【解决方案4】:
      private string MaskDigits(string input)
      {
          //take first 6 characters
          string firstPart = input.Substring(0, 6);
      
          //take last 4 characters
          int len = input.Length;
          string lastPart = input.Substring(len - 4, 4);
      
          //take the middle part (****)
          int middlePartLenght = len - (firstPart.Length + lastPart.Length);
          string middlePart = new String('*', middlePartLenght);
      
          return firstPart + middlePart + lastPart;
      }
      
      MaskDigits("1234567890123456");
      
      // output : "123456******3456"
      

      【讨论】:

        【解决方案5】:

        类似这样的:

        string s = "1234567890123"; // example
        string result = s.Substring(s.Length - 4).PadLeft(s.Length, '*');
        

        这将屏蔽除字符串的最后四个字符之外的所有字符。它假定源字符串至少有 4 个字符长。

        【讨论】:

          【解决方案6】:

          带有匹配评估器的正则表达式将完成这项工作

          string filterCC(string source) {
            var x=new Regex(@"^\d+(?=\d{4}$)");
            return x.Replace(source,match => new String('*',match.Value.Length));
          }
          

          这将匹配任意数量的数字,后跟 4 位数字和结尾(它不会在替换中包含 4 位数字)。 replace 函数会将匹配项替换为等长的 * 字符串。

          这还有一个额外的好处,即您也可以将其用作验证算法。将第一个 + 更改为 {11,12} 以使其匹配总共 15 或 16 个字符,然后您可以使用 x.IsMatch 来确定有效性。

          编辑

          或者,如果您总是想要 16 个字符的结果,只需使用

           return x.Replace(source,new String('*',12));
          

          【讨论】:

            【解决方案7】:

            试试这个:

            static string Mask(string str)
            {
                if (str.Length <= 4) return str;
                Regex rgx = new Regex(@"(.*?)(\d{4})$");
                string result = String.Empty;
                if (rgx.IsMatch(str))
                {
                    for (int i = 0; i < rgx.Matches(str)[0].Groups[1].Length; i++)
                        result += "*";
                    result += rgx.Matches(str)[0].Groups[2];
                    return result;
                }
                return str;
            }
            

            【讨论】:

              【解决方案8】:

              试试这个:

              var maskSize = ccDigits.Length - 4;
              var mask = new string('*', maskSize) + ccDigits.Substring(maskSize);
              

              【讨论】:

              • 这行得通,但创建的字符串都是 17 个字符长。
              • 真的吗?我似乎得到 15 或 16,具体取决于。
              • 针对这13个长度值22222222222221,返回17个字符。
              【解决方案9】:
              using System;
              
              class Program
              {
                  static void Main()
                  {
                      var str = "1234567890123456";
                      if (str.Length > 4)
                      {
                          Console.WriteLine(
                              string.Concat(
                                  "".PadLeft(12, '*'), 
                                  str.Substring(str.Length - 4)
                              )
                          );
                      }
                      else
                      {
                          Console.WriteLine(str);
                      }
                  }
              }
              

              【讨论】:

              • 你为什么从 string.Format 更改为 string.Concat,在这种情况下,它会创建一个 17 个字符长度的字符串、13 个 * 和最后 4 个数字。
              • 我刚刚将 PadLeft 函数中的 13 更改为 12,这似乎可以解决问题。
              • new String('*',12) 可能比"".PadLeft(12,'*') 更容易阅读
              • @BobVale - 使用其中任何一个都有性能或好处吗?
              • 我认为在空字符串常量上调用 PadLeft 看起来有点不确定。为什么不只是 str.Substring(str.Length - 4).PadLeft(16, '*')
              【解决方案10】:

              一个简单的方法

                 string s = "1234567890123"; // example
                 int l = s.Length;
                 s = s.Substring(l - 4);
                 string r = new string('*', l);
                 r = r + s;
              

              【讨论】:

                【解决方案11】:
                static private String MaskInput(String input, int charactersToShowAtEnd)
                {
                  if (input.Length < charactersToShowAtEnd)
                  {
                    charactersToShowAtEnd = input.Length;
                  }
                  String endCharacters = input.Substring(input.Length - charactersToShowAtEnd);
                  return String.Format(
                    "{0}{1}", 
                    "".PadLeft(input.Length - charactersToShowAtEnd, '*'), 
                    endCharacters
                    );
                }
                

                根据需要调整函数头,调用方式:

                MaskInput("yourInputHere", 4);
                

                【讨论】:

                • 我喜欢它,但我已经替换了 charactersToShowAtEnd = input.Length;通过返回输入 ;-)
                【解决方案12】:

                尝试以下方法:

                    private string MaskString(string s)
                    {
                        int NUM_ASTERISKS = 4;
                
                        if (s.Length < NUM_ASTERISKS) return s;
                
                        int asterisks = s.Length - NUM_ASTERISKS;
                        string result = new string('*', asterisks);
                        result += s.Substring(s.Length - NUM_ASTERISKS);
                        return result;
                    }
                

                【讨论】:

                • 这就是我想要的,但我认为这更优雅。不错!
                【解决方案13】:

                最简单的方法:创建一个扩展方法来提取最后四位数字。在您的 String.Format 调用中使用它。

                例如:

                public static string LastFour(this string value)
                {
                    if (string.IsNullOrEmpty(value) || value.length < 4)
                    {
                        return "0000";
                    }
                    return value.Substring(value.Length - 4, 4) 
                }
                

                在您的代码中:

                String.Format("{0}{1}", "************", str.LastFour());
                

                在我看来,这会导致代码更具可读性,并且可以重用。

                编辑:也许不是最简单的方法,而是一种可能产生更易于维护的结果的替代方法。

                【讨论】:

                • 想解释一下否决票?他显然在处理信用卡号码。可重用性是一个问题。
                • 我喜欢扩展方法,但只需要在一个地方,所以一个衬垫会更好。点赞
                • 根据我的经验,你只认为你需要它在一个地方。 :-)
                • 不是我的反对意见,但是如果您寻求可重复使用的解决方案,为什么不更优雅地处理输入 1 到 3 个字符的情况,并将字符数作为参数,而您在是吗?
                • @kuroineko 当时,这是针对特定情况(屏蔽 SSN)。当然,您可以创建一个带有附加参数并使其更可用的重载。这是差不多十年前的事了,我今天很可能会这样做。但一般来说,在我们真正需要它之前,我们不会创建功能。
                【解决方案14】:

                LINQ:

                char maskBy = '*'; 
                string input = "123456789012345";
                int count = input.Length <= 4 ? 0 : input.Length - 4; 
                string output = new string(input.Select((c, i) => i < count ? maskBy : c).ToArray()); 
                

                【讨论】:

                  猜你喜欢
                  • 2017-10-27
                  • 2014-09-07
                  • 2017-09-17
                  • 2013-06-27
                  • 2017-12-15
                  • 2020-01-09
                  • 2019-11-20
                  • 2016-12-06
                  • 2020-10-13
                  相关资源
                  最近更新 更多