Calculating a Luhn Check Digit I was able to find all kinds of examples that demonstrate how to validate a Luhn Checksum but very few that actually generated the check digit. Here is my attempt in base 10, based on the validation examples found at Wikipedia and Rosetta Code:

/// &lt;summary&gt;
/// Constructs the check digit for a given numeric string using the Luhn algorithm; also known as the "mod 10" algorithm.
/// &lt;/summary&gt;
/// &lt;param name="value"&gt;The string that a check digit will be calculated from.&lt;/param&gt;
public static int Mod10(string value) {
    const int validCodePointCount = 10;
    const int validCodePointOffset = 48;

    var index = value.Length;
    var parity = true;
    var sum = 0;

    while (0 &lt; index--) {
        var digit = (value[index] - validCodePointOffset);

        if (parity) {
            if ((validCodePointCount - 1) &lt; (digit &lt;&lt;= 1)) {
                digit -= (validCodePointCount - 1);
            }
        }

        parity = !parity;
        sum += digit;
    }

    return ((validCodePointCount - (sum %= validCodePointCount)) % validCodePointCount);
}
All in all it seems OK to me. A couple of things though:

1) 

  const int validCodePointCount = 10;
  const int validCodePointOffset = 48;


The names of these constants are hard to distinguish from each other and to understand in the context and they blur the behavior of the algorithm.

Better names could be:

const int numberBase = 10;
const int zero = '0';


Here I use '0' instead of 48 because the first is much more recognizable to programmers than the latter, and we instantly grasp the meaning. In fact in such a relatively small algorithm, I would prefer to use the literals directly in the code than the named constants like: 

var digit = (value[index] - '0');


This is such a common operation and we all know what it's about immediately when seeing it.

In general it is wise to avoid magic numbers, but in some situations it is preferable in order to improve readability - IMO.



2)

You don't have to iterate backwards because you can determine the initial parity from the length of the input string:

var parity = value.Length % 2 != 0;


You can then iterate forward:

foreach (int n in value.Select(c =&gt; c - '0'))
{
  ...
  parity = !parity;
}