掩盖java中的信用卡号码

jim*_*ner 8 java masking apache-commons-lang

我试图使用字符'X'掩盖信用卡号码字符串中的字符.我写了两个函数如下.第二个函数使用commons.lang.StringUtils类.我试图找到两种情况下的时间

public static String maskCCNumber(String ccnum){
        long starttime = System.currentTimeMillis();
        int total = ccnum.length();
        int startlen=4,endlen = 4;
        int masklen = total-(startlen + endlen) ;
        StringBuffer maskedbuf = new StringBuffer(ccnum.substring(0,startlen));
        for(int i=0;i<masklen;i++) {
            maskedbuf.append('X');
        }
        maskedbuf.append(ccnum.substring(startlen+masklen, total));
        String masked = maskedbuf.toString();
        long endtime = System.currentTimeMillis();
        System.out.println("maskCCNumber:="+masked+" of :"+masked.length()+" size");
        System.out.println("using StringBuffer="+ (endtime-starttime)+" millis");
        return masked;
    }

    public static String maskCCNumberCommons(String ccnum){
        long starttime = System.currentTimeMillis();
        int total = ccnum.length();
        int startlen=4,endlen = 4;
        int masklen = total-(startlen + endlen) ;
        String start = ccnum.substring(0,startlen);
        String end = ccnum.substring(startlen+masklen, total);
        String padded = StringUtils.rightPad(start, startlen+masklen,'X'); 
        String masked = padded.concat(end);
        long endtime = System.currentTimeMillis();
        System.out.println("maskCCNumber:="+masked+" of :"+masked.length()+" size");
        System.out.println("using Stringutils="+(endtime-starttime)+" millis");
        return masked;
    }

public static void ccNumberMaskingDemo() {
   String mcard1="5555555555554444";
   maskCCNumber(mcard1);
   maskCCNumberCommons(mcard1);
}
Run Code Online (Sandbox Code Playgroud)

当我跑这个时,我得到了这个结果

maskCCNumber:=5555XXXXXXXX4444 of :16 size
using StringBuffer=0 millis
maskCCNumber:=5555XXXXXXXX4444 of :16 size
using Stringutils=25 millis
Run Code Online (Sandbox Code Playgroud)

我无法理解为什么commons.StringUtils比第一个函数中的for循环+ StringBuffer花费更多的时间.显然我正在使用api,错误的方式..

在这种情况下,有人可以建议如何正确使用此api吗?

Aym*_*man 19

干得好.清洁和可重复使用:

/**
 * Applies the specified mask to the card number.
 *
 * @param cardNumber The card number in plain format
 * @param mask The number mask pattern. Use # to include a digit from the
 * card number at that position, use x to skip the digit at that position
 *
 * @return The masked card number
 */
public static String maskCardNumber(String cardNumber, String mask) {

    // format the number
    int index = 0;
    StringBuilder maskedNumber = new StringBuilder();
    for (int i = 0; i < mask.length(); i++) {
        char c = mask.charAt(i);
        if (c == '#') {
            maskedNumber.append(cardNumber.charAt(index));
            index++;
        } else if (c == 'x') {
            maskedNumber.append(c);
            index++;
        } else {
            maskedNumber.append(c);
        }
    }

    // return the masked number
    return maskedNumber.toString();
}
Run Code Online (Sandbox Code Playgroud)

示例电话:

System.out.println(maskCardNumber("1234123412341234", "xxxx-xxxx-xxxx-####"));
> xxxx-xxxx-xxxx-1234

System.out.println(maskCardNumber("1234123412341234", "##xx-xxxx-xxxx-xx##"));
> 12xx-xxxx-xxxx-xx34
Run Code Online (Sandbox Code Playgroud)

祝好运.


Jef*_*rey 9

使用Apache StringUtils ......

String ccNumber = "123232323767"; 

StringUtils.overlay(ccNumber, StringUtils.repeat("X", ccNumber.length()-4), 0, ccNumber.length()-4);
Run Code Online (Sandbox Code Playgroud)


Mic*_*l-7 8

这是一个基于StringUtils的略微更清晰的实现,但我不确定它与您的实现相比会如何执行.无论如何,"过早优化"评论仍然非常有效.

    public static String maskNumber(final String creditCardNumber) {
    final String s = creditCardNumber.replaceAll("\\D", "");

    final int start = 4;
    final int end = s.length() - 4;
    final String overlay = StringUtils.repeat(MASK_CHAR, end - start);

    return StringUtils.overlay(s, overlay, start, end);
}
Run Code Online (Sandbox Code Playgroud)


Fra*_*ank 6

首先,如果您对这样一个短时间运行的代码进行测量,由于您的CPU /库/任何提供的最小时序分辨率,您通常无法得到准确的结果(这意味着您通常会看到0ms或相同的小值,并且过度).

其次,更重要的是,不要优化这个!"过早的优化是所有邪恶的根源",并且在你只有几毫秒的情况下,你想要优化努力被彻底浪费.在你甚至应该远程考虑优化这种简单的掩码方法之前,你必须掩盖数以百万计的信用卡.


pad*_*ist 6

我知道这不是答案,但您可以使用正则表达式并一步解决这个问题

String replaced = originalCreditCardNo.replaceAll("\\b(\\d{4})(\\d{8})(\\d{4})", "$1XXXXXXXX$3");
Run Code Online (Sandbox Code Playgroud)

解释:

  • \ b边界有助于检查,我们的数字(也有其他方法可以做到这一点,但在这里,这是不行的)开始。
  • (\d{4})将四位数字捕获到第 1 组和第 3 组
  • (\d{8})将八位数字捕获到组 2
  • 在替换中,$1$3包含第 1 组和第 3 组匹配的内容