;; 
;;=====================================================================================----- 
;; 
;;FUNCTION       LuhnModCk() 
;; 
;;ACTION         Generate / Check a string of digits using Luhn's Mod 
;; 
;;AUTHOR         Glenn Barnas 
;; 
;;VERSION        1.0  - 2010/10/08 
;; 
;;HISTORY        1.0  - 2010/10/08 - Initial Release 
;; 
;;SYNTAX         LuhnModCk(Text [, flag] [, length]) 
;; 
;;PARAMETERS     Text - REQUIRED - String  
;;               - the string to check or generate a check value on 
;; 
;;		 flag - OPTIONAL - Integer 
;;               - When true, returns the Luhn check value 
;; 
;;		 length - OPTIONAL - Integer 
;;               - Specifies an alternate string length. Not reuquired 
;;               when generating a check digit. 
;; 
;;REMARKS        This version defaults to an 11-character string - 10 chars of data 
;;		 plus the check digit. If a different length is required, it can  
;;		 be specified as an optional parameter. Thus, the length and check 
;;		 are both validated in a single call. 
;; 
;;RETURNS        Bool for check status (1=Valid), Int containing the check digit 
;;               FLAG=0 - 1 (true) if a valid check, 0 (false) otherwise 
;;		 FLAG=1 - Digit needed for the supplied string to pass the check 
;; 
;;DEPENDENCIES   none 
;; 
;;TESTED WITH    W2K, WXP, W2K3, W2K8, Win7 
;; 
;;EXAMPLES       $S = LuhnModCk('023929503830037', 1)  ; return check digit 
;;               If LuhnModCk('023929503830037'+$S, 0, 16) 
;;		   "Valid check!' ? 
;;		 EndIf 
; 
Function LuhnModCk($_Check, OPTIONAL $_Flag, OPTIONAL $_Len)
 
  Dim $_F					; cycle flag 
  Dim $_S					; Subtotal 
  Dim $_Cv					; Check value 
 
  $_F = 0
 
  If Val($_Len) = 0 $_Len = 11 EndIf
 
  If Len($_Check) <> $_Len And Not $_Flag	; verify length 
    $LuhnModCk = 0
    Exit 87
  Else
    If Not $_Flag				; strip the check digit 
      $_S = Val(Right($_Check, 1))
      $_Check = Left($_Check, Len($_Check) - 1)
    EndIf
  EndIf
 
  While $_Check
    $_F = $_F ^ 1				; get last char 
 
    ; force digits 
    $_Cv = InStr('0123456789', (Right($_Check, 1))) - 1
    If $_F
      $_Cv = $_Cv * 2
      While $_Cv > 9
        $_Cv = $_Cv - 9
      Loop
    EndIf
    ; without this check, non-digits are simply ignored, creating an improper check value 
    If $_Flag And $_Cv < 0 $_Cv = 0 EndIf	; invalidate non-digits 
    $_S = $_S + $_Cv
 
    $_Check = Left($_Check, ~)
  Loop
 
  If $_Flag
    $LuhnModCk = 0
    If $_S Mod 10 
      $LuhnModCk = 10 - ($_S Mod 10)		; return check digit 
    EndIf
  Else
    $LuhnModCk = Not ($_S Mod 10)		; return status 
  EndIf
 
  Exit 0
 
EndFunction