// ============================================================================ // // Copyright (C) 2006-2016 Talend Inc. - www.talend.com // // This source code is available under agreement available at // %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt // // You should have received a copy of the agreement // along with this program; if not, write to Talend SA // 9 rue Pages 92150 Suresnes, France // // ============================================================================ package org.talend.dataquality.datamasking.functions; /** * created by jgonzalez on 24 juin 2015 . This class holds all the function required to generate a credit card number. * */ public abstract class GenerateCreditCard<T2> extends Function<T2> { private static final long serialVersionUID = -5998632284990879388L; private static final String DIGITS = "0123456789"; //$NON-NLS-1$ /** * The enum stores the different types of Credit Card that can be generated. * */ public enum CreditCardType { AMERICAN_EXPRESS, MASTER_CARD, VISA } /** * This function tests a credit card number if valid. * * @param number represents the credit card number to be testes. * @return a boolean : true if the number is valid, false if not */ public static boolean luhnTest(StringBuilder number) { int s1 = 0, s2 = 0; String reverse = new StringBuffer(number).reverse().toString(); for (int i = 0; i < reverse.length(); i++) { int digit = Character.digit(reverse.charAt(i), 10); if (i % 2 == 0) { s1 += digit; } else { s2 += 2 * digit; if (digit >= 5) { s2 -= 9; } } } return (s1 + s2) % 10 == 0; } /** * This function creates a new Credit Card Number. * * @param cct represents the credit card type to generate. * @param valueIn represents the credit card number sent in input. * @return a new number with the same length and prefix as @param valueIn. */ public Long generateCreditCardFormat(CreditCardType cct, Long valueIn) { StringBuilder res = new StringBuilder(""); //$NON-NLS-1$ int len = valueIn.toString().length(); String prefix = ""; //$NON-NLS-1$ if (cct == CreditCardType.VISA) { prefix = valueIn.toString().substring(0, 1); } else { prefix = valueIn.toString().substring(0, 2); } res.append(prefix); for (int i = prefix.length(); i < len; ++i) { int tmp = rnd.nextInt(10); res.append(tmp); } for (int i = 0; i < 10; ++i) { res.setCharAt(res.length() - 1, DIGITS.charAt(i)); if (luhnTest(res)) { break; } } Long result = Long.parseLong(res.toString()); return result; } public StringBuilder generateCreditCardFormat(CreditCardType cct, String str) { StringBuilder res = new StringBuilder(""); //$NON-NLS-1$ String prefix = ""; //$NON-NLS-1$ if (cct == CreditCardType.VISA) { prefix = str.substring(0, 1); } else { prefix = str.substring(0, 2); } res.append(prefix); for (int i = prefix.length(); i < str.length(); ++i) { int tmp = rnd.nextInt(10); res.append(tmp); } for (int i = 0; i < 10; ++i) { res.setCharAt(res.length() - 1, DIGITS.charAt(i)); if (luhnTest(res)) { break; } } return res; } /** * This function creates a new Credit Card Number. * * @param cct represents the credit card type to generate. * @return a new credit card number. */ public Long generateCreditCard(CreditCardType cct) { int len = 0; String init = ""; //$NON-NLS-1$ StringBuilder res = new StringBuilder(""); //$NON-NLS-1$ switch (cct) { case VISA: init = "4"; //$NON-NLS-1$ len = 15; break; case MASTER_CARD: init = "53"; //$NON-NLS-1$ len = 14; break; case AMERICAN_EXPRESS: init = "34"; //$NON-NLS-1$ len = 13; break; default: return null; } res.append(init); for (int i = 0; i < len; ++i) { int tmp = rnd.nextInt(10); res.append(tmp); } for (int i = 0; i < 10; ++i) { res.setCharAt(res.length() - 1, DIGITS.charAt(i)); if (luhnTest(res)) { break; } } Long result = Long.parseLong(res.toString()); return result; } /** * This function checks if the input number is one of the known type. (see the enum) * * @param ccn The credit card number sent in input. * @return Either null if the type is unknown, or the type of the card if known. */ public CreditCardType getCreditCardType(Long ccn) { StringBuilder number = new StringBuilder(ccn.toString()); if (number.length() == 15) { if ("34".equals(number.substring(0, 2)) || ("37").equals(number.substring(0, 2))) { //$NON-NLS-1$ //$NON-NLS-2$ return CreditCardType.AMERICAN_EXPRESS; } } else if (number.length() == 16 || number.length() == 13) { Integer iin = Integer.parseInt(number.substring(0, 2)); if (iin >= 51 && iin <= 56 && number.length() == 16) { return CreditCardType.MASTER_CARD; } else { Integer iinShort = iin / 10; if (iinShort == 4) { return CreditCardType.VISA; } } } return null; } /** * The function is called if the input is null or if its type is unkwown. * * @return One of the types from the enum, chosen randomly. */ public CreditCardType chooseCreditCardType() { int choice = rnd.nextInt(3); if (choice == 0) { return CreditCardType.AMERICAN_EXPRESS; } else if (choice == 1) { return CreditCardType.MASTER_CARD; } else { return CreditCardType.VISA; } } }