-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathControlDigitAlgo.cs
More file actions
115 lines (100 loc) · 3.49 KB
/
Copy pathControlDigitAlgo.cs
File metadata and controls
115 lines (100 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
using System;
using System.Collections.Generic;
using System.Linq;
namespace SRP.ControlDigit
{
public static class Extensions
{
public static int[] ParseCode(this long extensible)
{
return extensible.ToString().Select(c => int.Parse(c.ToString())).ToArray();
}
public static int GetSumOfDigits(this int extensible)
{
var sum = 0;
while (extensible >= 10)
{
sum += extensible % 10;
extensible /= 10;
}
return sum + extensible;
}
public static int[] CompleteToIsbn10Length(this int[] extensible)
{
var ten = new int[9];
var counter = 8;
foreach (var digit in extensible.Reverse())
{
ten[counter] = digit;
counter--;
}
return ten;
}
public static IEnumerable<int> SelectOdd(this IEnumerable<int> extensible)
{
return extensible.Where((d, index) => index % 2 != 0);
}
public static IEnumerable<int> SelectEven(this IEnumerable<int> extensible)
{
return extensible.Where((d, index) => index % 2 == 0);
}
public static int SumWithRule(this IEnumerable<int> extensible, Func<int, int, int> func)
{
var enumerable = extensible.ToArray();
return enumerable.Select((d, index) => (10 - index) * d).Sum();
}
}
public class ControlDigitAlgo
{
private static int ReturnControlDigitUpc(int extensible)
{
return extensible % 10 == 0
? 0
: 10 - extensible % 10;
}
private static char ReturnControlDigitIsbn10(int value)
{
return value == 10
? 'X'
: (char) (value + 48);
}
private static int ReturnControlDigitLuhn(int value)
{
return (10 - value % 10) % 10;
}
private static int LuhnForOddLength(int[] digits)
{
var sumOdd = digits.SelectOdd().Sum();
var sumEven = digits.SelectEven().Select(d => (d * 2).GetSumOfDigits()).Sum();
return ReturnControlDigitLuhn(sumOdd + sumEven);
}
private static int LuhnForEvenLength(int[] digits)
{
var sumEven = digits.SelectEven().Sum();
var sumOdd = digits.SelectOdd().Select(d => (d * 2).GetSumOfDigits()).Sum();
return ReturnControlDigitLuhn(sumEven + sumOdd);
}
public static int Upc(long number)
{
if (number < 10 && number != 0) return (int) (10 - number * 3 % 10);
const int factor = 3;
var digits = number.ParseCode();
var sumOdd = digits.SelectOdd().Sum();
var sumEven = digits.Take(digits.Length - 1).SelectEven().Sum();
return ReturnControlDigitUpc(sumOdd * factor + sumEven);
}
public static char Isbn10(long number)
{
var digits = number.ParseCode().CompleteToIsbn10Length();
var sum = digits.SumWithRule((d, index) => (10 - index) * d);
return ReturnControlDigitIsbn10((11 - sum % 11) % 11);
}
public static int Luhn(long number)
{
var digits = number.ParseCode();
return digits.Length % 2 == 0
? LuhnForEvenLength(digits)
: LuhnForOddLength(digits);
}
}
}