implementing luhn algorithm using c#

后端 未结 9 445
醉梦人生
醉梦人生 2020-12-03 02:19

I am using following code to implement Luhn algorithm for credit card check in c# language but could not get the output to generate the check sum its showing validity: kindl

相关标签:
9条回答
  • 2020-12-03 02:37

    Here is a correct and fast implementation:

    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;
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-03 02:41

    I have tried this code which might help for other future folk:

        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;
        }
    
    0 讨论(0)
  • 2020-12-03 02:43

    Here are some extension methods that compute a Luhn checkdigit, validate a number with a checkdigit, and add a checkdigit to a number. Tested in .NET 4.5.

    There are extension methods for strings, ints, int64s and IList.

    I got some ideas for this from rosettacode.org

    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
    }
    

    Here are some XUnit test cases that show how the extension methods work.

    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());
        }
    }
    
    0 讨论(0)
  • 2020-12-03 02:49

    Compact Luhn check:

    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;
    }
    

    Fiddle: https://dotnetfiddle.net/CCwE48

    0 讨论(0)
  • 2020-12-03 02:50

    This one will do it I believe:

    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; 
        }
    
    0 讨论(0)
  • 2020-12-03 02:55

    These are my methods for validating and calculating the last digit. To validate a number simply check that the result of the first method is 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;
        }
    
    0 讨论(0)
提交回复
热议问题