The credit card mod 10 validation algorithm is quite straightforward. Easy enough for me to have a go at writing with LINQ. This example is written as an extension method validator. Let me know if you can make this even more concise.
public ValidationProperty IsCreditCard()
{
value.Label(label).IsNumeric().WithLengthRange(13.To(18));
var numbers = value.Trim().Reverse().Select(c => int.Parse(c.ToString()));
int oddSum = numbers.AtOddPositions().Sum();
int doubleEvenSum = numbers.AtEvenPositions().SelectMany(i => new int[] { (i * 2) % 10, (i * 2) / 10 }).Sum();
if ((oddSum + doubleEvenSum) % 10 != 0)
{
throw new ValidationException("{0} is not a valid credit card number".With(label));
}
return this;
}
Here are the AtOddPositions and AtEvenPositions extension methods:
public static IEnumerable<T> AtOddPositions<T>(this IEnumerable<T> list)
{
bool odd = false; // 0th position is even
foreach (T item in list)
{
odd = !odd;
if (odd)
{
yield return item;
}
}
}
public static IEnumerable<T> AtEvenPositions<T>(this IEnumerable<T> list)
{
bool even = true; // 0th position is even
foreach (T item in list)
{
even = !even;
if (even)
{
yield return item;
}
}
}
Am I going extension method crazy??
1 comment:
Here's another implementation.
Post a Comment