Generating Luhn Checksums

前端 未结 6 474
挽巷
挽巷 2020-12-28 08:36

There are lots of implementations for validating Luhn checksums but very few for generating them. I\'ve come across this one however in my tests it has revealed to be buggy

6条回答
  •  清酒与你
    2020-12-28 08:59

    Since the other answers that displayed or linked to C# weren't working, I've added a tested and more explanatory C# version:

        /// 
        /// Calculates Luhn Check Digit based on 
        /// https://en.wikipedia.org/wiki/Luhn_algorithm
        /// 
        /// The digits EXCLUDING the check digit on the end. 
        /// The check digit should be compared against the result of this method.      
        /// 
        /// The correct checkDigit
        public static int CalculateLuhnCheckDigit(int[] digits)
        {
            int sum = 0;
            bool isMultiplyByTwo = false;
    
            //Start the summing going right to left
            for (int index = digits.Length-1; index >= 0; --index) 
            {
                int digit = digits[index];
    
                //Every other digit should be multipled by two.
                if (isMultiplyByTwo) 
                    digit *= 2;
    
                //When the digit becomes 2 digits (due to digit*2),
                //we add the two digits together.
                if (digit > 9) 
                    digit = digit.ToString()
                      .Sum(character => (int)char.GetNumericValue(character));
    
                sum += digit;
                isMultiplyByTwo = !isMultiplyByTwo;
            }
    
            int remainder = sum % 10;
    
            //If theres no remainder, the checkDigit is 0.
            int checkDigit = 0; 
    
            //Otherwise, the checkDigit is the number that gets to the next 10
            if (remainder != 0)
                checkDigit = 10 - (sum % 10); 
    
            return checkDigit;
        }
    

    An example of its use:

        public static bool IsValid(string userValue)
        {
            //Get the check digit from the end of the value
            int checkDigit = (int)char.GetNumericValue(userValue[userValue.Length - 1]);
    
            //Remove the checkDigit for the luhn calculation
            userValue = userValue.Substring(0, userValue.Length - 1); 
            int[] userValueDigits = userValue.Select(ch => (int)char.GetNumericValue(ch))
                                             .ToArray();
    
            int originalLuhnDigit = CalculateLuhnCheckDigit(userValueDigits);
    
            //If the user entered check digit matches the calcuated one,
            //the number is valid.
            return checkDigit == originalLuhnDigit;
        }
    

提交回复
热议问题