- From: Steven Pemberton <steven.pemberton@cwi.nl>
- Date: Thu, 28 Aug 2025 16:53:05 +0000
- To: XForms <public-xformsusers@w3.org>, ixml <public-ixml@w3.org>
Here is a better version. The previous version worked from right to left, because the Luhn algorithm works from right to left, numbering the digits from the right. So to know whether you should double a digit, you need to know if it is odd or even numbered from the right. The new version however works from left to right. So how does it know if a digit is to be doubled or not? It doesn't. Instead, it does both, but a string that begins with a doubled digit has to have an even number of digits, so that it ends with a singled digit, and a string that starts with a singled digit has to have an odd number of digits, likewise. So "s0" matches an odd number of characters that add up to a multiple of 10 following the Luhn algorithm, and "d0" matches an even number of characters that match the Luhn algorithm. Here is the left to right version, this time announcing if a number matches the Luhn constraint or not (followed by an example of its output): {this version works from left to right} input: try++-#a, -#a. -try: good; bad. good: s0; d0. bad: ^s1; ^d1; ^s2; ^d2; ^s3; ^d3; ^s4; ^d4; ^s5; ^d5; ^s6; ^d6; ^s7; ^d7; ^s8; ^d8; ^s9; ^d9. -s0: "0", d0; "1", d1; "2", d2; "3", d3; "4", d4; "5", d5; "6", d6; "7", d7; "8", d8; "9", d9. -d0: "0", s0; "1", s2; "2", s4; "3", s6; "4", s8; "5", s1; "6", s3; "7", s5; "8", s7; "9", s9; . -s1: "0", d1; "1", d2; "2", d3; "3", d4; "4", d5; "5", d6; "6", d7; "7", d8; "8", d9; "9", d0. -d1: "0", s1; "1", s3; "2", s5; "3", s7; "4", s9; "5", s2; "6", s4; "7", s6; "8", s8; "9", s0. -s2: "0", d2; "1", d3; "2", d4; "3", d5; "4", d6; "5", d7; "6", d8; "7", d9; "8", d0; "9", d1. -d2: "0", s2; "1", s4; "2", s6; "3", s8; "4", s0; "5", s3; "6", s5; "7", s7; "8", s9; "9", s1. -s3: "0", d3; "1", d4; "2", d5; "3", d6; "4", d7; "5", d8; "6", d9; "7", d0; "8", d1; "9", d2. -d3: "0", s3; "1", s5; "2", s7; "3", s9; "4", s1; "5", s4; "6", s6; "7", s8; "8", s0; "9", s2. -s4: "0", d4; "1", d5; "2", d6; "3", d7; "4", d8; "5", d9; "6", d0; "7", d1; "8", d2; "9", d3. -d4: "0", s4; "1", s6; "2", s8; "3", s0; "4", s2; "5", s5; "6", s7; "7", s9; "8", s1; "9", s3. -s5: "0", d5; "1", d6; "2", d7; "3", d8; "4", d9; "5", d0; "6", d1; "7", d2; "8", d3; "9", d4. -d5: "0", s5; "1", s7; "2", s9; "3", s1; "4", s3; "5", s6; "6", s8; "7", s0; "8", s2; "9", s4. -s6: "0", d6; "1", d7; "2", d8; "3", d9; "4", d0; "5", d1; "6", d2; "7", d3; "8", d4; "9", d5. -d6: "0", s6; "1", s8; "2", s0; "3", s2; "4", s4; "5", s7; "6", s9; "7", s1; "8", s3; "9", s5. -s7: "0", d7; "1", d8; "2", d9; "3", d0; "4", d1; "5", d2; "6", d3; "7", d4; "8", d5; "9", d6. -d7: "0", s7; "1", s9; "2", s1; "3", s3; "4", s5; "5", s8; "6", s0; "7", s2; "8", s4; "9", s6. -s8: "0", d8; "1", d9; "2", d0; "3", d1; "4", d2; "5", d3; "6", d4; "7", d5; "8", d6; "9", d7. -d8: "0", s8; "1", s0; "2", s2; "3", s4; "4", s6; "5", s9; "6", s1; "7", s3; "8", s5; "9", s7. -s9: "0", d9; "1", d0; "2", d1; "3", d2; "4", d3; "5", d4; "6", d5; "7", d6; "8", d7; "9", d8. -d9: "0", s9; "1", s1; "2", s3; "3", s5; "4", s7; "5", s0; "6", s2; "7", s4; "8", s6; "9", s8. ====== <input> <bad> <d3>3141592653589793</d3> </bad> <good>3141592653589796</good> <bad> <d4>1414213562373095</d4> </bad> <good>1414213562373099</good> <bad> <s4>141421356237309</s4> </bad> <bad> <s4>14142135623730991</s4> </bad> <good>0</good> <good>00</good> <good>000</good> <bad> <s9>1</s9> </bad> <good>34</good> <good>133</good> <good>1330133</good> <good>01330133</good> </input> Steven
Received on Thursday, 28 August 2025 16:53:14 UTC