Luhn

1. Readme

Luhn

给定一个数,判定它是否有效 Luhn 公式.

Luhn 算法,也称为“模 10”算法

这个Luhn 算法是一个简单的校验和公式,用于验证各种身份号码,如信用卡号码和加拿大社会保险号码.

任务是检查给定字符串是否有效.

验证一个数

长度为 1 或更小的字符串无效。在输入中允许使用空格,但在检查前,应清除空格。所有其他非数字字符都是不允许的.

例子 1:有效信用卡号码

4539 1488 0343 6467

LuHN 算法的第一步是,从右边开始每第二个数字加倍。我们要加倍的位

4_3_ 1_8_ 0_4_ 6_6_

如果加倍的数字值导致大于 9 的数字,则将此值减去 9。我们加倍的结果:

8569 2478 0383 3437

1_8_ => 2_7_ , 8*2 - 9 = 7

然后把所有数字加起来:

8+5+6+9+2+4+7+8+0+3+8+3+3+4+3+7 = 80

如果总和可被 10 整除,则数字是有效的.这个号码是有效的!

例子 2:信用卡号码无效

8273 1232 7352 0569

把每第二个数字加倍,从右边开始

7253 2262 5312 0539

合计数字

7+2+5+3+2+2+6+2+5+3+1+2+0+5+3+9 = 57

57 不能被 10 整除,所以这个数字是无效的.

资源

维基百科上的 LuHn 算法http://en.wikipedia.org/wiki/Luhn_algorithm

2. 开始你的表演

/// Check a Luhn checksum.
pub fn is_valid(code: &str) -> bool {
   unimplemented!("Is the Luhn checksum for {} valid?", code);
}

3. 测试代码查看


# #![allow(unused_variables)]
#fn main() {
#[test]
fn single_digit_string_is_invalid() {
   assert!(!is_valid("1"));
}

#[test]
//#[ignore]
fn single_zero_string_is_invalid() {
   assert!(!is_valid("0"));
}

#[test]
//#[ignore]
fn simple_valid_sin() {
   assert!(is_valid(" 5 9 "));
}

#[test]
//#[ignore]
fn valid_canadian_sin_is_valid() {
   assert!(is_valid("046 454 286"));
}

#[test]
//#[ignore]
fn invalid_canadian_sin_is_invalid() {
   assert!(!is_valid("046 454 287"));
}

#[test]
//#[ignore]
fn invalid_credit_card_is_invalid() {
   assert!(!is_valid("8273 1232 7352 0569"));
}

#[test]
//#[ignore]
fn strings_that_contain_non_digits_are_invalid() {
   assert!(!is_valid("046a 454 286"));
}

#[test]
//#[ignore]
fn punctuation_is_invalid() {
   assert!(!is_valid("055-444-285"));
}

#[test]
//#[ignore]
fn symbols_are_invalid() {
   assert!(!is_valid("055£ 444$ 285"));
}

#[test]
//#[ignore]
fn single_digit_with_space_is_invalid() {
   assert!(!is_valid(" 0"));
}

#[test]
//#[ignore]
fn lots_of_zeros_are_valid() {
   assert!(is_valid(" 00000"));
}

#[test]
//#[ignore]
fn another_valid_sin() {
   assert!(is_valid("055 444 285"));
}

#[test]
//#[ignore]
fn nine_doubled_is_nine() {
   assert!(is_valid("091"));
}

#}

4. 答案


# #![allow(unused_variables)]
#fn main() {
pub fn is_valid(candidate: &str) -> bool {
   if candidate.chars().filter(|c| c.is_digit(10)).take(2).count() <= 1
       || candidate.chars().any(|c| !c.is_digit(10) && c != ' ')
   {
       return false;
   }

   candidate
       .chars()
       .filter_map(|c| c.to_digit(10))
       .rev()
       .enumerate()
       .map(|(index, digit)| if index % 2 == 0 { digit } else { digit * 2 })
       .map(|digit| if digit > 9 { digit - 9 } else { digit })
       .sum::<u32>() % 10 == 0
}

#}



填充/相关