C# 用c语言实现luhn算法#
我正在使用以下代码在c#语言中实现信用卡检查的Luhn算法,但无法获得生成检查和的输出,显示其有效性:请帮助我。提前谢谢C# 用c语言实现luhn算法#,c#,checksum,luhn,C#,Checksum,Luhn,我正在使用以下代码在c#语言中实现信用卡检查的Luhn算法,但无法获得生成检查和的输出,显示其有效性:请帮助我。提前谢谢 public class Program { private static void Main(string[]creditcard) { int sum = 0, d; string num ="7992739871"; int a = 0; for (int i = num.Length -
public class Program
{
private static void Main(string[]creditcard)
{
int sum = 0, d;
string num ="7992739871";
int a = 0;
for (int i = num.Length - 2; i >= 0; i--)
{
d = Convert.ToInt32(num.Substring(i, 1));
if (a % 2 == 0)
d = d * 2;
if (d > 9)
d -= 9;
sum += d;
a++;
}
if ((10 - (sum % 10) == Convert.ToInt32(num.Substring(num.Length - 1))))
Console.WriteLine("valid");
Console.WriteLine("sum of digits of the number" + sum);
}
}
您的算法是正确的,但您的测试方法是错误的 我可以看到您的示例输入来自wiki页面:。不同的是,他们正在计算
“7992739871X”
的检查位数,其中X
是他们要查找的检查位数。您的代码将验证您已有的编号
将您的输入更改为“79927398713”,它会将其标记为正确的数字
更新
好的,我知道问题出在哪里了。你没有正确理解算法的这一部分:
从最右边的数字(即校验数字)开始,向左移动,每两个数字的值增加一倍
您的代码每隔一个数字取一个,但不必从最左边的数字开始。请尝试以下代码:
for (int i = 0; i < num.Length; i++)
{
d = Convert.ToInt32(num.Substring(num.Length - 1 - i, 1));
if (a % 2 == 0)
d = d * 2;
if (d > 9)
d -= 9;
sum += d;
a++;
}
var checkDigit = 10 - (sum % 10);
for(int i=0;i9)
d-=9;
总和+=d;
a++;
}
var校验位=10-(总和%10);
以下是一些扩展方法,可以计算Luhn checkdigit,使用checkdigit验证数字,并向数字添加checkdigit。在.NET4.5中测试
字符串、ints、int64s和IList都有扩展方法
我从你那里得到了一些想法
使用系统;
使用System.Collections.Generic;
利用制度全球化;
使用System.Linq;
公共静态类CheckDigitExtension
{
静态只读int[]结果={0,2,4,6,8,1,3,5,7,9};
#IList的区域扩展方法
///
///对于数字列表,计算结束校验位
///
///要计算校验位的数字列表
///校验位
公共静态整数校验位(此IList位)
{
var i=0;
var lengthMod=位数。计数%2;
返回(digits.Sum(d=>i++%2==lengthMod?d:Results[d])*9)%10;
}
///
///返回包含校验位的数字列表
///
///原始数字列表
///新的数字列表,包括checkdigit
公共静态IList AppendCheckDigit(此IList数字)
{
var结果=位数;
结果.添加(digits.CheckDigit());
返回结果;
}
///
///当数字列表具有有效的校验位时,返回true
///
///要检查的数字列表
///正确/错误取决于有效的校验位
公共静态bool HasValidCheckDigit(此IList数字)
{
返回digits.Last()==CheckDigit(digits.Take(digits.Count-1).ToList());
}
#ILST的端域扩展方法
#字符串的区域扩展方法
///
///用于将字符串转换为整数列表的内部转换函数
///
///原始字符串
///INT列表
私有静态IList ToDigitList(此字符串为数字)
{
返回数字.Select(d=>d-48).ToList();
}
///
///对于一串数字,计算结束的校验位
///
///要为其计算校验位的数字字符串
///校验位
公共静态字符串校验位(此字符串为数字)
{
返回digits.ToDigitList().CheckDigital().ToString(CultureInfo.InvariantCulture);
}
///
///返回包含校验位的数字字符串
///
///原始数字串
///新的数字字符串,包括checkdigit
公共静态字符串AppendCheckDigit(此字符串为数字)
{
返回数字+数字。检查数字();
}
///
///当一串数字具有有效的校验位时,返回true
///
///要检查的数字字符串
///正确/错误取决于有效的校验位
公共静态bool HasValidCheckDigit(此字符串为数字)
{
返回数字。ToDigitList().HasValidCheckDigit();
}
#字符串的endregion扩展方法
#整数的区域扩展方法
///
///内部转换函数,用于将整数转换为整数列表,每个数字对应一个整数
///
///原始int
///INT列表
私有静态IList到数字列表(此整数位数)
{
返回digits.ToString(CultureInfo.InvariantCulture).Select(d=>d-48.ToList();
}
///
///对于整数,计算结束校验位
///
///要计算其校验位的整数
///校验位
公共静态整数校验位(此整数位)
{
返回数字。ToDigitList().CheckDigit();
}
///
///返回一个包含校验位的整数
///
///原始整数
///包含校验位的新整数
公共静态整数AppendCheckDigit(此整数位数)
{
返回数字*10+个数字。检查数字();
}
///
///当整数具有有效的校验位时,返回true
///
///要检查的整数
///正确/错误取决于有效的校验位
公共静态布尔值HasValidCheckDigit(此整数位数)
{
返回数字。ToDigitList().HasValidCheckDigit();
}
#整数的端域扩展方法
#int64s的区域扩展方法
///
///内部转换函数,用于将整数转换为整数列表,每个数字对应一个整数
///
///原始int
///INT列表
私有静态IList到数字列表(此Int64位)
{
返回digits.ToString(CultureInfo.InvariantCulture).Select(d=>d-48.ToList();
}
///
///对于整数,计算结束校验位
///
///要计算其校验位的整数
///校验位
公共静态整数校验位(此整数为64位)
{
返回数字。ToDigitList().CheckDigit();
}
///
/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
public static class CheckDigitExtension
{
static readonly int[] Results = { 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 };
#region extension methods for IList<int>
/// <summary>
/// For a list of digits, compute the ending checkdigit
/// </summary>
/// <param name="digits">The list of digits for which to compute the check digit</param>
/// <returns>the check digit</returns>
public static int CheckDigit(this IList<int> digits)
{
var i = 0;
var lengthMod = digits.Count%2;
return (digits.Sum(d => i++ % 2 == lengthMod ? d : Results[d]) * 9) % 10;
}
/// <summary>
/// Return a list of digits including the checkdigit
/// </summary>
/// <param name="digits">The original list of digits</param>
/// <returns>the new list of digits including checkdigit</returns>
public static IList<int> AppendCheckDigit(this IList<int> digits)
{
var result = digits;
result.Add(digits.CheckDigit());
return result;
}
/// <summary>
/// Returns true when a list of digits has a valid checkdigit
/// </summary>
/// <param name="digits">The list of digits to check</param>
/// <returns>true/false depending on valid checkdigit</returns>
public static bool HasValidCheckDigit(this IList<int> digits)
{
return digits.Last() == CheckDigit(digits.Take(digits.Count - 1).ToList());
}
#endregion extension methods for IList<int>
#region extension methods for strings
/// <summary>
/// Internal conversion function to convert string into a list of ints
/// </summary>
/// <param name="digits">the original string</param>
/// <returns>the list of ints</returns>
private static IList<int> ToDigitList(this string digits)
{
return digits.Select(d => d - 48).ToList();
}
/// <summary>
/// For a string of digits, compute the ending checkdigit
/// </summary>
/// <param name="digits">The string of digits for which to compute the check digit</param>
/// <returns>the check digit</returns>
public static string CheckDigit(this string digits)
{
return digits.ToDigitList().CheckDigit().ToString(CultureInfo.InvariantCulture);
}
/// <summary>
/// Return a string of digits including the checkdigit
/// </summary>
/// <param name="digits">The original string of digits</param>
/// <returns>the new string of digits including checkdigit</returns>
public static string AppendCheckDigit(this string digits)
{
return digits + digits.CheckDigit();
}
/// <summary>
/// Returns true when a string of digits has a valid checkdigit
/// </summary>
/// <param name="digits">The string of digits to check</param>
/// <returns>true/false depending on valid checkdigit</returns>
public static bool HasValidCheckDigit(this string digits)
{
return digits.ToDigitList().HasValidCheckDigit();
}
#endregion extension methods for strings
#region extension methods for integers
/// <summary>
/// Internal conversion function to convert int into a list of ints, one for each digit
/// </summary>
/// <param name="digits">the original int</param>
/// <returns>the list of ints</returns>
private static IList<int> ToDigitList(this int digits)
{
return digits.ToString(CultureInfo.InvariantCulture).Select(d => d - 48).ToList();
}
/// <summary>
/// For an integer, compute the ending checkdigit
/// </summary>
/// <param name="digits">The integer for which to compute the check digit</param>
/// <returns>the check digit</returns>
public static int CheckDigit(this int digits)
{
return digits.ToDigitList().CheckDigit();
}
/// <summary>
/// Return an integer including the checkdigit
/// </summary>
/// <param name="digits">The original integer</param>
/// <returns>the new integer including checkdigit</returns>
public static int AppendCheckDigit(this int digits)
{
return digits * 10 + digits.CheckDigit();
}
/// <summary>
/// Returns true when an integer has a valid checkdigit
/// </summary>
/// <param name="digits">The integer to check</param>
/// <returns>true/false depending on valid checkdigit</returns>
public static bool HasValidCheckDigit(this int digits)
{
return digits.ToDigitList().HasValidCheckDigit();
}
#endregion extension methods for integers
#region extension methods for int64s
/// <summary>
/// Internal conversion function to convert int into a list of ints, one for each digit
/// </summary>
/// <param name="digits">the original int</param>
/// <returns>the list of ints</returns>
private static IList<int> ToDigitList(this Int64 digits)
{
return digits.ToString(CultureInfo.InvariantCulture).Select(d => d - 48).ToList();
}
/// <summary>
/// For an integer, compute the ending checkdigit
/// </summary>
/// <param name="digits">The integer for which to compute the check digit</param>
/// <returns>the check digit</returns>
public static int CheckDigit(this Int64 digits)
{
return digits.ToDigitList().CheckDigit();
}
/// <summary>
/// Return an integer including the checkdigit
/// </summary>
/// <param name="digits">The original integer</param>
/// <returns>the new integer including checkdigit</returns>
public static Int64 AppendCheckDigit(this Int64 digits)
{
return digits * 10 + digits.CheckDigit();
}
/// <summary>
/// Returns true when an integer has a valid checkdigit
/// </summary>
/// <param name="digits">The integer to check</param>
/// <returns>true/false depending on valid checkdigit</returns>
public static bool HasValidCheckDigit(this Int64 digits)
{
return digits.ToDigitList().HasValidCheckDigit();
}
#endregion extension methods for int64s
}
public class CheckDigitExtensionShould
{
[Fact]
public void ComputeCheckDigits()
{
Assert.Equal(0, (new List<int> { 0 }).CheckDigit());
Assert.Equal(8, (new List<int> { 1 }).CheckDigit());
Assert.Equal(6, (new List<int> { 2 }).CheckDigit());
Assert.Equal(0, (new List<int> { 3, 6, 1, 5, 5 }).CheckDigit());
Assert.Equal(0, 36155.CheckDigit());
Assert.Equal(8, (new List<int> { 3, 6, 1, 5, 6 }).CheckDigit());
Assert.Equal(8, 36156.CheckDigit());
Assert.Equal(6, 36157.CheckDigit());
Assert.Equal("6", "36157".CheckDigit());
Assert.Equal("3", "7992739871".CheckDigit());
}
[Fact]
public void ValidateCheckDigits()
{
Assert.True((new List<int> { 3, 6, 1, 5, 6, 8 }).HasValidCheckDigit());
Assert.True(361568.HasValidCheckDigit());
Assert.True("361568".HasValidCheckDigit());
Assert.True("79927398713".HasValidCheckDigit());
}
[Fact]
public void AppendCheckDigits()
{
Console.WriteLine("36156".CheckDigit());
Console.WriteLine("36156".AppendCheckDigit());
Assert.Equal("361568", "36156".AppendCheckDigit());
Assert.Equal("79927398713", "7992739871".AppendCheckDigit());
}
}
public static bool Mod10Check(string creditCardNumber)
{
// check whether input string is null or empty
if (string.IsNullOrEmpty(creditCardNumber))
{
return false;
}
int sumOfDigits = creditCardNumber.Where((e) => e >= '0' && e <= '9')
.Reverse()
.Select((e, i) => ((int)e - 48) * (i % 2 == 0 ? 1 : 2))
.Sum((e) => e / 10 + e % 10);
return sumOfDigits % 10 == 0;
}
public static bool Luhn(string digits)
{
return digits.All(char.IsDigit) && digits.Reverse()
.Select(c => c - 48)
.Select((thisNum, i) => i % 2 == 0
? thisNum
:((thisNum *= 2) > 9 ? thisNum - 9 : thisNum)
).Sum() % 10 == 0;
}
static void Main(string[] args)
{
string number = "1762483";
int digit = 0;
int sum = 0;
for (int i = 0; i <= number.Length - 1; i++)
{
if (i % 2 == 1)
{
digit = int.Parse(number.Substring(i, 1));
sum += DoubleDigitValue(digit);
Console.WriteLine(digit);
}
else
{
digit = int.Parse(number.Substring(i, 1));
sum += digit;
}
}
Console.WriteLine(sum);
if (sum % 10 == 0)
{
Console.WriteLine("valid");
}
else
{
Console.WriteLine("Invalid");
}
}
static int DoubleDigitValue(int digit)
{
int sum;
int doubledDigit = digit * 2;
if (doubledDigit >= 10)
{
sum = 1 + doubledDigit % 10;
} else
{
sum = doubledDigit;
}
return sum;
}
public string GenerateLuhnNumber(string baseNumber)
{
if (!double.TryParse(baseNumber, out double baseNumberInt))
throw new InvalidWorkflowException($"Field contains non-numeric character(s) : {baseNumber}");
var step2 = string.Empty;
for (var index = baseNumber.Length - 1; index >= 0; index -= 2)
{
var doubleTheValue = (int.Parse(baseNumber[index].ToString())) * 2;
if (doubleTheValue > 9)
doubleTheValue = Math.Abs(doubleTheValue).ToString().Sum(c => Convert.ToInt32(c.ToString()));
step2 = step2.Insert(0, (index != 0 ? baseNumber[index - 1].ToString() : "") + doubleTheValue);
}
var step3 = Math.Abs(Convert.ToDouble(step2)).ToString(CultureInfo.InvariantCulture).Sum(c => Convert.ToDouble(c.ToString())).ToString(CultureInfo.InvariantCulture);
var lastDigitStep3 = Convert.ToInt32(step3[step3.Length - 1].ToString());
string checkDigit = "0";
if (lastDigitStep3 != 0)
checkDigit = (10 - lastDigitStep3).ToString();
return baseNumber + checkDigit;
}
bool PassesLuhnCheck(string value)
{
long sum = 0;
for (int i = 0; i < value.Length; i++)
{
var digit = value[value.Length - 1 - i] - '0';
sum += (i % 2 != 0) ? GetDouble(digit) : digit;
}
return sum % 10 == 0;
int GetDouble(long i)
{
switch (i)
{
case 0: return 0;
case 1: return 2;
case 2: return 4;
case 3: return 6;
case 4: return 8;
case 5: return 1;
case 6: return 3;
case 7: return 5;
case 8: return 7;
case 9: return 9;
default: return 0;
}
}
}
private int LuhnChecksum(string input)
{
var length = input.Length;
var even = length % 2;
var sum = 0;
for (var i = length - 1; i >= 0; i--)
{
var d = int.Parse(input[i].ToString());
if (i % 2 == even)
d *= 2;
if (d > 9)
d -= 9;
sum += d;
}
return sum % 10;
}
private int LuhnCalculateLastDigit(string input)
{
var checksum = LuhnChecksum(input + "0");
return checksum == 0 ? 0 : 10 - checksum;
}
byte[] data = new byte[19];
//fill the data[]
...
//use it
if (checkByLuhn(data))
{
//check complete
}
...
private bool checkByLuhn(byte[] pPurposed)
{
int nSum = 0;
int nDigits = pPurposed.Length;
int nParity = (nDigits - 1) % 2;
char[] cDigit = new char[] { '0','\0' };
for (int i = nDigits; i > 0; i--)
{
cDigit[0] = (char)pPurposed[i - 1];
int nDigit = (int)Char.GetNumericValue(cDigit[0]);
if (nParity == i % 2)
{
nDigit = nDigit * 2;
}
nSum += nDigit / 10;
nSum += nDigit % 10;
}
return 0 == nSum % 10;
}