it-swarm.com.de

alle Ziffern außer den ersten 6 und den letzten 4 Ziffern einer Zeichenkette maskieren (Länge variiert)

Ich habe eine Kartennummer als Zeichenfolge, zum Beispiel:

string  ClsCommon.str_CardNumbe r = "3456123434561234";

Die Länge dieser Kartennummer kann je nach Anforderung zwischen 16 und 19 Ziffern variieren.

Meine Voraussetzung ist, dass ich die ersten sechs Ziffern und die letzten 4 Ziffern einer Kartennummer anzeigen und die anderen Zeichen dazwischen mit dem Zeichen 'X' maskieren muss.

Ich habe es mit subString versucht und es separat für 16,17,18,19 Stellen implementiert.

Ich teile den String (ClsCommon.str_CardNumber) in 5 Strings auf (str_cardNum1, str_cardNum2, str_cardNum3, str_cardNum4, str_cardNum5 - 4 Ziffern für jeden String ... verbleibende Ziffern für den 5. String)

Alle Zeichenfolgen werden in der ClsCommon-Datei ..__ abgelegt. Darauf basierend habe ich das Folgende implementiert, das perfekt funktioniert:

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);

Für mehrere Längen ist der obige Ansatz nicht nützlich.

Ich möchte eine einfache Methode, bei der die ersten 6 und die letzten 4 Ziffern angezeigt werden und die anderen Ziffern mit X ..__ maskiert werden. Die letzte Zeichenfolge sollte zwischen allen 4 Ziffern ein Leerzeichen enthalten.

16
Kartiikeya

Dies funktioniert mit jeder Kartennummernlänge:

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 ");
21
Yannick Meeus

Probier diese. Einfach und unkompliziert.

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;
    }
}
3
jmvtrinidad

Ich würde so etwas tun (Pseudo-C # - als grobe Idee nehmen, um darauf aufzubauen).

Ungetesteter Code voraus ...

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;
}
3
David Votrubec

Mögliche Implementierung (berücksichtigt verschiedene Formate, z. B. können Zahlen in Gruppen usw. unterteilt werden):

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"));

diese Implementierung maskiert nur die Ziffern und behält das Format bei.

1
Dmitry Bychenko

Eine Methode:

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 += " ";
}
1
Alex K.

Ich bin sicher, dass es einen saubereren Weg gibt, dies zu tun:

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;
}
1
Ted James

Linq speichert Codierungszeilen, kleine Codeausschnitte. 

Ersetzt durch (*) Zeichen über 6 und unter CardPan-Länge minus 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;
});
0

Viele der angegebenen Lösungen analysieren die Eingabe mehrmals. Im Folgenden stelle ich eine Lösung vor, die die Eingabe nur einmal analysiert . Aber ich habe keine Erfahrung mit C #, daher ist die Funktion in Schema geschrieben.

Die Funktion ist in zwei Teile unterteilt:

(1) visit-first-6 parst die ersten sechs Zeichen und verkettet sie mit dem Rest der Berechnung ..__ Wenn visit-first-6 die ersten sechs Zeichen analysiert hat, ruft es visit-rest auf.

(2) visit-rest nutzt die Tatsache aus, dass wir einige Berechnungen verzögern können, bis wir mehr Wissen erworben haben .. In diesem Fall warten wir, ob das Element in der Liste angezeigt werden soll, bis wir wissen, wie viele Zeichen übrig sind .

(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)))

Laufmaske im Petite Chez Scheme-Interpreter

> (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. Ich sah das als eine lustige Übung an und dachte, ich könnte es genauso gut teilen ... Yannick Meeus hat bereits eine leicht verständliche Lösung geliefert. Das dient also nur dem Interessierten.

0
Little Helper

So ersetzen Sie eine bestimmte übereinstimmende Gruppe mit 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
        });
0
WizLiz