• P (unregistered)

TRWTF is it's a roundabout way of just writing

``````int result = certificateNumber.ToString().Sum(c => (c - '0') * 2);
``````

aka the typical tunnel vision noob coder syndrome

• Anon (unregistered)

TRWTF is adding digits of a positive number and somehow getting 0.

• (nodebb) in reply to Anon

@Anon You're the frist guy to see that additional WTF. Well, there is a solution: they use rather complex numbers, not necessarily positive ints only. What about number 7-38i53-42i?

• my name is missing (unregistered)

When I see people call toString() so many times instead of making a local string and calling it one time, its clear they have no idea how anything actually works.

• Andrew (unregistered)

"Easy Reader Version: I didn't learn that credit card numbers could be checksummed until college, and spent most of my teen years wondering why "just any random number" wasn't a common exploit. I was not a bright child."

Most people aren't aware of the Luhn formula, or any checksum at all, while clutching their Social Security numbers. All they know is that the computer said the number isn't right and try again.

• P (unregistered) in reply to BernieTheBernie

That's Remy's WTF. Common checksum algorithms do not "sum to 0", but "sum then modulo to 0". That's a rookie mistake there.

But a more blatant WTF is that they're trying to implement a borked version of Luhn algorithm. You multiply every other digit by 2 in Luhn algorithm before adding the digits of each result together because that prevents single-digit errors and adjacent digit swapping errors. Doing it as in the WTF does not protect against the latter (and would've been better just summing the digits, which'd give whatever monkey coding this a easier time).

• (nodebb)

@Anon is trolling us, right? Never heard of "casting out nines", which dates to the second century?

• Alloni (unregistered)

No, summing the digits to get 0 is still a reasonable checksum - it gives a nice large pool of valid numbers - 0, 00, 000000, 000000000000000000000, etc.

• JP (unregistered) in reply to Anon

That's not what is going on. They're adding positive numbers and expecting a sum that is divisible by 10.

• JP (unregistered) in reply to P

That's not true, since it will only work if all digits are between 0 and 4 (2n < 10).

The checksum digits map to (2*n % 9)

So you would get int result = certificateNumber.ToString().Sum(c => ((c - '0') * 2) % 9);

Just rolling with the wrong implementation of the Luhn rule, let's say you did have a cert number '1235' which when you double every digit adds up to 22, % 10 = 2... boy if only there was some way you could figure out what number would add up to 30 without trying them all, huh? But this guy obviously hadn't advanced to subtraction yet.

• (nodebb)

Given that this guy uses string to simulate a collection of integers, (which isn't even needed as far as I can tell) he should use strings in style - get him I'm touch with the makers of the StringManager.

• gnasher729 (unregistered)

The real WTF is that the place either has no code reviews, or this code passed a code review.

• markm (unregistered)

Are they hiring English majors to do programming? So many of these WTF's, including this one, are about someone who misuses strings because they do not understand integer arithmetic, and also can't figure out how to write "if(x >= 10)".

Converting an integer to a string to isolate the digits is sort of clever, but slow. (I would use %10 to get the lowest digit, then /10 to advance to the next digit, but that requires math beyond the 4th grade.) Borking the Luhn rule is just another little bit added to a steaming pile.

• D. Beckman (unregistered)

I could not find a better way than incrementing and re-checking the sum, but here is the simplified .NET code that produces the same values:

private static int CleanupV2(int value) { while (!IsValidV2(value)) { value ++; }

``````return value;
``````

}

private static bool IsValidV2(int value) { int sum = 0; int remainder = value;

``````while (remainder > 0)
{
var modifiedDigit = (remainder % 10) << 1;
sum += (modifiedDigit / 10) + modifiedDigit % 10;
remainder /= 10;
}

return sum % 10 == 0;
``````

}

When testing locally for the first 1,000,000 numbers, they produce the same values ... v1 took 12.9s where v2 took 1.0s. Surprisingly, not that great of a speed-up.

• I'm not a robot (unregistered) in reply to Ross_Presser
Never heard of "casting out nines"
Not the person you were replying to, but no, I have literally never heard of that. Based on the context I can guess what you might be talking about, but I'm fairly sure that that particular phrasing came directly from your nether regions.
• (nodebb) in reply to I'm not a robot

I'm fairly sure that that particular phrasing came directly from your nether regions.

Nah, I can vouch for it. Casting out nines is a thing.

• (nodebb) in reply to I'm not a robot

See, for example, https://www.google.com/search?q=%22casting+out+nines%22 I haven't seen or heard much of it lately, but back in ancient history when arithmetic was performed by humans it was a convenient way to checksum calculations.