master
1/**
2 * Assignment 2, COMP268 Class: CreditCard.java
3 *
4 * @description Provides an implementation of Luhn's algorithm
5 * @author: mo khan Student ID: 3431709
6 * @date Jun 9, 2019
7 * @version 1.0
8 */
9package Q3;
10
11import java.util.*;
12
13public class CreditCard {
14 private int evenSum = 0;
15 private int oddSum = 0;
16 private int sum = 0;
17 private String ccNumber;
18 private String company;
19
20 public CreditCard(String num) {
21 this.ccNumber = num;
22 this.company = this.identifyCompany(num);
23 this.calculateSums(num);
24 }
25
26 /**
27 * Returns the sum of the even digits
28 *
29 * @return the sum of the even digits
30 */
31 public int getEvenSum() {
32 return evenSum;
33 }
34
35 /**
36 * Returns the sum of the odd digits
37 *
38 * @return the sum of the odd digits
39 */
40 public int getOddSum() {
41 return oddSum;
42 }
43
44 /**
45 * Returns the sum of all the digits
46 *
47 * @return the sum of the even and odd digits.
48 */
49 public int getSum() {
50 return sum;
51 }
52
53 /**
54 * Return the credit card number
55 *
56 * @return the credit card number.
57 */
58 public String getCcNumber() {
59 return this.ccNumber;
60 }
61
62 /**
63 * Return the company that issues this credit card number.
64 *
65 * @return the name of the company that owns this credit card number.
66 */
67 public String getCompany() {
68 return this.company;
69 }
70
71 /** @return true if the credit card # is valid, otherwise returns false. */
72 public boolean isValid() {
73 return this.validateCompany()
74 && this.validateLength()
75 && this.validateNumber()
76 && this.validateSums()
77 && this.isDivisibleBy10();
78 }
79
80 /** @return true if the total sum is divisible by 10, otherwise returns false. */
81 public boolean isDivisibleBy10() {
82 return ((this.getSum()) % 10) == 0;
83 }
84
85 /**
86 * Validates the company that the credit card number belongs to.
87 *
88 * @return true if the card belongs to one of the described credit card company, otherwise false.
89 */
90 public boolean validateCompany() {
91 return this.ccNumber.startsWith("4")
92 || this.ccNumber.startsWith("5")
93 || this.ccNumber.startsWith("37")
94 || this.ccNumber.startsWith("6");
95 }
96
97 /** @return true if the length of the card number is valid. */
98 public boolean validateLength() {
99 return this.ccNumber.length() >= 13 && this.ccNumber.length() <= 16;
100 }
101
102 /** @return true if each character in the credit card number is a digit. */
103 public boolean validateNumber() {
104 for (int i = 0; i < this.ccNumber.length(); i++)
105 if (!Character.isDigit(this.ccNumber.charAt(i))) return false;
106 return true;
107 }
108
109 /** @return true if the sum is greater than 0; */
110 public boolean validateSums() {
111 return this.evenSum > 0 && this.oddSum > 0;
112 }
113
114 private String identifyCompany(String number) {
115 if (validateCompany())
116 switch (number.charAt(0)) {
117 case '3':
118 return "American Express";
119 case '4':
120 return "Visa";
121 case '5':
122 return "MasterCard";
123 case '6':
124 return "Discover";
125 }
126
127 return "Unknown";
128 }
129
130 private void calculateSums(String number) {
131 if (!validateNumber()) return;
132
133 String reversed = this.reverseString(number);
134 for (int i = 0; i < reversed.length(); i++) {
135 int digit = this.digitFrom(reversed, i);
136 if (this.isOdd(i + 1)) this.oddSum += digit;
137 else {
138 String value = String.valueOf(digit * 2);
139 for (int j = 0; j < value.length(); j++) this.evenSum += this.digitFrom(value, j);
140 }
141 }
142
143 this.sum = this.oddSum + this.evenSum;
144 }
145
146 private String reverseString(String value) {
147 return new StringBuilder(value).reverse().toString();
148 }
149
150 private boolean isEven(int number) {
151 return number % 2 == 0;
152 }
153
154 private boolean isOdd(int number) {
155 return !this.isEven(number);
156 }
157
158 private int digitFrom(String input, int index) {
159 return Character.getNumericValue(input.charAt(index));
160 }
161
162 /**
163 * The entry point to the console application.
164 *
165 * @param args the argument vector provided to the console application.
166 */
167 public static void main(String[] args) {
168 Scanner in = new Scanner(System.in);
169 System.out.println("Enter credit card #:");
170 CreditCard creditCard = new CreditCard(in.next());
171 if (creditCard.isValid())
172 System.out.println(
173 String.format("%s is offerred by %s", creditCard.getCcNumber(), creditCard.getCompany()));
174 else System.out.println(String.format("%s in invalid", creditCard.getCcNumber()));
175 }
176}