Как я могу динамически маскировать все цифры, кроме последних 4, всегда?

#javascript

#javascript

Вопрос:

Как я могу замаскировать все цифры, которые пользователь вводит динамически?

Сценарий 1: Пользовательский ввод: 1234 5678 9123 4414 Вывод: xxxx xxxx xxxx 4414

Сценарий 2: Пользовательский ввод: 12345678 8234245 Вывод: xxxxxxxx xxx4245

Сценарий 3: Пользовательский ввод: 12 345678911 Вывод: xx xxxxx8911

То, что у меня есть, — это только исправление, и оно статично, как я могу сделать свой код динамичным? чтобы я мог уменьшить свое утверждение if else?

 function hideMask(num) {
    
  var regExp = /[a-zA-Z]/g;
  
  if(regExp.test(num)){
     return null;
  } else {
    if(num.replace(/s/g, '').length == 16){ // 16 digit
    mask = num.substring(num.length - 14).replace(/d/g,"x");
    unmaskCardNumber = num.substring(14, 19);
    return(mask   unmaskCardNumber);
  }else if(num.replace(/s/g, '').length == 18){ //18 digit
    mask = num.substring(0,15).replace(/d/g,"x");
    unmaskCardNumber = num.substring(15, 19);
    return(mask   unmaskCardNumber);
  }else{
    return null;
   }
  }
}
 

Комментарии:

1. Есть an if , затем an else , затем an else if и, наконец, an else . Это не имеет смысла. Вы можете удалить последние два условия.

2. return num.replace(/(.*)(.{4})/, (_, a, b) => 'x'.repeat(a.length) b)

3. @deceze Насколько я понимаю, не требуется, чтобы последние 4 цифры были непрерывными. Сценарий 4: 123456 78 отсутствует.

4. Я надеюсь, что вы преобразуете эти данные на стороне сервера, прежде чем передавать их интерфейсу, потому что это может быть проблемой с точки зрения безопасности. Я имею в виду, если вы преобразуете его во внешнем интерфейсе, я почти уверен, что я мог бы легко получить этот номер карты, быстро взглянув на него как разработчик (без особых навыков взлома …)

Ответ №1:

Вы можете легко добиться результата, используя split , reverse и map

 function mask(s) {
  let count = 0;
  return s
    .split("")
    .reverse()
    .map((n, i) => (!n.match(/d/) ? n : count < 4 ? (count  , n) : "x"))
    .reverse()
    .join("");
}
 
 function mask(s) {
  let count = 0;
  return s
    .split("")
    .reverse()
    .map((n, i) => {
      if (!n.match(/d/)) return n;
      else {
        return count < 4 ? (count  , n) : "x";
      }
    })
    .reverse()
    .join("");
}

console.log(mask("1234 5678 9123 4414"));
console.log(mask("12345678 8234245"));
console.log(mask("12 345678911"));
console.log(mask("12 345678 9 1 1")); //  CORNER CASE 

Вы даже можете пропустить reverse шаг, если используете reduceRight как:

 function mask(s) {
  let count = 0;
  return s
    .split("")
    .reduceRight((acc, n, i) => {
      acc.push(!n.match(/d/) ? n : count < 4 ? (count  , n) : "x");
      return acc;
    }, [])
    .reverse()
    .join("");
}
 
 function mask(s) {
  let count = 0;
  return s
    .split("")
    .reduceRight((acc, n, i) => {
      acc.push(!n.match(/d/) ? n : count < 4 ? (count  , n) : "x");
      return acc;
    }, [])
    .reverse()
    .join("");
}

console.log(mask("1234 5678 9123 4414"));
console.log(mask("12345678 8234245"));
console.log(mask("12 345678 9 1 1")); 

Ответ №2:

Я бы сделал это, используя slice и replace: сначала замените все буквенно-цифровые символы в строке, выделите последние четыре с помощью ‘x’ и добавьте последние четыре из предыдущих:

 function mask(input) {
  return input
    .slice(0, input.length - 4)
    .replace(/([a-zA-Z0-9])/g, 'x')   input.slice(-4)
}
console.log(mask('abcd efgh 1234 5678')) 

Комментарии:

1. Это неправильное решение, потому что оно завершится неудачей, если вы введете ввод как mask("12 345678 9 1 1")

2. @decpk я не могу найти, где «12 345678 9 1 1» является прецедентом, и в этом контексте, что означает «сбой»? Я думаю, что вы устанавливаете критерии, которые не являются частью проблемы / решения.