Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#17 Add credit_card_luhn generater #26

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 51 additions & 2 deletions src/payment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,38 @@ pub fn credit_card_number() -> String {
}

pub fn credit_card_luhn_number() -> String {
// @TODO
return String::from("");
let mut cc_str = credit_card_number();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think writing the algorithm of luhn generation? I think it's much nicer solution to write the function on the way that it generates a proper luhn number sequence for the first run.

Resources:

Let me know your thoughts. :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I absolutely think that is the right way to go. I only did it this way because I was trying to stay close to the go fakeit library, but if you're cool diverging a bit, then generating the last digit is much better and potentially future-usable than guess-and-check.

Will change.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'm not a big fan of how gofakeit solves it, so that would be awesome if you could have change it. Thank you.

let mut cc_num = cc_str
.parse::<u64>()
.expect("generated bad credit card number");

// iterate until you hit a cc number that passes the luhn check
while !is_luhn(&cc_str) {
cc_num += 1;
cc_str = cc_num.to_string();
}

cc_str
}

// is_luhn check is used for checking if credit card is a valid luhn card
fn is_luhn(cc_str: &String) -> bool {
let parity = cc_str.len() & 1;
let mut sum = 0;
for (i, ch) in cc_str.chars().enumerate() {
let Some(digit) = ch.to_digit(10) else {
return false;
};

if i & 1 != parity {
sum += digit;
} else if digit > 4 {
sum += digit * 2 - 9;
} else {
sum += digit * 2;
}
}
sum % 10 == 0
}

pub fn credit_card_exp() -> String {
Expand Down Expand Up @@ -69,6 +99,25 @@ mod tests {
});
}

#[test]
fn is_luhn() {
exec_mes("payment::is_luhn", || {
(if payment::is_luhn(&"4716685826369360".to_string()) {
"luhn"
} else {
""
})
.to_string()
});
}

#[test]
fn credit_card_luhn_number() {
exec_mes("payment::credit_card_luhn_number", || {
payment::credit_card_luhn_number()
});
}

#[test]
fn credit_card_exp() {
exec_mes("payment::credit_card_exp", || payment::credit_card_exp());
Expand Down