# C problems validating a credit card

The Luhn test is used by some credit card companies to distinguish valid credit card numbers from what could be a random selection of digits. Those companies using credit card numbers that can be validated by the Luhn test have numbers that pass the following test: Reverse the digits: 61789372994 Sum the odd digits: 6 7 9 7 9 4 = 42 = s1 The even digits: 1, 8, 3, 2, 9 Two times each even digit: 2, 16, 6, 4, 18 Sum the digits of each multiplication: 2, 7, 6, 4, 9 Sum the last: 2 7 6 4 9 = 28 = s2 s1 s2 = 70 which ends in zero which means that 49927398716 passes the Luhn test* Luhn test of credit card numbers 22/05/2016LUHNTEST CSECT USING LUHNTEST, R13 base register B 72(R15) skip savearea DC 17F'0' savearea STM R14, R12,12(R13) prolog ST R13,4(R15) " ST R15,8(R13) " LR R13, R15 " LA R9, T @t(k) LA R8, N for n LOOPK EQU * for k=1 to n LR R4, R9 @t(k),@s[1] LA R6,1 from i=1 LA R7, M to m LOOPI1 CR R6, R7 for i=1 to m BH ELOOPI1 leave i CLI 0(R4), C' ' if mid(s,i,1)=" " BNE ITERI1 then BCTR R6,0 i-1 ST R6, L l=i-1 B ELOOPI1 exit for* end if ITERI1 LA R4,1(R4) next @s[i] LA R6,1(R6) i=i 1 B LOOPI1 next i ELOOPI1 EQU * out of loop i MVC W, BLANK w=" " LA R4, W [email protected] LR R5, R9 [email protected] A R5, L [email protected] l BCTR R5,0 is=s l-1 L R6, L i=l LA R7,1 to 1LOOPI2 CR R6, R7 for i=l to 1 by -1 BL ELOOPI2 leave i MVC 0(1, R4),0(R5) mid(w,iw,1)=mid(s,is,1) LA R4,1(R4) iw=iw 1 BCTR R5,0 is=is-1 BCTR R6,0 i=i-1 B LOOPI2 next i ELOOPI2 EQU * out of loop i LA R11,0 s1=0 LA R12,0 s2=0 LA R6,1 i=1 L R7, L to l LOOPI3 CR R6, R7 for i=1 to l BH ELOOPI3 leave i LA R2, W-1 @w-1 AR R2, R6 w[i] MVC CI,0(R2) ci=mid(w,i,1) NI CI, X'0F' zap upper half byte LR R4, R6 i SRDA R4,32 0 BNH NOTMOD then XR R2, R2 clear IC R2, CI z=cint(mid(w,i,1)) AR R11, R2 s1=s1 cint(mid(w,i,1)) B EIFMOD else NOTMOD XR R2, R2 clear IC R2, CI cint(mid(w,i,1)) SLA R2,1 *2 ST R2, Z z=cint(mid(w,i,1))*2 C R2,=F'10' if z \ Adapted from the C version:: remap \ n1 -- n2 [0,2,4,6,8,1,3,5,7,9] swap caseof ; : luhn \ s -- f 0 swap s:rev ( '0 n:- swap 2 n:mod if remap then n: ) s:each 10 n:mod not ; : test-luhn \ s -- dup . cr ; "49927398716" test-luhn"49927398717" test-luhn "1234567812345678" test-luhn"1234567812345670" test-luhn bye% returns true if cc Number passes the Luhn test, false otherwise %% as Algol W has fixed length strings, the length of the number %% must be specified in cc Length %logical procedure Luhn Test ( string(32) value cc Number ; integer value cc Length ) ;begin integer check Sum; logical odd Digit, is Valid; check Sum := 0; is Valid := odd Digit := true; for c Pos := cc Length step -1 until 1 do begin integer digit; digit := decode( cc Number( c Pos - 1 // 1 ) ) - decode( "0" ); if digit 9 then is Valid := false else if odd Digit then check Sum := check Sum digit else check Sum := check Sum ( case digit 1 of ( 0, 2, 4, 6, 8 , 1, 3, 5, 7, 9 ) ); odd Digit := not odd Digit end for_c Pos ; is Valid and ( ( check Sum rem 10 ) = 0 )end Luhn Testbegin % external procedure that returns true if cc Number passes the Luhn test, false otherwise % logical procedure Luhn Test ( string(32) value cc Number ; integer value cc Length ) ; algol "LUHN" ; % task test cases % procedure test Luhn Test ( string(32) value cc Number ; integer value cc Length ) ; write( s_w := 0, cc Number, if Luhn Test( cc Number, cc Length ) then " is valid" else " is invalid" ); test Luhn Test( "49927398716", 11 ); test Luhn Test( "49927398717", 11 ); test Luhn Test( "1234567812345678", 16 ); test Luhn Test( "1234567812345670", 16 ) end.global _start_start: ldr r0, =example_numbers bl test_number add r1, r0, #1 bl length add r0, r1, r0 bl test_number add r1, r0, #1 bl length add r0, r1, r0 bl test_number add r1, r0, #1 bl length add r0, r1, r0 bl test_number mov r0, #0 mov r7, #1 swi 0 test_number: push bl print_string bl luhn_test cmp r0, #1 ldreq r0, =valid_message ldrne r0, =invalid_message bl print_string pop mov pc, lr print_string: push mov r1, r0 @ string to print bl length mov r2, r0 @ length of string mov r0, #1 @ write to stdout mov r7, #4 @ SYS_WRITE swi 0 @ call system interupt pop mov pc, lr @ r0 address of credit card number [email protected] returns result in r0luhn_test: push mov r1, r0 bl is Numerical @ check if string is a number cmp r0, #1 bne .luhn_test_end @ exit if not number mov r0, r1 ldr r1, =reversed_string @ address to store reversed string bl reverse @ reverse string push bl length @ get length of string mov r4, r0 @ store string length in r4 pop mov r2, #0 @ string index mov r6, #0 @ sum of odd digits mov r7, #0 @ sum of even digits Next: ldrb r3, [r1, r2] @ load byte into r3 sub r3, #'0' @ convert letter to digit and r5, r2, #1 @ test if index is even or odd cmp r5, #0 beq .odd_digit bne .even_digit .odd_digit: add r6, r3 @ add digit to sum if odd b .continue @ skip next step .even_digit: lsl r3, #1 @ multiply digit by 2 cmp r3, #10 @ sum digits subge r3, #10 @ get digit in 1s place addge r3, #1 @ add 1 for the 10s place add r7, r3 @ add digit sum to the total .continue: add r2, #1 @ increment digit index cmp r2, r4 @ check if at end of string blt Next add r0, r6, r7 @ add even and odd sum mov r3, r0 @ copy sum to r3 ldr r1, =429496730 @ (2^32-1)/10 sub r0, r0, r0, lsr #30 @ divide by 10 umull r2, r0, r1, r0 mov r1, #10 mul r0, r1 @ multiply the r0 by 10 to see if divisible cmp r0, r3 @ compare with the original value in r3 .luhn_test_end: movne r0, #0 @ return false if invalid card number moveq r0, #1 @ return true if valid card number pop mov pc, lr length: push mov r2, r0 @ start of string address .loop: ldrb r1, [r2], #1 @ load byte from address r2 and increment cmp r1, #0 @ check for end of string bne @ load next byte if not 0 sub r0, r2, r0 @ subtract end of string address from start sub r0, #1 @ end of line from count pop mov pc, lr @ reverses a [email protected] r0 address of string to [email protected] r1 address to store reversed stringreverse: push push bl length @ get length of string to reverse mov r3, r0 @ backword index pop mov r4, #0 @ fowrard index .reverse_next: sub r3, #1 @ decrement backword index ldrb r5, [r0, r3] @ load byte from original string at index strb r5, [r1, r4] @ copy byte to reversed string add r4, #1 @ increment fowrard index cmp r3, #0 @ check if any characters are left bge .reverse_next mov r5, #0 strb r5, [r1, r4] @ write null byte to terminate reversed string pop mov pc, lr is Numerical: push Numerical_check Next: ldrb r1, [r0], #1 cmp r1, #0 beq Numerical_true cmp r1, #'0' blt Numerical_false cmp r1, #'9' bgt Numerical_false b Numerical_check Next Numerical_false: mov r0, #0 b Numerical_end Numerical_true: mov r0, #1 Numerical_end: pop mov pc, lr .datavalid_message: .asciz " valid card number\n"invalid_message: .asciz " invalid card number\n" reversed_string: .space 32 example_numbers: .asciz "49927398716" .asciz "49927398717" .asciz "1234567812345678" .asciz "1234567812345670" FOR card% = 1 TO 4 READ cardnumber$ IF FNluhn(cardnumber$) THEN PRINT "Card number " cardnumber$ " is valid" ELSE PRINT "Card number " cardnumber$ " is invalid" ENDIF NEXT card% END DATA 49927398716, 49927398717, 1234567812345678, 1234567812345670 DEF FNluhn(card$) LOCAL I%, L%, N%, S% L% = LEN(card$) FOR I% = 1 TO L% N% = VAL(MID$(card$, L%-I% 1, 1)) IF I% AND 1 THEN S% = N% ELSE N% *= 2 S% = N% MOD 10 N% DIV 10 ENDIF NEXT = (S% MOD 10) = 0 The labelled points (1 to 11) are: 1. Augment(,get_RGB:function(t),get_gray:function(t),get_named:function(t),padding:function()}, Math Jax.

MONOSPACE, REMAPGREEK:, Remap Plane1:function(t,e){for(var a=0,i=this. PLANE1MAP.length;a /* https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/css */ /*! * Bootstrap v3.3.7 (https://getbootstrap.com) * Copyright 2011-2016 Twitter, Inc.

This could be done by reading characters and ending at a new line, but this way is much simpler.

The code requires input be separated by spaces and ended with a number greater than 10 to exit the reading loop.

The code seems to work fine until it needs to check which type of card it is (Visa American Express or Master Card ) .

The problem seems to be somewhere in the last part where it checks the conditions for different types of cards (i wrote a comment in red ) .

||MONOSPACE]], REMAPGREEK:, Remap Plane1:function(t,e){for(var a=0,i=this. PLANE1MAP.length;a /* https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/css */ /*! * Bootstrap v3.3.7 (https://getbootstrap.com) * Copyright 2011-2016 Twitter, Inc. This could be done by reading characters and ending at a new line, but this way is much simpler. The code requires input be separated by spaces and ended with a number greater than 10 to exit the reading loop. The code seems to work fine until it needs to check which type of card it is (Visa American Express or Master Card ) .The problem seems to be somewhere in the last part where it checks the conditions for different types of cards (i wrote a comment in red ) .

]]
Even, profiles of couple can be explored, previewed for free, and join their porn live chat for free.

Their process was never made mainstream, but e Harmony says this is known as the first attempt at creating an automated matchmaking service.

And that is even if you are focusing on only one aspect of this very diverse subject.