簡體   English   中英

屏蔽除字符串的前 6 位和后 4 位以外的所有數字(長度不同)

[英]mask all digits except first 6 and last 4 digits of a string( length varies )

我有一個卡號作為字符串,例如:

string  ClsCommon.str_CardNumbe r = "3456123434561234";

此卡號的長度可以從 16 到 19 位不等,具體取決於要求。

我的要求是我必須顯示卡號的前六位和后四位數字,並用字符“X”屏蔽中間的其他字符。

我試過使用 subString 並分別為 16、17、18、19 位數字實現它。

我將字符串 (ClsCommon.str_CardNumber) 拆分為 5 個字符串(str_cardNum1、str_cardNum2、str_cardNum3、str_cardNum4、str_cardNum5 - 每個字符串 4 位數字......第 5 個字符串的剩余數字)

所有字符串都放在 ClsCommon 文件中。 基於此,我實施了以下內容,效果很好:

if (ClsCommon.str_CardNumber.Length == 16) {
    txtmskcrdnum.Text = string.Concat(ClsCommon.str_cardNum1, " ", ClsCommon.str_cardNum2.Substring(0, 2), "XX", " ", "XXXX", " ", ClsCommon.str_cardNum4);

}
if (ClsCommon.str_CardNumber.Length == 17) {
    txtmskcrdnum.Text = string.Concat(ClsCommon.str_cardNum1, " ", ClsCommon.str_cardNum2.Substring(0, 2), "XX", " ", "XXXX", " ", "X", ClsCommon.str_cardNum4.Substring(1, 3), " ", ClsCommon.str_cardNum5);
}
if (ClsCommon.str_CardNumber.Length == 18) {
    txtmskcrdnum.Text = string.Concat(ClsCommon.str_cardNum1, " ", ClsCommon.str_cardNum2.Substring(0, 2), "XX", " ", "XXXX", " ", "XX", ClsCommon.str_cardNum4.Substring(2, 2), " ", ClsCommon.str_cardNum5);
}


if (ClsCommon.str_CardNumber.Length == 19) {
    txtmskcrdnum.Text = string.Concat(ClsCommon.str_cardNum1, " ", ClsCommon.str_cardNum2.Substring(0, 2), "XX", " ", "XXXX", " ", "XXX", ClsCommon.str_cardNum4.Substring(3, 1), " ", ClsCommon.str_cardNum5);
}
txtmskcrdnum.Text = ClsCommon.str_CardNumber.PadLeft(ClsCommon.str_CardNumber.Length, 'X').Substring(ClsCommon.str_CardNumber.Length - 4);

對於多個長度,上述方法沒有用。

我想要一種顯示前 6 位和后 4 位數字並用 X 屏蔽其他數字的單一方法。最終字符串應該在每 4 位數字之間有一個空格。

這適用於任何卡號長度:

var cardNumber = "3456123434561234";

var firstDigits = cardNumber.Substring(0, 6);
var lastDigits = cardNumber.Substring(cardNumber.Length - 4, 4);

var requiredMask = new String('X', cardNumber.Length - firstDigits.Length - lastDigits.Length);

var maskedString = string.Concat(firstDigits, requiredMask, lastDigits);
var maskedCardNumberWithSpaces = Regex.Replace(maskedString, ".{4}", "$0 ");

我會做這樣的事情(偽C# - 以粗略的想法為基礎)。

未經測試的代碼......

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 (XXXXXXXXX)
    int middlePartLenght = input.Substring(6, len - 4).Count();
    string middlePart = new String('X', 5);

    return firstPart + middlePart + lastPart;
}

試試這個吧。 簡單直接。

public static class StringExtensions
{
    public static string Masked(this string source, int start, int count)
    {
        return source.Masked('x', start, count);
    }

    public static string Masked(this string source, char maskValue, int start, int count)
    {
        var firstPart = source.Substring(0, start);
        var lastPart = source.Substring(start + count);
        var middlePart = new string(maskValue, count);

        return firstPart + middlePart + lastPart;
    }
}

我確信有一種更清潔的方法可以做到這一點:

int currentChar = 0;
string maskable = "11111144441111";

string masked = maskable;
int length = masked.Length;

int startMaskPoint = 6;
int endMaskPoint = length - 4 - startMaskPoint;

masked = masked.Remove(startMaskPoint, endMaskPoint);

int numRemoved = length - masked.Length;
string Mask = "";
while (numRemoved != 0)
{
    Mask = Mask + "#";
    numRemoved--;
}

masked = masked.Insert(startMaskPoint, Mask);
string returnableString = masked;
while (length > 4)
{
    returnableString = returnableString.Insert(currentChar + 4, " ");
    currentChar = currentChar + 5;
    length = length - 4;
}

可能的實現(接受varios格式,例如數字可以分成組等):

private static String MaskedNumber(String source) {
  StringBuilder sb = new StringBuilder(source);

  const int skipLeft = 6;
  const int skipRight = 4;

  int left = -1;

  for (int i = 0, c = 0; i < sb.Length; ++i) {
    if (Char.IsDigit(sb[i])) {
      c += 1;

      if (c > skipLeft) {
        left = i;

        break;
      }
    }
  }

  for (int i = sb.Length - 1, c = 0; i >= left; --i)
    if (Char.IsDigit(sb[i])) {
      c += 1;

      if (c > skipRight)
        sb[i] = 'X';
    }

  return sb.ToString();
}

// Tests 

  // 3456-12XX-XXXX-1234
  Console.Write(MaskedNumber("3456-1234-3456-1234"));
  // 3456123XXXXX1234
  Console.Write(MaskedNumber("3456123434561234"));

此實現只是屏蔽數字並保留格式。

一種方法:

string masked = null;
for (int i = 0; i < str_CardNumber.Length; i++) {
    masked += (i > 5 && i < str_CardNumber.Length - 4) ? 'X' : str_CardNumber[i];
    if ((i + 1) % 4 == 0)
        masked += " ";
}

如何使用Regex替換特定的匹配組:

        string cardNumber = "3456123434561234";
        var pattern = "^(.{6})(.+)(.{4})$";
        var maskedNumber = Regex.Replace(cardNumber, pattern, (match) =>
        {
           return Regex.Replace(String.Format("{0}{1}{2}",
           match.Groups[1].Value, // the first 6 digits
           new String('X', match.Groups[2].Value.Length), // X times the 'X' char
           match.Groups[3].Value) /*the last 4 digits*/,".{4}", "$0 "); //finally add a separator every 4 char
        });

許多給定的解決方案多次解析輸入。 下面我提出一個只解析輸入一次的解決方案。 但是我沒有C#的經驗,所以函數是用Scheme編寫的。

功能分為兩個:

(1)visit-first-6解析前六個字符並將它們連接到其余的計算中。 當visit-first-6解析了前六個字符時,它會調用visit-rest。

(2)訪問 - 休息利用我們可以延遲一些計算直到我們獲得更多知識的事實。 在這種情況下,我們等待確定是否應該顯示列表中的元素,直到我們知道剩下多少個字符。

(define (mask xs)
  (letrec ([visit-first-6 (lambda (xs chars-parsed)
                            (cond
                              [(null? xs)
                               ;; Shorter than 6 characters.
                               '()]
                              [(< chars-parsed 6)
                               ;; Still parsing the first 6 characters
                               (cons (car xs)
                                     (visit-first-6 (cdr xs)
                                                    (1+ chars-parsed)))]
                              [else
                               ;; The first 6 characters have been parsed.
                               (visit-rest xs
                                           (lambda (ys chars-left)
                                             ys))]))]
           [visit-rest (lambda (xs k)
                         (if (null? xs)
                             ;; End of input
                             (k '() 0)
                             ;; Parsing rest of the input
                             (visit-rest (cdr xs)
                                         (lambda (rest chars-left)
                                           (if (< chars-left 4)
                                               ;; Show the last 4 characters
                                               (k (cons (car xs) rest)
                                                  (1+ chars-left))
                                               ;; Don't show the middle characters
                                               (k (cons "X"
                                                        rest)
                                                  (1+ chars-left)))))))])
    (visit-first-6 xs
                   0)))

在Petite Chez Scheme翻譯中運行面具

> (mask '(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18))
(1 2 3 4 5 6 "X" "X" "X" "X" "X" "X" "X" "X" 15 16 17 18)
> (mask '())
()
> (mask '(1 2 3 4))
(1 2 3 4)
> (mask '(1 2 3 4 5))
(1 2 3 4 5)
> (mask '(1 2 3 4 5 6 7 8 9))
(1 2 3 4 5 6 7 8 9)
> (mask '(1 2 3 4 5 6 7 8 9 10))
(1 2 3 4 5 6 7 8 9 10)
> (mask '(1 2 3 4 5 6 7 8 9 10 11))
(1 2 3 4 5 6 "X" 8 9 10 11)

NB。 我認為這是一個有趣的練習,我想我也可以分享它。 Yannick Meeus已經提供了一個易於理解的解決方案。 所以,這只適合感興趣的人。

Linq保存了編碼行,小代碼片段。

用(*)char替換6以上,低於CardPan長度減去4

var CardPan = "1234567890123456";
var maskedPan = CardPan.Aggregate(string.Empty, (value, next) =>
{
    if (value.Length >= 6 && value.Length < CardPan.Length - 4)
    {
        next = '*';
    }
    return value + next;
});
str.substring(0, 5) +
                str.substring(5, str.length() - 3)
                .replaceAll("[\\d]", "x") +
                str.substring(str.length() - 3, str.length());

//這里是最簡單的方法

我認為這是最簡單的形式。 PadLeft/PadRight 沒有幫助我。

假設我有信用卡號(“2512920040512345”)並屏蔽除最后 4 位數字(“XXXXXXXXXXXX2345”)之外的所有數字。

//C# code will give you the desired output. Replace the string with your CreditCardno variable
new string('X', "2512920040512345".Length-4)+ "2512920040512345".Substring( "2512920040512345".Length-4, 4)

更好的方法是使用如下所示的字符串格式:

YourData = string.Format("************{0}", YourData.Trim().Substring(12, 4));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM