Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 354033
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 12, 20262026-05-12T11:53:10+00:00 2026-05-12T11:53:10+00:00

There are lots of implementations for validating Luhn checksums but very few for generating

  • 0

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 and I don’t understand the logic behind the delta variable.

I’ve made this function that supposedly should generated Luhn checksums but for some reason that I haven’t yet understood the generated checksums are invalid half of the time.

function Luhn($number, $iterations = 1)
{
    while ($iterations-- >= 1)
    {
        $stack = 0;
        $parity = strlen($number) % 2;
        $number = str_split($number, 1);

        foreach ($number as $key => $value)
        {
            if ($key % 2 == $parity)
            {
                $value *= 2;

                if ($value > 9)
                {
                    $value -= 9;
                }
            }

            $stack += $value;
        }

        $stack = 10 - $stack % 10;

        if ($stack == 10)
        {
            $stack = 0;
        }

        $number[] = $stack;
    }

    return implode('', $number);
}

Some examples:

Luhn(3); // 37, invalid
Luhn(37); // 372, valid
Luhn(372); // 3728, invalid
Luhn(3728); // 37283, valid
Luhn(37283); // 372837, invalid
Luhn(372837); // 3728375, valid

I’m validating the generated checksums against this page, what am I doing wrong here?


For future reference, here is the working function.

function Luhn($number, $iterations = 1)
{
    while ($iterations-- >= 1)
    {
        $stack = 0;
        $number = str_split(strrev($number), 1);

        foreach ($number as $key => $value)
        {
            if ($key % 2 == 0)
            {
                $value = array_sum(str_split($value * 2, 1));
            }

            $stack += $value;
        }

        $stack %= 10;

        if ($stack != 0)
        {
            $stack -= 10;
        }

        $number = implode('', array_reverse($number)) . abs($stack);
    }

    return $number;
}

I dropped the $parity variable since we don’t need it for this purpose, and to verify:

function Luhn_Verify($number, $iterations = 1)
{
    $result = substr($number, 0, - $iterations);

    if (Luhn($result, $iterations) == $number)
    {
        return $result;
    }

    return false;
}
  • 1 1 Answer
  • 1 View
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-12T11:53:10+00:00Added an answer on May 12, 2026 at 11:53 am

    Edit: Sorry, I realize now that you had almost my entire answer already, you had just incorrectly determined which factor to use for which digit.

    My entire answer now can be summed up with this single sentence:

    You have the factor reversed, you’re multiplying the wrong digits by 2 depending on the length of the number.


    Take a look at the Wikipedia article on the Luhn algorithm.

    The reason your checksum is invalid half the time is that with your checks, half the time your number has an odd number of digits, and then you double the wrong digit.

    For 37283, when counting from the right, you get this sequence of numbers:

      3 * 1 =  3             3
      8 * 2 = 16 --> 1 + 6 = 7
      2 * 1 =  2             2
      7 * 2 = 14 --> 1 + 4 = 5
    + 3 * 1 =  3             3
    =                       20
    

    The algorithm requires you to sum the individual digits from the original number, and the individual digits of the product of those “every two digits from the right”.

    So from the right, you sum 3 + (1 + 6) + 2 + (1 + 4) + 3, which gives you 20.

    If the number you end up with ends with a zero, which 20 does, the number is valid.

    Now, your question hints at you wanting to know how to generate the checksum, well, that’s easy, do the following:

    1. Tack on an extra zero, so your number goes from xyxyxyxy to xyxyxyxy0
    2. Calculate the luhn checksum sum for the new number
    3. Take the sum, modulus 10, so you get a single digit from 0 to 10
    4. If the digit is 0, then congratulations, your checksum digit was a zero
    5. Otherwise, calculate 10-digit to get what you need for the last digit, instead of that zero

    Example: Number is 12345

    1. Tack on a zero: 123450
    2. Calculate the luhn checksum for 123450, which results in

      0   5    4    3    2    1
      1   2    1    2    1    2  <-- factor
      0   10   4    6    2    2  <-- product
      0  1 0   4    6    2    2  <-- sum these to: 0+1+0+4+6+2+2=15
      
    3. Take the sum (15), modulus 10, which gives you 5

    4. Digit (5), is not zero
    5. Calculate 10-5, which gives you 5, the last digit should be 5.

    So the result is 123455.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

There's lots of questions on SO related to this, but the ones I scanned
There are LOTS of iphone-related questions of this type. I know; I read them
There are a few questions that approach an answer to this question, but none
There are lots of Fluent implementations out there now that work with Lambdas to
There are lots of tutorials/instructions on how to embed python in an application, but
There are lots of questions on how to strip html tags, but not many
Lots of Prolog-in-Scheme implementations are out there. E.g. Kanren, Schelog. Apparently in Paradigms of
First of all, I'm sure there must be a simple solution to this but
While there are lots of different sophisticated implementations of malloc / free for C/C++,
There's lots of good material on Design Patterns out there that covers how you

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.