Has anyone worked with the LUHN algorithm?
Here's a link for a description- http://en.wikipedia.org/wiki/Luhn_algorithm
Looking to see if anyone has written any methods using it. A forum search only turned up someone with the last name of Luhn.
Thanks.
Don
Looking to see if anyone has written any methods using it. A forum search only turned up someone with the last name of Luhn.
Thanks.
Don

Comments
More likely we would use a simple checksum or Cyclic Redundancy Check for verifying binary data in storage devices or communications protocols.
http://en.wikipedia.org/wiki/Cyclic_redundancy_check
The following code seems to work. It validated correct the example number in the Wiki and also my own CreditCard number.
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 OBJ ser : "FullDuplexSerial" VAR byte digits[20] PUB Main : i | ch ser.start(31,30,0,115200) 'Terminal communication waitcnt(clkfreq*3+cnt) repeat ser.str(string(13,"Enter number: ")) i := 0 repeat ch := ser.rx case ch "0".."9": digits[i++] := ch ser.tx(ch) 8,$C8: ser.tx(8) ser.tx(32) ser.tx(8) i := i-1 #> 0 other: digits[i] := 0 quit ' bytemove(@digits,string("79927398713"),12) 'Test number ser.str(string(13,"Number: ")) ser.str(@digits) if LuhnValidation(@digits) == 0 ser.str(string(" is Okay")) else ser.str(string(" is Wrong")) PUB LuhnValidation(strp) : sum | n, d '' expects number as characters in a string '' returns 0 if okay or 1..9 otherwise n := strsize(strp)-1 repeat sum += byte[strp+n]-"0" n-- if n => 0 d := byte[strp+n]-"0" if d*2 > 9 sum += 1 sum += d*2-10 else sum += d*2 n-- until n < 0 sum //= 10Andy
pub check_luhn(p_str) | sum, ndigits, parity, idx, n '' Validates credit card # (at p_str) using the Luhn check algorithm '' -- http://www.codeproject.com/Articles/10720/How-To-Validate-Credit-Card-Numbers sum := 0 ' clear Luhn sum ndigits := strsize(p_str) ' get # of digits in CC # parity := ndigits & 1 ' calc parity position repeat idx from 0 to ndigits-1 ' loop through string n := byte[p_str+idx] - "0" ' convert char to digit if ((idx & 1) == parity) ' parity position? n <<= 1 ' double it if (n > 9) ' if > 9 n -= 9 ' reduce to single digit sum += n ' update sum return ((sum // 10) == 0) ' return true if divisible by 10Thanks Jon. I'll look for that article as well.
Andy- Thanks for your demo. I'm trying to understand what you are looking for here:
I like your simple code that uses backspace to correct mistakes typed but I'm trying to figure out what you are looking for. I know the "8" is the backspace character but what does the $C8 ("200") represent?
$C8 is the code that the PS2 Keyboard driver returns for the Backspace key. I normally use PropTerminal on the PC to test such Spin code and PropTerminal sends key codes compatible to the PS2 keyboard driver. If I test for $C8 and 8 then the same code works with standard Terminals and PropTerminal (and PS2 keybords when you change ser.rx to kbrd.getkey).
Andy