@@ -52,6 +52,11 @@ public static class Luhn
52
52
/// </summary>
53
53
private const int Modulus = 10 ;
54
54
55
+ /// <summary>
56
+ /// Represents the ASCII code for the character '0'.
57
+ /// </summary>
58
+ private const int AsciiCodeForZero = 48 ;
59
+
55
60
#if NET8_0_OR_GREATER
56
61
/// <summary>
57
62
/// Computes the Luhn check digit
@@ -63,7 +68,7 @@ public static class Luhn
63
68
[ SuppressMessage ( "ReSharper" , "UnusedMember.Global" ) ]
64
69
[ SuppressMessage ( "ReSharper" , "HeapView.ObjectAllocation" ) ]
65
70
public static byte ComputeLuhnCheckDigit ( this ReadOnlySpan < char > number ) =>
66
- ( byte ) ( ( Modulus - number . IsNumber ( ) . GetDigits ( ) . DoubleEverySecondDigit ( false ) . SumDigits ( ) ) % Modulus ) ;
71
+ ( byte ) ( ( Modulus - number . ValidateAndTrimNumber ( ) . GetDigits ( ) . DoubleEverySecondDigit ( false ) . SumDigits ( ) ) % Modulus ) ;
67
72
#endif
68
73
69
74
/// <summary>
@@ -79,7 +84,7 @@ public static byte ComputeLuhnCheckDigit(this string number) =>
79
84
#if NET8_0_OR_GREATER
80
85
number . AsSpan ( ) . ComputeLuhnCheckDigit ( ) ;
81
86
#else
82
- ( byte ) ( ( Modulus - number . IsNumber ( ) . GetDigits ( ) . DoubleEverySecondDigit ( false ) . SumDigits ( ) ) % Modulus ) ;
87
+ ( byte ) ( ( Modulus - number . ValidateAndTrimNumber ( ) . GetDigits ( ) . DoubleEverySecondDigit ( false ) . SumDigits ( ) ) % Modulus ) ;
83
88
#endif
84
89
85
90
#if NET8_0_OR_GREATER
@@ -136,7 +141,7 @@ public static string ComputeLuhnNumber(this string number)
136
141
[ SuppressMessage ( "ReSharper" , "UnusedMember.Global" ) ]
137
142
[ SuppressMessage ( "ReSharper" , "HeapView.ObjectAllocation" ) ]
138
143
public static bool IsValidLuhnNumber ( this ReadOnlySpan < char > luhnNumber ) =>
139
- luhnNumber . IsNumber ( ) . GetDigits ( ) . DoubleEverySecondDigit ( true ) . SumDigits ( ) == 0 ;
144
+ luhnNumber . ValidateAndTrimNumber ( ) . GetDigits ( ) . DoubleEverySecondDigit ( true ) . SumDigits ( ) == 0 ;
140
145
#endif
141
146
142
147
/// <summary>
@@ -155,7 +160,7 @@ public static bool IsValidLuhnNumber(this string luhnNumber) =>
155
160
#if NET8_0_OR_GREATER
156
161
luhnNumber . AsSpan ( ) . IsValidLuhnNumber ( ) ;
157
162
#else
158
- luhnNumber . IsNumber ( ) . GetDigits ( ) . DoubleEverySecondDigit ( true ) . SumDigits ( ) == 0 ;
163
+ luhnNumber . ValidateAndTrimNumber ( ) . GetDigits ( ) . DoubleEverySecondDigit ( true ) . SumDigits ( ) == 0 ;
159
164
#endif
160
165
161
166
#if NET8_0_OR_GREATER
@@ -184,7 +189,7 @@ public static bool IsValidLuhnCheckDigit(this byte checkDigit, ReadOnlySpan<char
184
189
185
190
return string . Concat ( number . Trim ( ) , checkDigit . ToString ( CultureInfo . InvariantCulture ) )
186
191
. AsSpan ( )
187
- . IsNumber ( )
192
+ . ValidateAndTrimNumber ( )
188
193
. GetDigits ( )
189
194
. DoubleEverySecondDigit ( true )
190
195
. SumDigits ( ) == 0 ;
@@ -222,7 +227,7 @@ public static bool IsValidLuhnCheckDigit(this byte checkDigit, string number)
222
227
"{0}{1}" ,
223
228
number . Trim ( ) ,
224
229
checkDigit . ToString ( CultureInfo . InvariantCulture ) )
225
- . IsNumber ( )
230
+ . ValidateAndTrimNumber ( )
226
231
. GetDigits ( )
227
232
. DoubleEverySecondDigit ( true )
228
233
. SumDigits ( ) == 0 ;
@@ -294,12 +299,12 @@ public static string ConvertAlphaNumericToNumeric(this string alphaNumeric)
294
299
#endif
295
300
296
301
/// <summary>
297
- /// Doubling of every second digit.
302
+ /// Doubles every second digit of the <paramref name="digits"/> enumeration .
298
303
/// </summary>
299
304
/// <param name="digits">The digits represent a number w/ or w/o check digit.</param>
300
305
/// <param name="forValidation"><see langword="true"/> if the <paramref name="digits"/> represent
301
306
/// a Luhn number including a check digit; otherwise <see langword="false"/></param>
302
- /// <returns></returns>
307
+ /// <returns>Enumeration of digits </returns>
303
308
private static IEnumerable < uint > DoubleEverySecondDigit ( this IEnumerable < uint > digits , bool forValidation )
304
309
{
305
310
int index = 0 ;
@@ -336,7 +341,7 @@ private static IEnumerable<uint> DoubleEverySecondDigit(this IEnumerable<uint> d
336
341
/// <param name="number">An identification number</param>
337
342
/// <returns>The trimmed identification number if valid</returns>
338
343
/// <exception cref="ArgumentException"><paramref name="number"/> is not a valid number</exception>
339
- private static string IsNumber ( this string number )
344
+ private static string ValidateAndTrimNumber ( this string number )
340
345
{
341
346
string trimmedNumber = number ? . Trim ( ) ;
342
347
if ( string . IsNullOrWhiteSpace ( trimmedNumber ) || ! Regex . IsMatch ( trimmedNumber , @"^\d+$" ) )
@@ -355,7 +360,7 @@ private static string IsNumber(this string number)
355
360
/// <param name="number">An identification number</param>
356
361
/// <returns>The trimmed identification number if valid</returns>
357
362
/// <exception cref="ArgumentException"><paramref name="number"/> is not a valid number</exception>
358
- private static ReadOnlySpan < char > IsNumber ( this ReadOnlySpan < char > number )
363
+ private static ReadOnlySpan < char > ValidateAndTrimNumber ( this ReadOnlySpan < char > number )
359
364
{
360
365
var trimmedNumber = number . Trim ( ) ;
361
366
if ( trimmedNumber . Length == 0 || ! trimmedNumber . IsDigits ( ) )
@@ -397,7 +402,7 @@ private static IEnumerable<uint> GetDigits(this ReadOnlySpan<char> number)
397
402
uint [ ] digits = new uint [ number . Length ] ;
398
403
for ( int i = 0 ; i < number . Length ; i ++ )
399
404
{
400
- digits [ number . Length - i - 1 ] = ( uint ) number [ i ] - 48 ;
405
+ digits [ number . Length - i - 1 ] = ( uint ) number [ i ] - AsciiCodeForZero ;
401
406
}
402
407
403
408
return digits ;
@@ -407,7 +412,7 @@ private static IEnumerable<uint> GetDigits(this string number)
407
412
{
408
413
for ( int i = number . Length - 1 ; i >= 0 ; i -- )
409
414
{
410
- yield return ( uint ) number [ i ] - 48 ;
415
+ yield return ( uint ) number [ i ] - AsciiCodeForZero ;
411
416
}
412
417
}
413
418
#endif
0 commit comments