Here is some code that I put together a while back to calculate a MOD10 check digit for a specified value. These can be handy in structuring account numbers. By putting a check digit as the last digit you can then validate it when a data entry operator re-enters it helping to ensure that the correct account number was entered and didn't have a typo in it.
The only hiccup is that I'm using some extension methods to identify even/odd values and then also for Left and Right functions. I will include those extension methods also. You can also just turn them into functions and include them in the class / call them like functions.
VB.Net Mod10CheckDigit Class
Imports Argus.Extensions
Namespace Argus.Data
''' <summary>
''' Shared methods for calculating and verifying MOD10 check digits.
''' </summary>
Public Class Mod10CheckDigit
'*********************************************************************************************************************
'
' Class: Mod10CheckDigit
' Organization: http://www.blakepell.com
' Initial Date: 05/20/2013
' Last Updated: 11/17/2014
' Programmer(s): Blake Pell, blakepell@hotmail.com
'
'*********************************************************************************************************************
''' <summary>
''' Returns a check digit for a specified string.
''' </summary>
''' <param name="txt">The string value to create a check digit for</param>
''' <returns>An integer check digit</returns>
Public Shared Function Calculate(txt As String) As Integer
Dim baseList As New List(Of String)
txt = txt.ToUpper
For x As Integer = 0 To txt.Count - 1
baseList.Add(GetValue(txt.Substring(x, 1)))
Next
Dim calcList As New List(Of String)
' Get the new values
For x As Integer = 0 To baseList.Count - 1
If x.IsEven = True Then
calcList.Add(CInt(baseList(x)) * 1)
Else
calcList.Add(CInt(baseList(x)) * 2)
End If
Next
' Pad any single digits
For x As Integer = 0 To calcList.Count - 1
If calcList(x).Length = 1 Then
calcList(x) = "0" & calcList(x)
End If
Next
' Bust these all up into single digits
Dim digitList As New List(Of Integer)
For x As Integer = 0 To calcList.Count - 1
digitList.Add(CInt(calcList(x).Left(1)))
digitList.Add(CInt(calcList(x).Right(1)))
Next
Dim sumOfDigits As Integer = digitList.Sum
Dim lastDigit As Integer = CInt(sumOfDigits.ToString.Right(1))
If lastDigit = 0 Then
Return 0
Else
Return 10 - lastDigit
End If
End Function
''' <summary>
''' Whether or not the specified value is correct (e.g. the check digit matches the rest of the provided value). The inputted value would
''' be the string with the check digit (e.g., a full account number).
''' </summary>
''' <param name="val">The value with the check digit to validate.</param>
Public Shared Function IsValid(val As String) As Boolean
If String.IsNullOrWhiteSpace(val) = True Then
Return False
ElseIf val.Length = 1 Then
Return False
End If
Dim originalCheckDigit As String = val.SafeRight(1)
Dim originalWithoutCheckDigit As String = val.SafeLeft(val.Length - 1)
Dim calculatedCheckDigit As String = Calculate(originalWithoutCheckDigit)
If calculatedCheckDigit = originalCheckDigit Then
Return True
Else
Return False
End If
End Function
''' <summary>
''' Returns the lookup value as specified in the MOD-10 documentation.
''' </summary>
Public Shared Function GetValue(val As String) As String
If val.Length > 1 Then
Throw New Exception("Value has a length of greater than 1")
End If
Select Case val
Case "0"
Return "00"
Case "1"
Return "01"
Case "2"
Return "02"
Case "3"
Return "03"
Case "4"
Return "04"
Case "5"
Return "05"
Case "6"
Return "06"
Case "7"
Return "07"
Case "8"
Return "08"
Case "9"
Return "09"
Case "A"
Return "10"
Case "B"
Return "11"
Case "C"
Return "12"
Case "D"
Return "13"
Case "E"
Return "14"
Case "F"
Return "15"
Case "G"
Return "16"
Case "H"
Return "17"
Case "I"
Return "18"
Case "J"
Return "19"
Case "K"
Return "20"
Case "L"
Return "21"
Case "M"
Return "22"
Case "N"
Return "23"
Case "O"
Return "24"
Case "P"
Return "25"
Case "Q"
Return "26"
Case "R"
Return "27"
Case "S"
Return "28"
Case "T"
Return "29"
Case "U"
Return "30"
Case "V"
Return "31"
Case "W"
Return "32"
Case "X"
Return "33"
Case "Y"
Return "34"
Case "Z"
Return "35"
Case "*"
Return "36"
Case "@"
Return "37"
Case "#"
Return "38"
Case Else
Throw New Exception(String.Format("Invalid input. '{0}' is an unsupported character.", val))
End Select
End Function
End Class
End Namespace
VB.Net - Extension Methods
''' <summary>
''' This function will return the specified amount of characters from the left hand side of the string. This is the equivalent of the Visual Basic Left function.
''' </summary>
''' <param name="str"></param>
''' <param name="length"></param>
<Extension()> _
Public Function [Left](ByVal str As String, ByVal length As Integer) As String
Return str.Substring(0, length)
End Function
''' <summary>
''' This function will return the specified amount of characters from the right hand side of the string. This is the equivalent of the Visual Basic Right function.
''' </summary>
''' <param name="str"></param>
''' <param name="length"></param>
<Extension()> _
Public Function [Right](ByVal str As String, ByVal length As Integer) As String
Return str.Substring(str.Length - length, length)
End Function
''' <summary>
''' Returns the specified number of characters from the left hand side of the string. If the number asked for is longer the
''' string then the entire string is returned without an exception.
''' </summary>
''' <param name="str"></param>
''' <param name="length"></param>
<Extension()> _
Public Function SafeLeft(ByVal str As String, ByVal length As Integer) As String
If length >= str.Length Then
Return str
ElseIf length < 0 Then
Return ""
End If
Return Left(str, length)
End Function
''' <summary>
''' Returns the specified number of characters from the right hand side of the string. If the number asked for is longer the
''' string then the entire string is returned without an exception.
''' </summary>
''' <param name="str"></param>
''' <param name="length"></param>
<Extension()> _
Public Function SafeRight(ByVal str As String, ByVal length As Integer) As String
If length >= str.Length Then
Return str
ElseIf length < 0 Then
Return ""
End If
Return Right(str, length)
End Function
C# - Mod10CheckDigit Class
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using Argus.Extensions;
namespace Argus.Data
{
/// <summary>
/// Shared methods for calculating and verifying MOD10 check digits.
/// </summary>
/// <remarks></remarks>
public class Mod10CheckDigit
{
//*********************************************************************************************************************
//
// Class: Mod10CheckDigit
// Organization: http://www.blakepell.com
// Initial Date: 05/20/2013
// Last Updated: 11/17/2014
// Programmer(s): Blake Pell, blakepell@hotmail.com
//
//*********************************************************************************************************************
/// <summary>
/// Returns a check digit for a specified string.
/// </summary>
/// <param name="txt">The string value to create a check digit for</param>
/// <returns>An integer check digit</returns>
public static int Calculate(string txt)
{
List<string> baseList = new List<string>();
txt = txt.ToUpper;
for (int x = 0; x <= txt.Count - 1; x++) {
baseList.Add(GetValue(txt.Substring(x, 1)));
}
List<string> calcList = new List<string>();
// Get the new values
for (int x = 0; x <= baseList.Count - 1; x++) {
if (x.IsEven == true) {
calcList.Add(Convert.ToInt32(baseList(x)) * 1);
} else {
calcList.Add(Convert.ToInt32(baseList(x)) * 2);
}
}
// Pad any single digits
for (int x = 0; x <= calcList.Count - 1; x++) {
if (calcList(x).Length == 1) {
calcList(x) = "0" + calcList(x);
}
}
// Bust these all up into single digits
List<int> digitList = new List<int>();
for (int x = 0; x <= calcList.Count - 1; x++) {
digitList.Add(Convert.ToInt32(calcList(x).Left(1)));
digitList.Add(Convert.ToInt32(calcList(x).Right(1)));
}
int sumOfDigits = digitList.Sum;
int lastDigit = Convert.ToInt32(sumOfDigits.ToString.Right(1));
if (lastDigit == 0) {
return 0;
} else {
return 10 - lastDigit;
}
}
/// <summary>
/// Whether or not the specified value is correct (e.g. the check digit matches the rest of the provided value). The inputted value would
/// be the string with the check digit (e.g., a full account number).
/// </summary>
/// <param name="val">The value with the check digit to validate.</param>
public static bool IsValid(string val)
{
if (string.IsNullOrWhiteSpace(val) == true) {
return false;
} else if (val.Length == 1) {
return false;
}
string originalCheckDigit = val.SafeRight(1);
string originalWithoutCheckDigit = val.SafeLeft(val.Length - 1);
string calculatedCheckDigit = Calculate(originalWithoutCheckDigit);
if (calculatedCheckDigit == originalCheckDigit) {
return true;
} else {
return false;
}
}
/// <summary>
/// Returns the lookup value as specified in the MOD-10 documentation.
/// </summary>
public static string GetValue(string val)
{
if (val.Length > 1) {
throw new Exception("Value has a length of greater than 1");
}
switch (val) {
case "0":
return "00";
case "1":
return "01";
case "2":
return "02";
case "3":
return "03";
case "4":
return "04";
case "5":
return "05";
case "6":
return "06";
case "7":
return "07";
case "8":
return "08";
case "9":
return "09";
case "A":
return "10";
case "B":
return "11";
case "C":
return "12";
case "D":
return "13";
case "E":
return "14";
case "F":
return "15";
case "G":
return "16";
case "H":
return "17";
case "I":
return "18";
case "J":
return "19";
case "K":
return "20";
case "L":
return "21";
case "M":
return "22";
case "N":
return "23";
case "O":
return "24";
case "P":
return "25";
case "Q":
return "26";
case "R":
return "27";
case "S":
return "28";
case "T":
return "29";
case "U":
return "30";
case "V":
return "31";
case "W":
return "32";
case "X":
return "33";
case "Y":
return "34";
case "Z":
return "35";
case "*":
return "36";
case "@":
return "37";
case "#":
return "38";
default:
throw new Exception(string.Format("Invalid input. '{0}' is an unsupported character.", val));
}
}
}
}
C# - Extension Methods
/// <summary>
/// This function will return the specified amount of characters from the left hand side of the string. This is the equivalent of the Visual Basic Left function.
/// </summary>
/// <param name="str"></param>
/// <param name="length"></param>
public static string Left(this string str, int length)
{
return str.Substring(0, length);
}
/// <summary>
/// This function will return the specified amount of characters from the right hand side of the string. This is the equivalent of the Visual Basic Right function.
/// </summary>
/// <param name="str"></param>
/// <param name="length"></param>
/// <returns></returns>
/// <remarks></remarks>
public static string Right(this string str, int length)
{
return str.Substring(str.Length - length, length);
}
/// <summary>
/// Returns the specified number of characters from the left hand side of the string. If the number asked for is longer the
/// string then the entire string is returned without an exception.
/// </summary>
/// <param name="str"></param>
/// <param name="length"></param>
/// <returns></returns>
/// <remarks></remarks>
public static string SafeLeft(this string str, int length)
{
if (length >= str.Length)
{
return str;
}
else if (length < 0)
{
return "";
}
return Strings.Left(str, length);
}
/// <summary>
/// Returns the specified number of characters from the right hand side of the string. If the number asked for is longer the
/// string then the entire string is returned without an exception.
/// </summary>
/// <param name="str"></param>
/// <param name="length"></param>
/// <returns></returns>
/// <remarks></remarks>
[Extension()]
public static string SafeRight(this string str, int length)
{
if (length >= str.Length)
{
return str;
}
else if (length < 0)
{
return "";
}
return Strings.Right(str, length);
}