Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 屏蔽字符串的前6位和后4位以外的所有数字(长度不同)_C#_.net_String_Substring_Masking - Fatal编程技术网

C# 屏蔽字符串的前6位和后4位以外的所有数字(长度不同)

C# 屏蔽字符串的前6位和后4位以外的所有数字(长度不同),c#,.net,string,substring,masking,C#,.net,String,Substring,Masking,我将卡号作为字符串,例如: string ClsCommon.str_CardNumbe r = "3456123434561234"; 此卡号的长度可以从16位到19位不等,具体取决于要求 我的要求是,我必须显示卡号的前六位和后四位数字,并用字符“X”屏蔽中间的其他字符 我尝试过使用子字符串,并分别实现了16、17、18、19位数字 我将字符串(ClsCommon.str_CardNumber)拆分为5个字符串(str_cardNum1、str_cardNum2、str_cardNum3、

我将卡号作为字符串,例如:

string  ClsCommon.str_CardNumbe r = "3456123434561234";
此卡号的长度可以从16位到19位不等,具体取决于要求

我的要求是,我必须显示卡号的前六位和后四位数字,并用字符“X”屏蔽中间的其他字符

我尝试过使用子字符串,并分别实现了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位数字之间有一个空格。

我相信有一种更干净的方法可以做到这一点:

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

我会做这样的事情(伪C#-作为一个粗略的想法来构建)

未经测试的代码


这将适用于任何卡号长度:

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 ");
可能的实施方式(acccepts varios格式,例如数字可分为组等):

私有静态字符串掩码编号(字符串源){
StringBuilder sb=新的StringBuilder(来源);
常数int skipLeft=6;
常数int skipRight=4;
int left=-1;
for(int i=0,c=0;iskipLeft){
左=i;
打破
}
}
}
for(int i=sb.Length-1,c=0;i>=left;--i)
如果(字符为数字(sb[i])){
c+=1;
如果(c>skipRight)
sb[i]=“X”;
}
使某人返回字符串();
}
//测验
//3456-12XX-XXXX-1234
Console.Write(MaskedNumber(“3456-1234-3456-1234”);
//3456123XXXXX1234
Console.Write(MaskedNumber(“34561234613461234”);
此实现仅屏蔽数字并保留格式。

一种方法:

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 += " ";
}
字符串掩码=null;
对于(int i=0;i5&&i
使用正则表达式替换特定的匹配组如何:

        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) 访问rest利用了这样一个事实,即我们可以延迟一些计算,直到我们获得更多的知识。 在本例中,我们等待确定是否应显示列表中的元素,直到知道还剩多少个字符

(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)))
注意。我认为这是一个有趣的练习,我想我还是分享一下吧。 Yannick Meeus已经提供了一个易于理解的解决方案。
所以,这只服务于感兴趣的人。

试试这个。简单明了

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

Linq保存编码行,小代码段

替换为大于6的(*)字符和小于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;
});
var CardPan=“1234567890123456”; var maskedPan=CardPan.Aggregate(string.Empty,(value,next)=> { 如果(value.Length>=6&&value.Length我认为你的想法是相反的——前6个和后4个字符需要显示,其他所有字符都需要隐藏。在阅读了@Yannicks answer之后,我同意他的方法。我不知道您可以创建这样的字符串:)如果初始数字带有空格(或其他分隔符),例如
var cardname=“3456 1234 3456 1234”最终结果将是不正确的一个
3456 1x XXXX XXX1 234
;另一个问题是,我们通常希望保留给定的格式(例如,
3456-1234-3456-1234
)和掩码数字(
3456-12XX-XXXX-1234
)。@DmitryBychenko同意,但这超出了问题的范围。我们倾向于完全删除所有非数字字符,通过Luhn和Bin检查验证卡号,然后带着面具将其吐出来,有时格式化。我同意yannick的回答。去掉所有特殊字符,屏蔽数字,然后用破折号或空格重新格式化数字。你只是让生活变得困难,试图在整个过程中保留格式。它应该是
蒙面+=(i>=6…
(保留6个符号,而不是7)实际上应该是5!我更喜欢粗体而不是大写
> (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)
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;
    }
}
var CardPan = "1234567890123456";
var maskedPan = CardPan.Aggregate(string.Empty, (value, next) =>
{
    if (value.Length >= 6 && value.Length < CardPan.Length - 4)
    {
        next = '*';
    }
    return value + next;
});