Skip to content

Commit

Permalink
feat: Add CreditcardValidator and Utils classes to multiform_validato…
Browse files Browse the repository at this point in the history
…r package
  • Loading branch information
gabriel-logan committed Jul 7, 2024
1 parent 86bad91 commit fc9c213
Show file tree
Hide file tree
Showing 8 changed files with 397 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package io.github.gabriel_logan.multiform_validator;

import java.util.Arrays;

public class CnpjValidator {
private CnpjValidator() {
throw new IllegalStateException("Utility class");
}

private static int calculateFirstVerifier(int[] cnpjBase) {
final int[] weight = {5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2};
int sum = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public class CpfValidator {
private CpfValidator() {
throw new IllegalStateException("Utility class");
}

public static boolean cpfIsValid(String cpf) {
if (cpf == null) {
throw new NullPointerException("CPF cannot be null or empty");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package io.github.gabriel_logan.multiform_validator;

public class CreditCardValidator {
private static final String INPUT_VALUE_CANNOT_BE_EMPTY = "Input value cannot be empty.";

private CreditCardValidator() {
throw new IllegalStateException("Utility class");
}

public static boolean isCreditCardValid(String creditCard) {
if (creditCard == null || creditCard.isEmpty()) {
throw new IllegalArgumentException(INPUT_VALUE_CANNOT_BE_EMPTY);
}

final String creditCardString = creditCard.replaceAll("\\D", "");

if (creditCardString.length() < 13 || creditCardString.length() > 19) {
return false;
}

int sum = 0;
boolean alternate = false;

for (int i = creditCardString.length() - 1; i >= 0; i--) {
int n = Integer.parseInt(creditCardString.substring(i, i + 1));

if (alternate) {
n *= 2;

if (n > 9) {
n = (n % 10) + 1;
}
}

sum += n;
alternate = !alternate;
}

return sum % 10 == 0;
}

public static String identifyFlagCard(String cardNumber) {
if (cardNumber == null || cardNumber.isEmpty()) {
throw new IllegalArgumentException("The input should be a string.");
}

String[][] flags = {
{"Visa", "^4[0-9]{12}(?:[0-9]{3})?$"},
{"Mastercard", "^5[1-5][0-9]{14}$"},
{"American Express", "^3[47][0-9]{13}$"},
{"Discover", "^6(?:011|5[0-9]{2})[0-9]{12}$"},
{"JCB", "^(?:2131|1800|35[0-9]{3})[0-9]{11}$"},
{"Diners Club", "^3(?:0[0-5]|[68][0-9])[0-9]{11}$"},
{"Maestro", "^(?:5[0678][0-9]{2}|6304|6390|67[0-9]{2})[0-9]{12,15}$"},
{"UnionPay", "^(62|88)[0-9]{14,17}$"},
{"Elo", "^63[789][0-9]{13}$"},
{"Hipercard", "^(3841[0-9]{12}|60[0-9]{14})$"}
};

for (String[] flag : flags) {
if (cardNumber.matches(flag[1])) {
return flag[0];
}
}

return "Unknown";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package io.github.gabriel_logan.multiform_validator;

import java.util.*;
import java.util.regex.*;

public class Utils {
private Utils() {
throw new IllegalStateException("Utility class");
}

private static final List<String> CleanAfterDefaultDomain = Arrays.asList(
".br", ".io", ".pt", ".us", ".org", ".com"
);

public static class OptionsParams {
public Boolean multiple = false;
public Object cleanDomain = false;
public Boolean repeatEmail = false;
}

private static final OptionsParams defaultOptionsParams = new OptionsParams();

public static Object getOnlyEmail(String text, OptionsParams options) {
if (options == null) {
options = defaultOptionsParams;
}

Boolean multiple = options.multiple != null ? options.multiple : defaultOptionsParams.multiple;
Object cleanDomain = options.cleanDomain != null ? options.cleanDomain : defaultOptionsParams.cleanDomain;
Boolean repeatEmail = options.repeatEmail != null ? options.repeatEmail : defaultOptionsParams.repeatEmail;

Pattern emailPattern = Pattern.compile("[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}");
Matcher matcher = emailPattern.matcher(text);

List<String> matches = new ArrayList<>();
while (matcher.find()) {
matches.add(matcher.group());
}

if (matches.isEmpty()) {
return "No email found";
}

if (cleanDomain != null && !cleanDomain.equals(false)) {
List<String> domainsToClean = cleanDomain instanceof List ? (List<String>) cleanDomain : CleanAfterDefaultDomain;

List<String> cleanedEmails = new ArrayList<>();
for (String email : matches) {
for (String domain : domainsToClean) {
int index = email.lastIndexOf(domain);
if (index != -1) {
email = email.substring(0, index + domain.length());
break;
}
}

for (String domain : domainsToClean) {
int index = email.indexOf(domain);
if (index != -1) {
email = email.substring(0, index + domain.length());
break;
}
}
cleanedEmails.add(email);
}

if (Boolean.FALSE.equals(repeatEmail)) {
Set<String> uniqueEmails = new LinkedHashSet<>(cleanedEmails);
return Boolean.TRUE.equals(multiple) ? new ArrayList<>(uniqueEmails) : uniqueEmails.iterator().next();
}

return Boolean.TRUE.equals(multiple) ? cleanedEmails : cleanedEmails.get(0);
}

if (Boolean.FALSE.equals(repeatEmail)) {
Set<String> uniqueEmails = new LinkedHashSet<>(matches);
return Boolean.TRUE.equals(multiple) ? new ArrayList<>(uniqueEmails) : uniqueEmails.iterator().next();
}

return Boolean.TRUE.equals(multiple) ? matches : matches.get(0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

public class Validator {
private static final String INPUT_VALUE_CANNOT_BE_EMPTY = "Input value cannot be empty.";

private Validator() {
throw new IllegalStateException("Utility class");
}
Expand All @@ -19,7 +20,7 @@ public static boolean isBase64(String value) {
throw new IllegalArgumentException(INPUT_VALUE_CANNOT_BE_EMPTY);
}

return value.matches("^[a-zA-Z0-9+/]*={0,2}$");
return value.matches("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$");
}

public static boolean isCEP(String cep) {
Expand All @@ -42,6 +43,57 @@ public static boolean isCEP(String cep) {
return true;
}

public static boolean isDate(String date) {
if (date == null || date.isEmpty()) {
throw new IllegalArgumentException(INPUT_VALUE_CANNOT_BE_EMPTY);
}

return date.matches("^\\d{4}-\\d{2}-\\d{2}$");
}


public static boolean isDecimal(String value) {
if (value == null || value.isEmpty()) {
throw new IllegalArgumentException(INPUT_VALUE_CANNOT_BE_EMPTY);
}

try {
double parsedValue = Double.parseDouble(value);

return parsedValue % 1 != 0;
} catch (NumberFormatException e) {
return false;
}
}

public static boolean isMACAddress(String macAddress) {
if (macAddress == null || macAddress.isEmpty()) {
throw new IllegalArgumentException(INPUT_VALUE_CANNOT_BE_EMPTY);
}

return macAddress.matches("^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$");
}

public static boolean isMD5(String value) {
if (value == null || value.isEmpty()) {
throw new IllegalArgumentException(INPUT_VALUE_CANNOT_BE_EMPTY);
}

return value.matches("^[a-fA-F0-9]{32}$");
}

public static boolean isNumber(String value) {
if (value == null || value.isEmpty()) {
throw new IllegalArgumentException(INPUT_VALUE_CANNOT_BE_EMPTY);
}

return value.matches("^-?\\d+$");
}

public static boolean isPort(int port) {
return port >= 0 && port <= 65535;
}

public static boolean isPort(String port) {
if (port == null || port.isEmpty()) {
throw new IllegalArgumentException(INPUT_VALUE_CANNOT_BE_EMPTY);
Expand All @@ -54,4 +106,46 @@ public static boolean isPort(String port) {
return false;
}
}

public static boolean isPostalCode(String postalCode) {
if (postalCode == null || postalCode.isEmpty()) {
throw new IllegalArgumentException("Input value must be a string.");
}

final String usZipCodeRegex = "^\\d{5}(-\\d{4})?$";
final String canadaPostalCodeRegex = "^[A-Za-z]\\d[A-Za-z] \\d[A-Za-z]\\d$";
final String ukPostalCodeRegex = "^[A-Za-z]{1,2}\\d[A-Za-z\\d]? \\d[A-Za-z]{2}$";
final String francePostalCodeRegex = "^\\d{5}$";
final String netherlandsPostalCodeRegex = "^\\d{4}$";
final String japanPostalCodeRegex = "^\\d{3}-\\d{4}$";
final String spainPostalCodeRegex = "^\\d{5}$";
final String southAfricaPostalCodeRegex = "^\\d{4}$";
final String germanyPostalCodeRegex = "^\\d{5}$";
final String switzerlandPostalCodeRegex = "^\\d{4}$";
final String brazilPostalCodeRegex = "^\\d{5}-\\d{3}$";
final String italyPostalCodeRegex = "^\\d{5}$";
final String usZipCodeOnlyRegex = "^\\d{5}$";

return postalCode.matches(usZipCodeRegex) ||
postalCode.matches(canadaPostalCodeRegex) ||
postalCode.matches(ukPostalCodeRegex) ||
postalCode.matches(francePostalCodeRegex) ||
postalCode.matches(netherlandsPostalCodeRegex) ||
postalCode.matches(japanPostalCodeRegex) ||
postalCode.matches(spainPostalCodeRegex) ||
postalCode.matches(southAfricaPostalCodeRegex) ||
postalCode.matches(germanyPostalCodeRegex) ||
postalCode.matches(switzerlandPostalCodeRegex) ||
postalCode.matches(brazilPostalCodeRegex) ||
postalCode.matches(italyPostalCodeRegex) ||
postalCode.matches(usZipCodeOnlyRegex);
}

public static boolean isTime(String time) {
if (time == null || time.isEmpty()) {
throw new IllegalArgumentException(INPUT_VALUE_CANNOT_BE_EMPTY);
}

return time.matches("^(?:2[0-3]|1\\d|0?[0-9]):[0-5]\\d(?::[0-5]\\d)?(?: [APap][Mm])?$");
}
}
34 changes: 34 additions & 0 deletions packages/java/src/test/java/CreditCardValidatorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import org.junit.jupiter.api.Test;

import static io.github.gabriel_logan.multiform_validator.CreditCardValidator.identifyFlagCard;
import static io.github.gabriel_logan.multiform_validator.CreditCardValidator.isCreditCardValid;
import static org.junit.jupiter.api.Assertions.*;

class CreditCardValidatorTest {
@Test
void testIsCreditCardValid() {
assertTrue(isCreditCardValid("4111111111111111"));
assertTrue(isCreditCardValid("5500000000000004"));
assertFalse(isCreditCardValid("1234567890123456"));
assertFalse(isCreditCardValid("12345678901234567890"));
assertThrows(IllegalArgumentException.class, () -> isCreditCardValid(null));
assertThrows(IllegalArgumentException.class, () -> isCreditCardValid(""));
}

@Test
void testIdentifyFlagCard() {
assertEquals("Visa", identifyFlagCard("4111111111111111"));
assertEquals("Mastercard", identifyFlagCard("5555555555554444"));
assertEquals("American Express", identifyFlagCard("378282246310005"));
assertEquals("Discover", identifyFlagCard("6011111111111117"));
assertEquals("JCB", identifyFlagCard("3530111333300000"));
assertEquals("Diners Club", identifyFlagCard("30569309025904"));
assertEquals("Maestro", identifyFlagCard("6304000000000000"));
assertEquals("UnionPay", identifyFlagCard("6200000000000005"));
assertEquals("Elo", identifyFlagCard("6370950000000005"));
assertEquals("Hipercard", identifyFlagCard("3841000000000000"));
assertEquals("Unknown", identifyFlagCard("1234567890123456"));
assertThrows(IllegalArgumentException.class, () -> identifyFlagCard(null));
assertThrows(IllegalArgumentException.class, () -> identifyFlagCard(""));
}
}
50 changes: 50 additions & 0 deletions packages/java/src/test/java/UtilsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import io.github.gabriel_logan.multiform_validator.Utils;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

import static org.junit.jupiter.api.Assertions.*;

class UtilsTest {
@Test
void testGetOnlyEmail() {
// Test with no email found
assertEquals("No email found", Utils.getOnlyEmail("This is a sample text", null));

// Test with single email
assertEquals("test@example.com", Utils.getOnlyEmail("This is a sample text with email test@example.com", null));

// Test with multiple emails
Utils.OptionsParams options1 = new Utils.OptionsParams();
options1.multiple = true;
assertEquals(
new ArrayList<>(Arrays.asList("test1@example.com", "test2@example.com")),
Utils.getOnlyEmail("This is a sample text with emails test1@example.com and test2@example.com", options1)
);

// Test with cleaning domain
Utils.OptionsParams options = new Utils.OptionsParams();
options.cleanDomain = true;
assertEquals("test@example.com.br", Utils.getOnlyEmail("test@example.com.br", options));

// Test with cleaning domain and multiple emails
options.multiple = true;
assertEquals(
new ArrayList<>(Arrays.asList("test1@example.com.br", "test2@example.com.br")),
Utils.getOnlyEmail("test1@example.com.br and test2@example.com.br", options)
);

// Test with repeatEmail set to false
options.repeatEmail = false;
assertEquals(Collections.singletonList("test@example.com"), Utils.getOnlyEmail("test@example.com and test@example.com", options));

// Test with repeatEmail set to false and multiple emails
options.multiple = true;
assertEquals(
new ArrayList<>(Collections.singletonList("test@example.com")),
Utils.getOnlyEmail("test@example.com and test@example.com", options)
);
}
}
Loading

0 comments on commit fc9c213

Please sign in to comment.