[Question]
  [
### Challenge
Write the shortest [program or function](https://codegolf.meta.stackexchange.com/a/2422/46231) to calculate the [Luhn Algorithm](http://enwp.org/Luhn_algorithm) for verifying (credit card) numbers.
### Luhn algorithm explained
[From RosettaCode](http://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers), this algorithm for the purposes of this challenge is specified as such, with the example input of `49927398716`:
```
Reverse the digits, make an array:
    6, 1, 7, 8, 9, 3, 7, 2, 9, 9, 4
Double the numbers in odd indexes:
    6, 2, 7, 16, 9, 6, 7, 4, 9, 18, 4
Sum the digits in each number:
    6, 2, 7, 7, 9, 6, 7, 4, 9, 9, 4
Sum all of the numbers:
    6 + 2 + 7 + 7 + 9 + 6 + 7 + 4 + 9 + 9 + 4 = 70
If the sum modulo 10 is 0, then the number is valid:
    70 % 10 = 0 => valid
```
### IO Rules
**Input**: A string or number (your choice), in your [language's input/output format of choice](https://codegolf.meta.stackexchange.com/q/2447)
**Output**: A [truthy or falsy value](https://codegolf.meta.stackexchange.com/q/2190/46231), respectively, indicating whether or not the input is valid according to the test above.
### Notes / Tips
* Try not to accidentally post your own credit card or account numbers, if you use them to test :)
* If the input is invalid and impossible to process **with the specified algorithm** (i.e, too short to work with), you can do whatever you want, including blow up my computer.
* **However**, the previous bullet does not mean that your language can do whatever it wants with Numbers that are too large for it to handle. If your language isn't capable of handling a test case, then consider taking a string as input.
### Examples
The following examples were validated with [this Python script](http://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers#Python); if you think one is wrong or have a question, just ping @cat.
```
49927398716      True
49927398717      False
1234567812345670 True    
1234567812345678 False
79927398710      False
79927398711      False
79927398712      False
79927398713      True
79927398714      False
79927398715      False
79927398716      False
79927398717      False
79927398718      False
79927398719      False
374652346956782346957823694857692364857368475368 True
374652346956782346957823694857692364857387456834 False
8 False **
0 True  **
```
\*\* according to the Python implementation, but you may do anything because these are too short to be eligible by a strict adherence to the specification.
---
If any of the above invalidates existing answers (though I believe that should not be possible), then those answers are stil valid. However, **new** answers, in order to be valid, should follow the specification above.
### Leaderboard
```
var QUESTION_ID=22,OVERRIDE_USER=73772;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
```
```
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
```
```
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>
```
  
[Answer]
## Golfscript - 24 chars
```
-1%{2+0!:0)*109%+}*10%8=
```
Explanation:
1. `-1%` reverses the string
2. `{` begins a block (which we use as a loop). Each character in the strings is pushed as it's ascii value.
	1. `2+` adds 2. (the ascii value of a digit is 48+n, so we have 50+n now and the last digit is n)
	2. `0!:0` inverts the value of 0 and stores it (everything is a variable), so we have 1 on the first iteration, 0 on the second, etc.
	3. `)*` adds one to this value and multiplies it, so we multiply by 2, then 1, then 2, etc.
	4. `109%` is remainder modulo 109. This affects only values 5-9 which have been doubled and reduces them to the correct value.
	5. `+` adds this value to the running sum
3. `}*` ends the block and does a 'fold' operation. First, the first character is pushed (since we have reversed, this is the check digit). Then, alternate pushing and executing the block. Thus, we are using the first character's ascii value as the starting value for the running sum.
4. `10%` takes the remainder modulo 10.
5. `8=` will return 1 if the value is 8. We use this because we did not normalize the first pushed character (the check digit).
One might think that we could use `8-` instead of `2+` to save a character by changing `109%` to `89%`, except then we would need to add a space so the `-` is subtraction (instead of `-0`).
[Answer]
## GolfScript, 44 chars
```
-1%{16%}%2/1,\+{(\.{0=2*.9>9*-+}{;}if+}*10%!
```
---
**Selected commentary**
Interestingly, the first two items below demonstrate three completely different uses of the `%` operator: array selection, map, and mod. Most GolfScript operators are "context-sensitive", giving them hugely divergent behaviours depending on what types the arguments are.
1. `-1%` reverses the string. This is important as the digit pairs are counted from the right.
2. `{16%}%` converts all the ASCII digits into numbers, by modding them with 16.
3. `2/` splits the array into groups of 2.
4. `1,` is a cheap way to do `[0]`.
5. `\+` effectively prepends the 0 to the digits array. It does this by swapping then concatenating.
The 0 is prepended in preparation for the fold that comes in next. Rather than taking an explicit initial value, GolfScript's fold uses the first item in the array as the initial value.
Now, let's look at the actual fold function. This function takes two arguments: the folded value, and the current item on the array (which in this case will be an array of 2 or (uncommonly) 1, because of the `2/` earlier). Let's assume the arguments are `1 [2 3]`.
1. `(\.` splits out the leftmost array element, moves the remaining array to the front, then copies it. Stack now looks like: `1 2 [3] [3]`.
2. The `if` checks if the array is empty (which is the case for the last group when dealing with an odd-sized account number). If so, then no special processing happens (just pop off the empty array).
3. For an even group:
	1. `0=` grabs the first (only, in this case) element of the array. `1 2 3`
	2. `2*` doubles the number. `1 2 6`
	3. `.9>9*-` subtracts 9 from the number if it's greater than 9. Implemented as: copy the number, compare with 9, multiply the result (which is either 0 or 1) with 9, then subtract. `1 2 6`
	4. `+` finally adds that to the first number. `1 8`
4. `+` (after the `if`) adds the result of the `if` to the original value, resulting in the new folded value.
After the folding completes, we simply mod with 10 (`10%`), and negate the result (`!`), so that we return 1 iff the sum is a multiple of 10.
[Answer]
## Python, 73 69 characters
```
def P(x):D=map(int,x);return sum(D+[d-d/5*9for d in D[-2::-2]])%10==0
```
[Answer]
# Python 3, 77 bytes
```
c=lambda a:sum(sum(divmod(int(a[-e-1])<<e%2,10))for e in range(len(a)))%10==0
```
[Answer]
**C# 119 characters:**
```
bool l(string n){return(String.Join("",n.Reverse().Select((x,i)=>(x-48)*(i%2<1?1:2)+"").ToArray()).Sum(x=>x-48))%10<1;}
```
Not *too* bad for a code golf n00b in a statically typed language, I hope.
This can be reduced to **100**:
```
bool l(string n){return String.Join("",n.Reverse().Select((x,i)=>(x-48)*(i%2+1))).Sum(x=>x+2)%10<1;}
```
[Answer]
## Golfscript - 34 chars
```
{15&}%.-2%\);-2%{.+(9%)}%+{+}*10%!
```
Example number from wikipedia page 4992739871
```
{15&}%  does a bitwise and of each ascii digit with 00001111
        now I have a list of digits 
        [4 9 9 2 7 3 9 8 7 1 6]
.       makes a copy of the list, now I have two identical lists
        [4 9 9 2 7 3 9 8 7 1 6] [4 9 9 2 7 3 9 8 7 1 6]
-2%     like [::-2] in python takes every second element in reverse
        [4 9 9 2 7 3 9 8 7 1 6] [6 7 9 7 9 4]
\       swap the two lists around
        [6 7 9 7 9 4] [4 9 9 2 7 3 9 8 7 1 6]
);      drop the last digit off the list
        [6 7 9 7 9 4] [4 9 9 2 7 3 9 8 7 1]
-2%     same as before
        [6 7 9 7 9 4] [1 8 3 2 9]
{       for each item in the list ...
.+      ... double it ...
(       ... subtract 1 ...
9%      ... mod 9 ...
)}%     ... add 1 ...
        [6 7 9 7 9 4] [2 7 6 4 9]
+       join the two lists
        [6 7 9 7 9 4 2 7 6 4 9]
{+}*    add the elements up
        70
10%     mod 10
        0
!       invert the result
        1
```
[Answer]
# PHP, 108 bytes
```
<?function v($s,$t=0){for($i=strlen($s);$i>=0;$i--,$c=$s[$i])$t+=$c+$i%2*(($c>4)*-4+$c%5);return!($t % 10);}
```
[Answer]
## Ruby - 85 characters
```
def f s
l=s.size
s.chars.map{|k|(i=k.to_i*((l-=1)%2+1))%10+i/10}.inject(:+)%10==0
end
```
[Answer]
# Haskell, 96 bytes
There must be a better/shorter way, but here's my **Haskell** solution in **96 characters**:
```
l=(==0).(`mod`10).sum.zipWith($)(cycle[id,\x->x`mod`5*2+x`div`5]).reverse.map((+(-48)).fromEnum)
```
Sadly the `digitToInt` function can only be used if you `import Data.Char` first. Otherwise I could get down to 88 characters by replacing `((+(-48)).fromEnum)` with  `digitToInt`.
[Answer]
## Windows PowerShell, 82
```
filter f{!((''+($_[($_.length)..0]|%{+"$_"*($i++%2+1)})-replace'.','+$&'|iex)%10)}
```
History:
* 2011-02-13 03:08 (84) First attempt.
* 2011-02-13 12:13 (82) I don't need to join, as spaces do not hurt. `+1 + +3` can still be evaluated.
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~12~~ ~~11~~ 9 bytes
```
ṚḤÐeDFS⁵ḍ
```
[Try it online!](https://tio.run/##y0rNyan8///hzlkPdyw5PCHVxS34UePWhzt6/x9uf7i7@1HDnJCi0lQg5ZaYUwyk5x7a@qhpTeT//9EmlpZG5saWFuaGZjoKCI65joKhkbGJqZm5BZQ2wBCx0FEwh2swQOYYInOMkDnGyBwTZI4pMscMmWOOzEGx1FJHwdjcxMwU6B4zS5CLIAwQbWZpYmFqbmYJZIEYxmYWJuamQJJ4HRbmQE9aGAMdCdRkEAsA "Jelly – Try It Online")
## How it works
```
ṚḤÐeDFS⁵ḍ - Main link. Takes an integer n on the left
Ṛ         - Cast n to digits and reverse
  Ðe      - To values at even indices:
 Ḥ        -   Unhalve; Double
    D     - Cast to digits
     F    - Flatten
      S   - Sum
        ḍ - Divisible by:
       ⁵  - 10?
```
[Answer]
# Q, 63
```
{0=mod[(+/)"I"$(,/)($)($)@["I"$'x;1+2*'(!)(_)((#)x)%2;*;2];10]}
```
usage
```
q){0=mod[(+/)"I"$(,/)($)($)@["I"$'x;1+2*'(!)(_)((#)x)%2;*;2];10]}"79927398711"
0b
q){0=mod[(+/)"I"$(,/)($)($)@["I"$'x;1+2*'(!)(_)((#)x)%2;*;2];10]}"79927398712"
0b
q){0=mod[(+/)"I"$(,/)($)($)@["I"$'x;1+2*'(!)(_)((#)x)%2;*;2];10]}"79927398713"
1b
```
[Answer]
# D, 144 bytes
```
bool f(S)(S s){int t(C)(C c){return to!int(c)-'0';}int n,v;foreach(i,c;array(retro(s))){v=i&1?t(c)*2:t(c);n+=v>=10?v%10+v/10:v;}return n%10==0;}
```
More legibly:
```
bool f(S)(S s)
{
    int t(C)(C c)
    {
        return to!int(c) - '0';
    }
    int n, v;
    foreach(i, c; array(retro(s)))
    {
        v = i & 1 ? t(c) * 2 : t(c);
        n += v >= 10 ? v % 10 + v / 10 : v;
    }
    return n % 10 == 0;
}
```
[Answer]
# APL, 28 [bytes](https://en.wikipedia.org/wiki/APL_(codepage))
```
{0=10|+/⍎¨∊⍕¨v×⌽2-2|⍳⍴v←⍎¨⍵}
```
**Exploded view**
```
{                     v←⍎¨⍵}  ⍝ turn the string into a numeric vector of its digits, v
                2-2|⍳⍴v       ⍝ make a vector of the same length, with 2 in every 2nd place
             v×⌽              ⍝ multiply it with v, starting from the right
          ∊⍕¨                 ⍝ turn each component into a string and collect all the digits
      +/⍎¨                    ⍝ turn each digit again into a number and sum them
 0=10|                        ⍝ check whether the sum is a multiple of 10
```
**Examples**
```
      {0=10|+/⍎¨∊⍕¨v×⌽2-2|⍳⍴v←⍎¨⍵} '79927398713'
1
      {0=10|+/⍎¨∊⍕¨v×⌽2-2|⍳⍴v←⍎¨⍵} '123456789'
0
```
[Answer]
# [x86-16 machine code](https://software.intel.com/sites/default/files/managed/39/c5/325462-sdm-vol-1-2abcd-3abcd.pdf), 27 bytes
Binary:
```
00000000: bb00 0103 f1fd ac2c 30f6 df78 06d0 e0d4  .......,0..x....
00000010: 0a02 dc02 d8e2 ef93 d40a c3              ...........
```
Listing:
```
BB 0100         MOV  BX, 100H           ; running sum (BL) to 0, BH to a positive value
03 F1           ADD  SI, CX             ; start at end of input string
FD              STD                     ; set LODSB direction to decrement
            DIGIT_LOOP: 
AC              LODSB                   ; load next digit into AL, decrement SI
2C 30           SUB  AL, '0'            ; convert ASCII char to binary value 
F6 DF           NEG  BH                 ; flip sign of BH to alternate odd/even index
78 06           JS   IS_EVEN            ; if not odd index, do not double
D0 E0           SHL  AL, 1              ; double the value
D4 0A           AAM                     ; split digits (ex: 18 --> AH = 1, AL = 8) 
02 DC           ADD  BL, AH             ; add tens digit to running sum
            IS_EVEN:
02 D8           ADD  BL, AL             ; add ones digit to running sum 
E2 EF           LOOP DIGIT_LOOP 
93              XCHG AX, BX             ; sum is in BL, move to AL for mod 10 check
D4 0A           AAM                     ; ZF = ( AL % 10 == 0 ) 
C3              RET                     ; return to caller
```
Uses (abuses) x86's BCD-to-binary instruction `AAM` to handle the individual digit splitting and `modulo 10` check.
Callable function, input card num string pointer in `SI`, length in `CX`. Output: `ZF` if valid.
**Example test program output:**
[![enter image description here](https://i.stack.imgur.com/vOgkr.png)](https://i.stack.imgur.com/vOgkr.png)
## Alternate version, 29 bytes
```
33 DB           XOR  BX, BX             ; running sum (BL) to 0
03 F1           ADD  SI, CX             ; start at end of string
4E              DEC  SI                 ; align for WORD
FD              STD                     ; set LODSB direction to decrement
            DIGIT_LOOP:
AD              LODSW                   ; load next two digits into AH:AL, dec SI by 2
25 0F0F         AND  AX, 0F0FH          ; convert ASCII chars to binary value
02 DC           ADD  BL, AH             ; add ones digit of even index to sum
49              DEC  CX                 ; decrement counter for WORD
74 0A           JZ   DONE               ; if input is odd length, will be 0 at the end
D0 E0           SHL  AL, 1              ; double the value
D4 0A           AAM                     ; split digits (ex: 18 --> AH = 1, AL = 8)
02 DC           ADD  BL, AH             ; add tens digit to sum
02 D8           ADD  BL, AL             ; add ones digit to sum
E2 ED           LOOP DIGIT_LOOP
            DONE:
93              XCHG AX, BX             ; move sum to AL for mod 10 check
D4 0A           AAM                     ; ZF = ( AL % 10 == 0 )
C3              RET                     ; return to caller
```
This version loads two digits at the same time, eliminating the flip/flop branch. The issue here is having to check for an odd number of digits on the input and discard the value in memory right before the beginning of the string once it reaches the last word. Obviously not shorter, but perhaps someone clever can golf it more!
[Answer]
## PowerShell 123
```
filter L($x){$l=$x.Length-1;$l..0|%{$d=$x[$_]-48;if($_%2-eq$l%2){$s+=$d}elseif($d-le4){$s+=$d*2}else{$s+=$d*2-9}};!($s%10)}
```
[Answer]
# Perl, ~~46~~ ~~42~~ 41 bytes
Includes +1 for `-p`
Give input on STDIN:
```
luhn.pl <<< 79927398713
```
`luhn.pl`:
```
#!/usr/bin/perl -p
s%.%$=-=-$&-$&*1.2*/\G(..)+$/%eg;$_=/0$/
```
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), ~~12~~ 10 bytes
```
RSāÈ>*SOTÖ
```
[Try it online!](https://tio.run/##yy9OTMpM/f8/KPhI4@EOO61g/5DD0/7/N7G0NDI3trQwNzQDAA "05AB1E – Try It Online")
or as a [Test Suite](https://tio.run/##jc87CgJBDADQPqdYthSF@WTyaXaPILheQMHCykIQFmy28wReaL3XOIOiwcomeYSEJKfzbn885Otl7Ntm1TVtP@bN8JjmW7cY1tv5npcZVQNHFfYEXzP4EDERyzu734IAf7qdsTcOxtEYjZMxGbOx3aUQGSmVI0jrGS/UTIqSmLSoIpIgpxL/HhAuj0lEEHBP)
**Explanation**
```
R             # reverse input
 S            # split to list of digits
  ā           # push range[1 ... len(input)]
   È          # map isEven on each
    >         # increment
     *        # multiply doubling every other item
      SO      # sum digits
        TÖ    # mod 10 == 0
```
[Answer]
# Powershell, 74 bytes
```
param($s)$s[$s.Length..0]|%{(1+$i++%2)*"$_"}|%{$r+=$_-9*($_-gt9)}
!($r%10)
```
## Explanation
1. for each char of an argument string, in reverse order
2. get a digit of double value of a digit
3. a double value of a digit can not be greater then 18. Therefore, we accumulate a value minus 9 if value > 9
4. return true if the remainder of the division by 10 is 0
## Test script
```
$f = {
param($s)$s[$s.Length..0]|%{(1+$i++%2)*"$_"}|%{$r+=$_-9*($_-gt9)}
!($r%10)
}
@(
    ,("49927398716"      , $True)
    ,("49927398717"      , $False)
    ,("1234567812345670" , $True)
    ,("1234567812345678" , $False)
    ,("79927398710"      , $False)
    ,("79927398711"      , $False)
    ,("79927398712"      , $False)
    ,("79927398713"      , $True)
    ,("79927398714"      , $False)
    ,("79927398715"      , $False)
    ,("79927398716"      , $False)
    ,("79927398717"      , $False)
    ,("79927398718"      , $False)
    ,("79927398719"      , $False)
    ,("374652346956782346957823694857692364857368475368" , $True)
    ,("374652346956782346957823694857692364857387456834" , $False)
    ,("8" , $False)
    ,("0" , $True)
) | % {
    $s, $expected = $_
    $result = &$f $s
    "$($result-eq$expected): $result : $s"
}
```
## Output
```
True: True : 49927398716
True: False : 49927398717
True: True : 1234567812345670
True: False : 1234567812345678
True: False : 79927398710
True: False : 79927398711
True: False : 79927398712
True: True : 79927398713
True: False : 79927398714
True: False : 79927398715
True: False : 79927398716
True: False : 79927398717
True: False : 79927398718
True: False : 79927398719
True: True : 374652346956782346957823694857692364857368475368
True: False : 374652346956782346957823694857692364857387456834
True: False : 8
True: True : 0
```
[Answer]
# [GolfScript](http://www.golfscript.com/golfscript/), 31 bytes
```
.,2%0\@{48-..4>+@!:a*++a}/;10%!
```
[Try it online!](https://tio.run/##S8/PSStOLsosKPn/X0/HSNUgxqHaxEJXT8/ETttB0SpRS1s7sVbf2tBAVfH/f0MjYxNTM3MLKG0AAA "GolfScript – Try It Online")
Golfscript pushes the input as a list of characters to the stack
at the start of the program.
```
.                                Duplicate the top of the stack (input)
 ,2%                             Compute the modulo 2 of the length of the input,
                                 pushed 1/0 on the stack if the number if odd/even
    0                            Push an accumulater var on the stack, set to 0
    
     \                           Flip the even/odd and accumulator order on the stack
      @                          Bring the 3rd entry forward, input to the top
       {                }        Code block...
                         /       Apply the block of code to the elements of the list at
                                 the top of the stack. Each time through the loop, the
                                 next element from the list if pushed to the top of the
                                 stack
        48-                      Subtract "0" from the top of stack (which is a codepoint
                                 for the current digit/character)
           ..                    Duplicate the top of stack (the current digit) twice
             4>+                 If the current digit is >4 add one to the digit
                @                Pull the 3rd entry, the even/odd indicator, to the top
                 !:a             Flip the value and save in variable "a"
                    *            Multiple the top two stack entries, will be "0" or the
                                 value of current digit, with or without "1" more for the
                                 "+10" rule
                     ++          Add the current digit, to the possible "double" and
                                 "even/odd" bump
                       a         Push the flipped even/odd indicated to the top
                          ;      Drop the stop of stack, the even/odd indicator 
                           10%   Find the modulo 10 of the accumulated digits
                              !  Invert the result
```
The only thing on the stack is the answer, which is printed by default
[Answer]
# [C (clang)](http://clang.llvm.org/), ~~264~~ ~~212~~ ~~196~~ ~~175~~ 172 bytes
```
l,x;main(i){char*s;gets(s);int n[i=l=strlen(s)];for(;i--;)n[i]=s[i]-48;for(;(i+=2)<l;n[i]>9?n[i]=n[i]/10+n[i]%10:0)n[i]*=2;for(;l--;)x+=n[l];printf(x%10<1?"True":"False");}
```
[Try it online!](https://tio.run/##XY7BCoJAEIbvPUUYwa5mqUlp49atJ@gWHjZdbWBawzUQome3tU51mYHv//5hCr8gqethhrqgR6mmmelKbJbX/eQHEV7@WYu6tmygRQ83iZohfxZX2boGatUZZjig7qb6jIKE1Ulpy3KompYB@j5wG@XC2OHHyRcz9ETEM4Ix2qeHjzGOVRh4456HwS74FF0RfTs0nuo9q1EOd/tVV7Heell4cE7tQzk75yjJKIfDaxjiNI226zTZhps3 "C (clang) – Try It Online")
Simply the basic way of programming the algorithm, but all whitespace is removed. All I could say is that there are a bunch of for-loops in this one.
Thanks to ceilingcat for golfing 52 bytes, another 16 bytes, and another 21 bytes, and another 3 bytes.
[Answer]
# JavaScript (ES6), 61 bytes
Sum of digits of `2*n` is `2*n` if `n in 0..4`, `2*n-9` if `n in 5..9`. That said, all the sum can be computed in one step.
```
s=>!([...s].reduceRight((t,d)=>t-d-i++%2*(d>4?d-9:d),i=0)%10)
```
[Answer]
# [K (ngn/k)](https://bitbucket.org/ngn/k), 26 bytes
```
{~10!+//10\(1+2!!#x)*.'|x}
```
[Try it online!](https://tio.run/##lY@7DsIwDEV3voKaoS0VNE8/4FeYy4DUuVKBXw8JIMDqxBLf48TXN5fdeB5TGg7z3Zqq63trTo3tXFVtpna7r6/TLQ11A0HEkRcmi3D8IcpknQ8Rid/VLFsM7aq40GeuPPqSVeQUeUVh4RTVPSoiRaxIitMaPAWMOSVKyfkSpaIEjoSSVREeOVDMJ/wzxJR/zz7AM3PZb6BNDw "K (ngn/k) – Try It Online")
Another k variant, with a major debt to [@streetster's answer](https://codegolf.stackexchange.com/a/154051/98547).
[Answer]
# [Factor](https://factorcode.org/) + `validators`, 5 bytes
```
luhn?
```
[Try it online!](https://tio.run/##jc/NCsIwDADge58iTyDb2iatHjyKFy/iSTyUOXEw5346h4jPXjsUCZ68JB8hIcnJ5f7ahd12vVnNoekK7@9NV9Ye2hH6oh2KOi96uLmqPLrY2cNCtONDKGszktZQiswk0kwqjWQ@OfktGEHf7oQ5Zc6YJbNi1szITMx8lxWSFOp4BNrpjDemjFYZTWijJkg0inSMfw8Yio8ZqYQRiXjCPlTDuV6GA1xcA7PwAg "Factor – Try It Online")
[Answer]
### Scala: 132
```
def q(x:Int)=x%10+x/10
def c(i:String)={val s=i.reverse
(s(0)-48)==10-(s.tail.sliding(2,2).map(n=>(q((n(0)-48)*2)+n(1)-48)).sum%10)}
```
invocation:
```
c("79927398713")
```
* reverse ("79927398713") = 31789372997
* s(0), s.tail: (3)(1789372997)
* sliding (2,2) = (17 89 37 29 97)
* map (q((n(0)-48\*2 + n(1)-48)) => q(('1'-'0')\*2)+ '7'-'0')=1\*2+7
[Answer]
## JavaScript 1.8: 106 characters
This is an original solution I came up with before I found this post:
```
function(n){return!(n.split('').reverse().reduce(function(p,c,i){return(+c&&((c*(1+i%2)%9)||9))+p},0)%10)}
```
Readable form:
```
function luhnCheck(ccNum) {
    return !(                                  // True if the result is zero.
             ccNum.split('').
               reverse().                      // Iterate over the string from rtl.
               reduce(function(prev, cur, idx) {
                 return prev +                 // Sum the results of each character.
                        (+cur &&               // If the current digit is 0, move on.
                         ((cur * (1 + idx % 2) // Double cur at even indices.
                           % 9) || 9));        // Sum the digits of the result.
               }, 0)
            % 10);                             // Is the sum evenly divisible by 10?
}
```
[Answer]
# K4, 35 bytes
```
{~.*|$+/.:',/$x*1+1{y;~x}\|x:|.:'x}
```
[Answer]
## [Retina](https://github.com/mbuettner/retina), ~~43~~ 42 bytes
Retina is (much) newer than this challenge.
```
;
r`(.);.
$1$&
\d
$*
1+
$.&
.
$*
$
$._
0$
```
The leading empty line is significant.
Prints `0` for falsy and `1` for truthy results.
[Try it online!](http://retina.tryitonline.net/#code=JShHYAoKOwpyYCguKTsuCiQxJCYKXGQKJCoKMSsKJC4mCi4KJCoKJAokLl8KTWAwJAopR2A&input=NDk5MjczOTg3MTYKMTIzNDU2NzgxMjM0NTY3MAo3OTkyNzM5ODcxMwozNzQ2NTIzNDY5NTY3ODIzNDY5NTc4MjM2OTQ4NTc2OTIzNjQ4NTczNjg0NzUzNjgKMAoKNDk5MjczOTg3MTcKMTIzNDU2NzgxMjM0NTY3OAo3OTkyNzM5ODcxMAo3OTkyNzM5ODcxMQo3OTkyNzM5ODcxMgo3OTkyNzM5ODcxNAo3OTkyNzM5ODcxNQo3OTkyNzM5ODcxNgo3OTkyNzM5ODcxNwo3OTkyNzM5ODcxOAo3OTkyNzM5ODcxOQozNzQ2NTIzNDY5NTY3ODIzNDY5NTc4MjM2OTQ4NTc2OTIzNjQ4NTczODc0NTY4MzQKOA) (Slightly modified to run all test cases at once.)
### Explanation
```
;
```
Insert `;` in every position to separate digits.
```
r`(.);.
$1$&
```
From the `r`ight, we repeatedly match two digits and double the left one. This way we avoid an expensive reversing of the list.
```
\d
$*
```
We match each digit and convert it to that many `1`s (that is, we convert each digit to unary).
```
1+
$.&
```
This matches each unary number and converts it back to decimal by replacing it with its length. Together with the previous stage, this adds the doubled digits.
```
.
$*
```
Again, we match every character and turn it into that many `1`s. That is we convert each digit individually back to unary. This also matches the `;` separators, which are treated as zeros in the conversion, which means they're simply removed. Since all the unary numbers are now squashed together we've automatically added the unary representations of the all digits together.
```
$
$._
```
At the end, we insert the length of the entire string, i.e. the decimal representation of the unary checksum.
```
0$
```
Finally we count the number of matches of this regex, i.e. we check whether the decimal representation ends in `0`, printing `0` or `1` accordingly.
[Answer]
# [Japt](https://github.com/ETHproductions/japt), ~~14~~ 13 bytes
Takes input as an array of digits.
```
ÔxÈ*ÒYu)ìxÃvA
```
[Try it](https://petershaggynoble.github.io/Japt-Interpreter/?v=1.4.6&code=1HjIKtJZdSnseMN2QQ==&input=WzQsOSw5LDIsNywzLDksOCw3LDEsNl0KLaE=)
```
ÔxÈ*ÒYu)ìxÃvA     :Implicit input of array
Ô                 :Reverse
 x                :Reduce by addition
  È               :After passing each element at 0-based index Y through the following function
   *              :   Multiply by
    Ò             :     Bitwise increment
     Yu           :     Y modulo 2
       )          :   End multiplication
        ì         :   Convert to digit array
         x        :   Reduce by addition
          Ã       :End function
           v      :Test for divisibility by
            A     :  10
```
[Answer]
# [Vyxal](https://github.com/Lyxal/Vyxal), ~~12~~ 11 bytes
*-1 byte thanks to @lyxal reminding me about multibyte lambdas.*
```
ṘÞTf‡d∑ẇ∑₀Ḋ
```
[Try it Online!](http://lyxal.pythonanywhere.com?flags=&code=%E1%B9%98%C3%9ETf%E2%80%A1d%E2%88%91%E1%BA%87%E2%88%91%E2%82%80%E1%B8%8A&inputs=1234567812345678&header=&footer=)
Explanation:
```
             # Implicit input
Ṙ            # Reverse
 ÞT          # Transpose
   f         # Flatten list
    ‡  ẇ     # For every second element:
     d       #   Double
      ∑      #   Sum digits
        ∑    # Sum all elements
         ₀Ḋ  # x % 10 == 0?
             # Implicit output
```
]