CreditCardNumber.java 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package io.card.payment;
  2. /* CreditCardNumber.java
  3. * See the file "LICENSE.md" for the full license governing this code.
  4. */
  5. import java.text.CharacterIterator;
  6. import java.text.ParseException;
  7. import java.text.SimpleDateFormat;
  8. import java.text.StringCharacterIterator;
  9. import java.util.Calendar;
  10. import java.util.Date;
  11. class CreditCardNumber {
  12. /**
  13. * Checks if the given string represents a number that passes the Luhn Checksum which all valid
  14. * CCs will pass.
  15. *
  16. * @param number
  17. * @return true if the number does pass the checksum, else false
  18. */
  19. public static boolean passesLuhnChecksum(String number) {
  20. int even = 0;
  21. int sum = 0;
  22. final int[][] sums = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, { 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 } };
  23. CharacterIterator iter = new StringCharacterIterator(number);
  24. for (char c = iter.last(); c != CharacterIterator.DONE; c = iter.previous()) {
  25. if (!Character.isDigit(c)) {
  26. return false;
  27. }
  28. int cInt = c - '0';
  29. sum += sums[even++ & 0x1][cInt];
  30. }
  31. return sum % 10 == 0;
  32. }
  33. /**
  34. * @param numStr the String of numbers to view
  35. * @return null if numStr is not formattable by the known formatting rules
  36. */
  37. public static String formatString(String numStr) {
  38. return formatString(numStr, true, null);
  39. }
  40. public static String formatString(String numStr, boolean filterDigits, CardType type) {
  41. String digits;
  42. if (filterDigits) {
  43. digits = StringHelper.getDigitsOnlyString(numStr);
  44. } else {
  45. digits = numStr;
  46. }
  47. if (type == null) {
  48. type = CardType.fromCardNumber(digits);
  49. }
  50. int numLen = type.numberLength();
  51. if (digits.length() == numLen) {
  52. if (numLen == 16) {
  53. return formatSixteenString(digits);
  54. } else if (numLen == 15) {
  55. return formatFifteenString(digits);
  56. }
  57. }
  58. return numStr; // at the worst case, pass back what was given
  59. }
  60. private static String formatFifteenString(String digits) {
  61. StringBuilder sb = new StringBuilder();
  62. for (int i = 0; i < 15; i++) {
  63. if (i == 4 || i == 10) {
  64. sb.append(' ');
  65. }
  66. sb.append(digits.charAt(i));
  67. }
  68. return sb.toString();
  69. }
  70. private static String formatSixteenString(String digits) {
  71. StringBuilder sb = new StringBuilder();
  72. {
  73. for (int i = 0; i < 16; i++) {
  74. if (i != 0 && i % 4 == 0) {
  75. sb.append(' ');// insert every 4th char, except at end
  76. }
  77. sb.append(digits.charAt(i));
  78. }
  79. }
  80. return sb.toString();
  81. }
  82. public static boolean isDateValid(int expiryMonth, int expiryYear) {
  83. if (expiryMonth < 1 || 12 < expiryMonth) {
  84. return false;
  85. }
  86. Calendar now = Calendar.getInstance();
  87. int thisYear = now.get(Calendar.YEAR);
  88. int thisMonth = now.get(Calendar.MONTH) + 1;
  89. if (expiryYear < thisYear) {
  90. return false;
  91. }
  92. if (expiryYear == thisYear && expiryMonth < thisMonth) {
  93. return false;
  94. }
  95. if (expiryYear > thisYear + CreditCard.EXPIRY_MAX_FUTURE_YEARS) {
  96. return false;
  97. }
  98. return true;
  99. }
  100. public static boolean isDateValid(String dateString) {
  101. String digitsOnly = StringHelper.getDigitsOnlyString(dateString);
  102. SimpleDateFormat validDate = getDateFormatForLength(digitsOnly.length());
  103. if (validDate == null) {
  104. return false;
  105. }
  106. try {
  107. validDate.setLenient(false);
  108. Date enteredDate = validDate.parse(digitsOnly);
  109. return isDateValid(enteredDate.getMonth() + 1, enteredDate.getYear() + 1900);
  110. } catch (ParseException pe) {
  111. return false;
  112. }
  113. }
  114. public static SimpleDateFormat getDateFormatForLength(int len) {
  115. if (len == 4) {
  116. return new SimpleDateFormat("MMyy");
  117. } else if (len == 6) {
  118. return new SimpleDateFormat("MMyyyy");
  119. } else {
  120. return null;
  121. }
  122. }
  123. public static Date getDateForString(String dateString) {
  124. String digitsOnly = StringHelper.getDigitsOnlyString(dateString);
  125. SimpleDateFormat validDate = getDateFormatForLength(digitsOnly.length());
  126. if (validDate != null) {
  127. try {
  128. validDate.setLenient(false);
  129. Date date = validDate.parse(digitsOnly);
  130. return date;
  131. } catch (ParseException pe) {
  132. return null;
  133. }
  134. }
  135. return null;
  136. }
  137. }