Validate International Securities Identification Number: Difference between revisions

m
 
(18 intermediate revisions by 9 users not shown)
Line 68:
{{trans|Python}}
 
<langsyntaxhighlight lang="11l">F check_isin(a)
I a.len != 12
R 0B
Line 91:
 
print([‘US0378331005’, ‘US0373831005’, ‘U50378331005’, ‘US03378331005’,
‘AU0000XVGZA3’, ‘AU0000VXGZA3’, ‘FR0000988040’].map(s -> check_isin(s)))</langsyntaxhighlight>
 
{{out}}
Line 99:
 
=={{header|360 Assembly}}==
<langsyntaxhighlight lang="360asm">* Validate ISIN 08/03/2019
VALISIN CSECT
USING VALISIN,R13 base register
Line 274:
XDEC DS CL12 temp for xdeco and xdeci
REGEQU
END VALISIN</langsyntaxhighlight>
{{out}}
<pre>
Line 289:
Calling the existing Luhn algorithm implementation from the ''[[Luhn test of credit card numbers]]'' task.
 
<langsyntaxhighlight Adalang="ada">procedure ISIN is
-- Luhn_Test copied from other Task
function Luhn_Test (Number: String) return Boolean is
Line 362:
when others =>
Ada.Text_IO.Put_Line("Exception occured");
end ISIN;</langsyntaxhighlight>
 
Output:
Line 375:
=={{header|ALGOL W}}==
Uses the LuhnTest procedure from the [[Luhn test of credit card numbers]] task.
<langsyntaxhighlight lang="algolw">begin
% external procedure that returns true if ccNumber passes the Luhn test, false otherwise %
logical procedure LuhnTest ( string(32) value ccNumber
Line 449:
testIsIsin( "AU0000VXGZA3", true );
testIsIsin( "FR0000988040", true );
end.</langsyntaxhighlight>
{{out}}
<pre>
Line 465:
This script calls a handler posted for the [https://www.rosettacode.org/wiki/Luhn_test_of_credit_card_numbers#Straightforward Luhn test of credit card numbers] task.
 
<langsyntaxhighlight lang="applescript">use AppleScript version "2.4" -- OS X 10.10 (Yosemite) or later
use framework "Foundation"
 
Line 490:
set end of testResults to {testNumber:ISIN's contents, valid:ISINTest(ISIN)}
end repeat
return testResults</langsyntaxhighlight>
 
{{output}}
<langsyntaxhighlight lang="applescript">{{testNumber:"US0378331005", valid:true}, {testNumber:"US0373831005", valid:false}, {testNumber:"U50378331005", valid:false}, {testNumber:"US03378331005", valid:false}, {testNumber:"AU0000XVGZA3", valid:true}, {testNumber:"AU0000VXGZA3", valid:true}, {testNumber:"FR0000988040", valid:true}}</langsyntaxhighlight>
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: GAWK -f VALIDATE_INTERNATIONAL_SECURITIES_IDENTIFICATION_NUMBER.AWK
# converted from Fortran
Line 532:
return(v % 10 == 0)
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 543:
1 FR0000988040
</pre>
 
=={{header|BASIC256}}==
<syntaxhighlight lang="vbnet">array base 1
 
dim test_set$(7)
test_set$ = {"US0378331005", "US0373831005", "U50378331005", "US03378331005", "AU0000XVGZA3", "AU0000VXGZA3", "FR0000988040"}
 
for i = 1 to test_set$[?]
test_str$ = ""
l = length(test_set$[i])
if l <> 12 then
print test_set$[i]; " Invalid, length <> 12 char."
continue for
end if
if asc(mid(test_set$[i], 1, 1)) < asc("A") or asc(mid(test_set$[i], 2, 1)) < asc("A") then
print test_set$[i]; " Invalid, number needs to start with 2 characters"
continue for
end if
for n = 1 to l
x = asc(mid(test_set$[i], n, 1)) - asc("0")
if x > 9 then x -= 7
if x < 10 then
test_str$ += string(x)
else # two digest number
test_str$ += string(x \ 10) + string(x mod 10)
end if
next
print test_set$[i]; " ";
if luhntest(test_str$) = 1 then
print "Invalid, checksum error"
else
print "Valid"
end if
next
end
 
function luhntest(cardnr$)
cardnr$ = trim(cardnr$) # remove spaces
l = length(cardnr$)
s1 = 0
s2 = 0
 
# sum odd numbers
for i = 1 to l step 2
s1 += fromradix(asc(mid(cardnr$, i, 1)), 10)
next
# sum even numbers
for i = 2 to l step 2
j = fromradix(asc(mid(cardnr$, i, 1)), 10)
j *= 2
if j > 9 then j = (j mod 10) + 1
s2 += j
next
 
return (s1 + s2) mod 10 = 0
end function</syntaxhighlight>
{{out}}
<pre>Similar to FreeBASIC entry.</pre>
 
=={{header|Bruijn}}==
Using bruijn's <code>luhn</code> solution from [[Luhn test of credit card numbers]]:
<syntaxhighlight lang="bruijn">
:import luhn_test_of_credit_card_numbers .
 
:import std/Number/Conversion .
:import std/Combinator .
:import std/String .
:import std/Char .
:import std/Logic .
:import std/Number .
 
# verifies ISIN format
format? [len ⋀? country ⋀? security ⋀? checksum]
len (length 0) =? (+12)
country all? uppercase? (take (+2) 0)
security all? (φ or? uppercase? numeric?) (take (+9) (drop (+2) 0))
checksum numeric? _0
 
# performs luhn test
checksum? (map (from-base36 → number→string)) → concat → string→number → luhn
from-base36 binary→ternary → [(0 - (0 ≥? (+65) ((+65) - (+10)) (+48)))]
 
# performs format and checksum test
validate φ and? format? checksum?
 
:test (validate "US0378331005") (true)
:test (validate "US0373831005") (false)
:test (validate "U50378331005") (false)
:test (validate "US03378331005") (false)
:test (validate "AU0000XVGZA3") (true)
:test (validate "AU0000VXGZA3") (true)
:test (validate "FR0000988040") (true)
</syntaxhighlight>
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
 
int check_isin(char *a) {
Line 590 ⟶ 683:
}
 
/* will print: T F F F T T T */</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
{
<langsyntaxhighlight lang="csharp">using System;
using System.Linq;
using System.Text.RegularExpressions;
Line 644 ⟶ 737:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>US0378331005 is valid
Line 655 ⟶ 748:
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">
 
#include <string>
Line 716 ⟶ 809:
return 0;
}
</syntaxhighlight>
</lang>
 
=={{header|Caché ObjectScript}}==
 
<langsyntaxhighlight lang="cos">Class Utils.Check [ Abstract ]
{
 
Line 749 ⟶ 842:
}
 
}</langsyntaxhighlight>
{{out|Examples}}
<pre>USER>For { Read isin Quit:isin="" Write ": "_##class(Utils.Check).ISIN(isin), ! }
Line 763 ⟶ 856:
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="clojure">(defn luhn? [cc]
(let [sum (->> cc
(map #(Character/digit ^char % 10))
Line 783 ⟶ 876:
"AU0000XVGZA3" "AU0000VXGZA3" "FR0000988040"]]
(cl-format *out* "~A: ~:[invalid~;valid~]~%" isin (is-valid-isin? isin)))
</syntaxhighlight>
</lang>
<tt>luhn?</tt> is based on ''[[Luhn test of credit card numbers#Clojure]]''.
{{out}}
Line 796 ⟶ 889:
=={{header|COBOL}}==
{{works with|GnuCOBOL}}
<langsyntaxhighlight lang="cobol"> >>SOURCE FORMAT FREE
*> this is gnucobol 2.0
identification division.
Line 968 ⟶ 1,061:
goback
.
end program luhntest.</langsyntaxhighlight>
 
{{out}}
Line 981 ⟶ 1,074:
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defun alphap (char)
(char<= #\A char #\Z))
 
Line 1,018 ⟶ 1,111:
(dolist (isin '("US0378331005" "US0373831005" "U50378331005" "US03378331005"
"AU0000XVGZA3" "AU0000VXGZA3" "FR0000988040"))
(format t "~A: ~:[invalid~;valid~]~%" isin (valid-isin-p isin))))</langsyntaxhighlight>
{{out}}
<pre>US0378331005: valid
Line 1,031 ⟶ 1,124:
{{trans|Java}}
Code for the luhn test was taken from [[https://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers#D]]
<langsyntaxhighlight Dlang="d">import std.stdio;
 
void main() {
Line 1,070 ⟶ 1,163:
import luhn;
return luhnTest(sb.data);
}</langsyntaxhighlight>
 
{{out}}
Line 1,080 ⟶ 1,173:
AU0000VXGZA3 is valid
FR0000988040 is valid</pre>
 
=={{header|Dart}}==
<syntaxhighlight lang="dart">bool checkISIN(String isin) {
int j = 0, v = 0;
List<int> s = List.filled(24, 0);
 
for (int i = 0; i < 12; i++) {
int k = isin.codeUnitAt(i);
if (k >= '0'.codeUnitAt(0) && k <= '9'.codeUnitAt(0)) {
if (i < 2) return false;
s[j++] = k - '0'.codeUnitAt(0);
} else if (k >= 'A'.codeUnitAt(0) && k <= 'Z'.codeUnitAt(0)) {
if (i == 11) return false;
k -= 'A'.codeUnitAt(0) - 10;
s[j++] = k ~/ 10;
s[j++] = k % 10;
} else {
return false;
}
}
 
if (isin.length > 12) return false;
 
for (int i = j - 2; i >= 0; i -= 2) {
int k = 2 * s[i];
v += k > 9 ? k - 9 : k;
}
 
for (int i = j - 1; i >= 0; i -= 2) {
v += s[i];
}
 
return v % 10 == 0;
}
 
void main() {
List<String> test = [
"US0378331005",
"US0373831005",
"U50378331005",
"US03378331005",
"AU0000XVGZA3",
"AU0000VXGZA3",
"FR0000988040"
];
 
for (String isin in test) {
print('$isin - ${checkISIN(isin)}');
}
}</syntaxhighlight>
{{out}}
<pre>US0378331005 - true
US0373831005 - false
U50378331005 - false
US03378331005 - false
AU0000XVGZA3 - true
AU0000VXGZA3 - true
FR0000988040 - true</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
 
 
<syntaxhighlight lang="Delphi">
 
 
function StrToBase10(S: string): TByteDynArray;
{Convert ASCII string to Base-10}
{ASCII Digits converted to integer 0..9 }
{ASCII Chars convert to bytes "A"=10, "B"=11, etc }
var I: Integer;
var B: byte;
 
procedure StoreByte(B: byte);
begin
SetLength(Result,Length(Result)+1);
Result[High(Result)]:=B;
end;
 
begin
SetLength(Result,0);
for I:=1 to Length(S) do
begin
if S[I] in ['0'..'9'] then StoreByte(Byte(S[I])-$30)
else
begin
B:=(Byte(S[I])-$41)+10;
StoreByte(B div 10);
StoreByte(B mod 10);
end;
end;
end;
 
{Simplifies cases where we have to sum a two digit number}
 
const DigitSum: array [0..18] of byte = (0,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9);
 
function LuhnTest(Nums: array of byte): boolean;
{Perform Luhn Test of byte array}
var I,J,Len,Sum,Sum1,Sum2: integer;
var Rev: array of byte;
begin
Sum1:=0; Sum2:=0;
Len:=High(Nums);
for I:=Len downto 0 do
if ((I-Len) and 1)=0 then Sum1:=Sum1 + Nums[I]
else Sum2:=Sum2 + DigitSum[Nums[I]*2];
Sum:=Sum1+Sum2;
Result:=(Sum mod 10)=0;
end;
 
{String error types}
 
type TStringErrors = (seNone,seLength,seCountry);
 
function ValidateStr(IDStr: string): TStringErrors;
{Validate string checking for incorrectly length}
{And invalid country code}
begin
if Length(IDStr)<>12 then Result:=seLength
else if not (IDStr[1] in ['a'..'z','A'..'Z']) or
not (IDStr[2] in ['a'..'z','A'..'Z']) then Result:=seCountry
else Result:=seNone;
end;
 
 
 
procedure ValidateID(Memo: TMemo; IDStr: string);
{Validate and display status of string}
var BA: TByteDynArray;
var LT: boolean;
var SE: TStringErrors;
var S: string;
begin
SE:=ValidateStr(IDStr);
BA:=StrToBase10(IDStr);
LT:=LuhnTest(BA);
if LT and (SE=seNone) then Memo.Lines.Add(IDStr+': Valid')
else
begin
S:=IDStr+': Invalid';
if not LT then S:=S+', Luhn Error';
case SE of
seLength: S:=S+', Length Error';
seCountry: S:=S+', Country Code Error';
end;
Memo.Lines.Add(S);
end;
end;
 
 
 
procedure ValidateSecuritiesID(Memo: TMemo);
var BA: TByteDynArray;
var I: integer;
var S: string;
begin
ValidateID(Memo,'US0378331005');
ValidateID(Memo,'US0373831005');
ValidateID(Memo,'U50378331005');
ValidateID(Memo,'US03378331005');
ValidateID(Memo,'AU0000XVGZA3');
ValidateID(Memo,'AU0000VXGZA3');
ValidateID(Memo,'FR0000988040');
end;
 
 
 
</syntaxhighlight>
{{out}}
<pre>
US0378331005: Valid
US0373831005: Invalid, Luhn Error
U50378331005: Invalid, Country Code Error
US03378331005: Invalid, Length Error
AU0000XVGZA3: Valid
AU0000VXGZA3: Valid
FR0000988040: Valid
 
Elapsed Time: 6.863 ms.
 
</pre>
 
 
=={{header|EasyLang}}==
{{trans|AWK}}
<syntaxhighlight>
func isin t$ .
if len t$ <> 12
return 0
.
for i to 12
k = strcode substr t$ i 1
if k >= 48 and k <= 57
if i <= 2
return 0
.
s[] &= k - 48
elif k >= 65 and k <= 91
if (i = 12)
return 0
.
k -= 55
s[] &= k div 10
s[] &= k mod 10
else
return 0
.
.
i = len s[] - 1
while i >= 1
k = 2 * s[i]
if k > 9
k -= 9
.
v += k
i -= 2
.
i = len s[]
while i >= 1
v += s[i]
i -= 2
.
if v mod 10 = 0
return 1
.
.
test$[] = [ "US0378331005" "US0373831005" "U50378331005" "US03378331005" "AU0000XVGZA3" "AU0000VXGZA3" "FR0000988040" ]
for t$ in test$[]
if isin t$ = 1
print t$ & " is valid"
else
print t$ & " is invalid"
.
.
</syntaxhighlight>
{{out}}
<pre>
US0378331005 is valid
US0373831005 is invalid
U50378331005 is invalid
US03378331005 is invalid
AU0000XVGZA3 is valid
AU0000VXGZA3 is valid
FR0000988040 is valid
</pre>
 
=={{header|Elixir}}==
used Luhn module from [[Luhn_test_of_credit_card_numbers#Elixir | here]]
<langsyntaxhighlight lang="elixir">isin? = fn str ->
if str =~ ~r/\A[A-Z]{2}[A-Z0-9]{9}\d\z/ do
String.codepoints(str)
Line 1,101 ⟶ 1,441:
AU0000VXGZA3
FR0000988040)
|> Enum.each(&IO.puts "#{&1}\t#{isin?.(&1)}")</langsyntaxhighlight>
 
{{out}}
Line 1,117 ⟶ 1,457:
=={{header|Factor}}==
We re-use the <code>luhn?</code> word from ''[[Luhn test of credit card numbers#Factor]]''.
<langsyntaxhighlight lang="factor">USING: combinators.short-circuit.smart formatting kernel luhn
math math.parser qw sequences strings unicode ;
IN: rosetta-code.isin
Line 1,154 ⟶ 1,494:
] each ;
MAIN: main</langsyntaxhighlight>
{{out}}
<pre>
Line 1,168 ⟶ 1,508:
=={{header|Fortran}}==
 
<langsyntaxhighlight lang="fortran">program isin
use ctype
implicit none
Line 1,224 ⟶ 1,564:
check_isin = 0 == mod(v, 10)
end function
end program</langsyntaxhighlight>
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' version 27-10-2016
' compile with: fbc -s console
 
Line 1,304 ⟶ 1,644:
Print : Print "hit any key to end program"
Sleep
End</langsyntaxhighlight>
{{out}}
<pre>US0378331005 Valid
Line 1,316 ⟶ 1,656:
=={{header|Go}}==
 
<langsyntaxhighlight lang="go">package main
 
import "regexp"
Line 1,345 ⟶ 1,685:
sum += int(n[11] - '0')
return sum%10 == 0
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="go">package main
 
import "testing"
Line 1,372 ⟶ 1,712:
}
}
}</langsyntaxhighlight>
 
=={{header|Groovy}}==
Line 1,378 ⟶ 1,718:
{{update|Groovy|Use the new test-cases, and consider calling the existing Luhn algorithm implementation from the ''[[Luhn test of credit card numbers]]'' task instead of duplicating it.}}
 
<langsyntaxhighlight lang="groovy">CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
 
int checksum(String prefix) {
Line 1,390 ⟶ 1,730:
assert checksum('GB000263494') == 6
assert checksum('US037833100') == 5
assert checksum('US037833107') == 0</langsyntaxhighlight>
 
=={{header|Haskell}}==
<langsyntaxhighlight Haskelllang="haskell">module ISINVerification2 where
 
import Data.Char (isUpper, isDigit, digitToInt)
Line 1,474 ⟶ 1,814:
, "FR0000988040"
]
mapM_ printSolution isinnumbers</langsyntaxhighlight>
 
{{out}}
Line 1,486 ⟶ 1,826:
 
Or, making alternative choices from the standard libraries:
<langsyntaxhighlight lang="haskell">import Control.Monad ((<=<))
import Data.Bifunctor (first)
import Data.List (foldl') -- '
Line 1,550 ⟶ 1,890:
"AU0000VXGZA3",
"FR0000988040"
]</langsyntaxhighlight>
{{Out}}
<pre>("US0378331005",True)
Line 1,563 ⟶ 1,903:
 
'''Solution:'''
<langsyntaxhighlight lang="j">require'regex'
validFmt=: 0 -: '^[A-Z]{2}[A-Z0-9]{9}[0-9]{1}$'&rxindex
 
Line 1,569 ⟶ 1,909:
luhn=: 0 = 10 (| +/@,) 10 #.inv 1 2 *&|: _2 "."0\ |. NB. as per task Luhn_test_of_credit_card_numbers#J
 
validISIN=: validFmt *. luhn@df36</langsyntaxhighlight>
 
'''Required Examples:'''
<langsyntaxhighlight lang="j"> Tests=: 'US0378331005';'US0373831005';'U50378331005';'US03378331005';'AU0000XVGZA3';'AU0000VXGZA3';'FR0000988040'
validISIN&> Tests
1 0 0 0 1 1 1</langsyntaxhighlight>
 
=={{header|Java}}==
As the Luhn test method from the ''[[Luhn test of credit card numbers]]'' task is only a few lines, it has been embedded in the ISIN class for convenience.
 
<langsyntaxhighlight lang="java">public class ISIN {
public static void main(String[] args) {
Line 1,625 ⟶ 1,965:
return (s1 + s2) % 10 == 0;
}
}</langsyntaxhighlight>
 
<pre>US0378331005 is valid
Line 1,638 ⟶ 1,978:
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
<langsyntaxhighlight lang="jq"># This filter may be applied to integers or integer-valued strings
def luhntest:
def digits: tostring | explode | map([.]|implode|tonumber);
Line 1,661 ⟶ 2,001:
type == "string"
and test("^(?<cc>[A-Z][A-Z])(?<sc>[0-9A-Z]{9})(?<cs>[0-9])$")
and (decodeBase36 | luhntest);</langsyntaxhighlight>
'''The Task'''
<langsyntaxhighlight lang="jq">def task:
"US0378331005",
"US0373831005",
Line 1,673 ⟶ 2,013:
| . + " => " + (if is_ISIN then "valid" else "invalid" end);
 
task</langsyntaxhighlight>
{{out}}
<pre>
Line 1,687 ⟶ 2,027:
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">using Printf
 
luhntest(x) = luhntest(parse(Int, x))
Line 1,699 ⟶ 2,039:
"US03378331005", "AU0000XVGZA3", "AU0000VXGZA3", "FR0000988040"]
@printf("%-15s %5s\n", inum, ifelse(checkISIN(inum), "pass", "fail"))
end</langsyntaxhighlight>
 
{{out}}
Line 1,712 ⟶ 2,052:
=={{header|Kotlin}}==
As the Luhn test method is only a few lines, it's reproduced here for convenience:
<langsyntaxhighlight lang="scala">// version 1.1
 
object Isin {
Line 1,748 ⟶ 2,088:
println("$isin\t -> ${if (Isin.isValid(isin)) "valid" else "not valid"}")
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,762 ⟶ 2,102:
 
=={{header|langur}}==
The luhn test is repeated here for simplicity (from Luhn_test_of_credit_card_numbers#langur).
 
<syntaxhighlight lang="langur">val .luhntest = fn(.s) {
{{works with|langur|0.8.10}}
<lang langur>val .luhntest = f(.s) {
val .t = [0, 2, 4, 6, 8, 1, 3, 5, 7, 9]
val .numbers = s2n .s
Line 1,771 ⟶ 2,110:
 
for[=0] .i of .numbers {
_for += if( .i rem 2 == .oddeven: .numbers[.i]; .t[.numbers[.i]+1]){
.numbers[.i]
} else {
.t[.numbers[.i]+1]
}
} div 10
}
 
val .isintest = ffn(.s) {
matching(.s -> re/^[A-Z][A-Z][0-9A-Z]{9}[0-9]$/, .s) and
.luhntest(join s2n .s)
}
 
val .tests = h{
"US0378331005": true,
"US0373831005": false,
Line 1,794 ⟶ 2,137:
write .key, ": ", .pass
writeln if(.pass == .tests[.key]: ""; " (ISIN TEST FAILED)")
}</langsyntaxhighlight>
 
{{out}}
Line 1,806 ⟶ 2,149:
 
=={{header|Lua}}==
<langsyntaxhighlight Lualang="lua">function luhn (n)
local revStr, s1, s2, digit, mod = n:reverse(), 0, 0
for pos = 1, #revStr do
Line 1,842 ⟶ 2,185:
"FR0000988040"
}
for _, ISIN in pairs(testCases) do print(ISIN, checkISIN(ISIN)) end</langsyntaxhighlight>
{{out}}
<pre>US0378331005 true
Line 1,853 ⟶ 2,196:
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">ClearAll[LuhnQ, VakudISINQ]
LuhnQ[n_Integer] := Block[{digits = Reverse@IntegerDigits@n}, Mod[Total[{digits[[;; ;; 2]], IntegerDigits[2 #] & /@ digits[[2 ;; ;; 2]]}, -1], 10] == 0]
VakudISINQ[sin_String] := Module[{s = ToUpperCase[sin]},
Line 1,868 ⟶ 2,211:
]
]
VakudISINQ /@ {"US0378331005", "US0373831005", "U50378331005", "US03378331005", "AU0000XVGZA3", "AU0000VXGZA3", "FR0000988040"}</langsyntaxhighlight>
{{out}}
<pre>{True, False, False, False, True, True, True}</pre>
 
=={{header|Nim}}==
<langsyntaxhighlight Nimlang="nim">import strformat
 
const
Line 1,918 ⟶ 2,261:
echo &"{isin} is valid."
except ISINError:
echo &"{isin} is not valid: {getCurrentExceptionMsg()}."</langsyntaxhighlight>
 
{{out}}
Line 1,931 ⟶ 2,274:
=={{header|Perl}}==
We reuse the <tt>luhn_test()</tt> function from ''[[Luhn test of credit card numbers#Perl]]''.
<langsyntaxhighlight lang="perl">use strict;
use English;
use POSIX;
Line 1,951 ⟶ 2,294:
split(//s, $isin));
return luhn_test($base10);
}</langsyntaxhighlight>
{{out}}
<pre>1..7
Line 1,964 ⟶ 2,307:
=={{header|Phix}}==
Note this (slightly better) version of Luhn() has the reverse() inside it, whereas the original did not.
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">Luhn</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">st</span><span style="color: #0000FF;">)</span>
Line 2,007 ⟶ 2,350:
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s : %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">reasons</span><span style="color: #0000FF;">[</span><span style="color: #000000;">valid_ISIN</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 2,021 ⟶ 2,364:
=={{header|PicoLisp}}==
Using the <tt>luhn</tt> function defined at ''[[Luhn test of credit card numbers#PicoLisp]]'':
<langsyntaxhighlight PicoLisplang="picolisp">(de isin (Str)
(let Str (mapcar char (chop Str))
(and
Line 2,043 ⟶ 2,386:
"AU0000XVGZA3"
"AU0000VXGZA3"
"FR0000988040" ) ) )</langsyntaxhighlight>
{{out}}
<pre>(0 NIL NIL NIL 0 0 0)</pre>
 
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
<lang PowerShell>
function Test-ISIN
{
Line 2,112 ⟶ 2,455:
(10 - ($sum % 10)) % 10 -match $checkDigit
}
</syntaxhighlight>
</lang>
<syntaxhighlight lang="powershell">
<lang PowerShell>
"US0378331005","US0373831005","US0337833103","AU0000XVGZA3","AU0000VXGZA3","FR0000988040" | ForEach-Object {
[PSCustomObject]@{
Line 2,120 ⟶ 2,463:
}
}
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 2,134 ⟶ 2,477:
 
=={{header|PureBasic}}==
<langsyntaxhighlight PureBasiclang="purebasic">EnableExplicit
 
Procedure.b Check_ISIN(*c.Character)
Line 2,182 ⟶ 2,525:
CloseFile(0)
EndIf
Input()</langsyntaxhighlight>
{{Out}}
<pre>US0378331005 TRUE
Line 2,194 ⟶ 2,537:
=={{header|Python}}==
 
<langsyntaxhighlight lang="python">def check_isin(a):
if len(a) != 12 or not all(c.isalpha() for c in a[:2]) or not all(c.isalnum() for c in a[2:]):
return False
Line 2,226 ⟶ 2,569:
"AU0000XVGZA3", "AU0000VXGZA3", "FR0000988040"]]
 
# [True, False, False, False, True, True, True]</langsyntaxhighlight>
 
=={{header|Quackery}}==
Line 2,232 ⟶ 2,575:
<code>luhn</code> is defined at [[Luhn test of credit card numbers#Quackery]].
 
<langsyntaxhighlight Quackerylang="quackery"> [ 2 split drop do
char A char z 1+ within
swap
Line 2,263 ⟶ 2,606:
$ "AU0000VXGZA3" task
$ "FR0000988040" task
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,277 ⟶ 2,620:
=={{header|Racket}}==
 
<langsyntaxhighlight lang="racket">
#lang racket
 
Line 2,311 ⟶ 2,654:
(map isin-test? test-cases)
;; -> '(#t #f #f #f #t #t #t)
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,323 ⟶ 2,666:
Using the <tt>luhn-test</tt> function from the ''[[Luhn test of credit card numbers#Raku|Luhn test of credit card numbers]]'' task.
 
<syntaxhighlight lang="raku" perl6line>my $ISIN = /
^ <[A..Z]>**2 <[A..Z0..9]>**9 <[0..9]> $
<?{ luhn-test $/.comb.map({ :36($_) }).join }>
Line 2,345 ⟶ 2,688:
AU0000VXGZA3
FR0000988040
>;</langsyntaxhighlight>
 
{{out}}
Line 2,359 ⟶ 2,702:
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/*REXX program validates the checksum digit for an International Securities ID number.*/
parse arg z /*obtain optional ISINs from the C.L.*/
if z='' then z= "US0378331005 US0373831005 U50378331005 US03378331005 AU0000XVGZA3" ,
Line 2,385 ⟶ 2,728:
$= $ + substr(y, j, 1) + left(_, 1) + substr(_, 2 , 1, 0)
end /*j*/ /* [↑] sum the odd and even digits.*/
return right($, 1)==0 /*return "1" if number passed Luhn test*/</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
Line 2,398 ⟶ 2,741:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : Validate International Securities Identification Number
 
Line 2,479 ⟶ 2,822:
next
return sumarr
</syntaxhighlight>
</lang>
Output:
<pre>
Line 2,489 ⟶ 2,832:
AU0000VXGZA3 -> Valid
FR0000988040 -> Valid
</pre>
 
=={{header|RPL}}==
<code>LUHN?</code> is defined at [[Luhn test of credit card numbers#RPL|Luhn test of credit card numbers]]
{{works with|RPL|HP48-R}}
« '''IF''' DUP SIZE 12 ≠ '''THEN''' DROP 0
'''ELSE'''
""
1 3 PICK SIZE '''FOR''' j
OVER j DUP SUB
'''IF''' "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" SWAP POS '''THEN''' LASTARG 1 - + '''END'''
'''NEXT'''
<span style="color:blue">LUHN?</span>
{ "AD" "AT" "AU" "BE" "CA" "DE" "ES" "FR" "GB" "HK" "IT" "US" "ZW" } <span style="color:grey">@ country codes sample </span>
ROT 1 2 SUB POS AND
'''END'''
» '<span style="color:blue">ISIN?</span>' STO
 
{"US0378331005" "US0373831005" "U50378331005" "US03378331005" "AU0000XVGZA3" "AU0000VXGZA3" "FR0000988040"}
1 « <span style="color:blue">ISIN?</span> » DOLIST
{{out}}
<pre>
1: { 1 0 0 0 1 1 1 }
</pre>
 
=={{header|Ruby}}==
Using a pre-existing luhn method:
<langsyntaxhighlight lang="ruby">RE = /\A[A-Z]{2}[A-Z0-9]{9}[0-9]{1}\z/
 
def valid_isin?(str)
Line 2,508 ⟶ 2,874:
FR0000988040).map{|tc| valid_isin?(tc) }
# => [true, false, false, false, true, true, true]</langsyntaxhighlight>
 
=={{header|Rust}}==
 
<langsyntaxhighlight Rustlang="rust">extern crate luhn_cc;
 
use luhn_cc::compute_luhn;
Line 2,556 ⟶ 2,922:
return compute_luhn(number);
}
</syntaxhighlight>
</lang>
 
=={{header|SAS}}==
<langsyntaxhighlight lang="sas">data test;
length isin $20 ok $1;
input isin;
Line 2,606 ⟶ 2,972:
FR0000988040
;
run;</langsyntaxhighlight>
 
=={{header|Scala}}==
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/D9ax4Js/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/yOymYqoPSEeA7K7rjgn65g Scastie (remote JVM)].
<langsyntaxhighlight Scalalang="scala">object Isin extends App {
val isins = Seq("US0378331005", "US0373831005", "U50378331005",
"US03378331005", "AU0000XVGZA3","AU0000VXGZA3", "FR0000988040")
Line 2,649 ⟶ 3,015:
isins.foreach(isin => println(f"$isin is ${if (ISINtest(isin)) "" else "not"}%s valid"))
 
}</langsyntaxhighlight>
 
=={{header|SQL PL}}==
{{works with|Db2 LUW}} version 9.7 or higher.
With SQL PL:
<langsyntaxhighlight lang="sql pl">
--#SET TERMINATOR @
 
Line 2,707 ⟶ 3,073:
RETURN RET;
END @
</syntaxhighlight>
</lang>
Output:
<pre>
Line 2,773 ⟶ 3,139:
 
=={{header|Tcl}}==
<syntaxhighlight lang Tcl="tcl">package require Tcl 8.6 ;# mostly needed for [assert]. Substitute a simpler one or a NOP if required.</langsyntaxhighlight>
A proc like assert is always good to have around. This one tries to report values used in its expression using subst:
<langsyntaxhighlight Tcllang="tcl">proc assert {expr} { ;# for "static" assertions that throw nice errors
if {![uplevel 1 [list expr $expr]]} {
set msg "{$expr}"
Line 2,781 ⟶ 3,147:
tailcall throw {ASSERT ERROR} $msg
}
}</langsyntaxhighlight>
isin itself is a simple package. We compute the alphabet when the package is loaded in _init, because that's more fun than typing out the table:
<langsyntaxhighlight Tcllang="tcl">namespace eval isin {
proc _init {} { ;# sets up the map used on every call
variable map
Line 2,819 ⟶ 3,185:
}
 
}</langsyntaxhighlight>
To run the test suite, we use the tcltest framework included with Tcl:
<langsyntaxhighlight Tcllang="tcl">package require tcltest
 
tcltest::test isin-1 "Test isin validation" -body {
Line 2,840 ⟶ 3,206:
}
return ok
} -result ok</langsyntaxhighlight>
 
=={{header|Transact-SQL}}==
 
<syntaxhighlight lang="transact-sql">
<lang Transact-SQL>
CREATE FUNCTION dbo._ISINCheck( @strISIN VarChar(40) )
RETURNS bit
Line 2,886 ⟶ 3,252:
RETURN @bValid
END
</syntaxhighlight>
</lang>
Testing
<syntaxhighlight lang="transact-sql">
<lang Transact-SQL>
-- Testing. The following tests all pass.
;WITH ISIN_Tests AS
Line 2,902 ⟶ 3,268:
)
SELECT ISIN, Expected, dbo._ISINCheck(ISIN) AS TestResult FROM ISIN_Tests ORDER BY ISIN
</syntaxhighlight>
</lang>
 
=={{header|VBScript}}==
<langsyntaxhighlight lang="vb">' Validate International Securities Identification Number - 03/03/2019
 
buf=buf&test("US0378331005")&vbCrLf
Line 2,951 ⟶ 3,317:
end if
test=cc&" "&msg
end function 'test </langsyntaxhighlight>
{{out}}
<pre>
Line 2,966 ⟶ 3,332:
{{works with|Visual Basic|VB6 Standard}}
Calls LuhnCheckPassed() function described at [[Luhn_test_of_credit_card_numbers#Visual_Basic]]
<langsyntaxhighlight lang="vb">Function IsValidISIN(ByVal ISIN As String) As Boolean
Dim s As String, c As String
Dim i As Long
Line 2,985 ⟶ 3,351:
IsValidISIN = LuhnCheckPassed(s)
End If
End Function</langsyntaxhighlight>
Test:
<langsyntaxhighlight lang="vb">Sub Main()
Debug.Assert IsValidISIN("US0378331005")
Debug.Assert Not IsValidISIN("US0373831005")
Line 2,996 ⟶ 3,362:
Debug.Assert IsValidISIN("FR0000988040")
Debug.Assert Not IsValidISIN("FR000098804O")
End Sub</langsyntaxhighlight>
 
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<langsyntaxhighlight lang="vbnet">Option Strict On
Imports System.Text.RegularExpressions
 
Line 3,048 ⟶ 3,414:
End Sub
 
End Module</langsyntaxhighlight>
{{out}}
<pre>US0378331005 is valid
Line 3,058 ⟶ 3,424:
FR0000988040 is valid</pre>
 
=={{header|V (Vlang)}}==
{{trans|go}}
<syntaxhighlight lang="v (vlang)">import regex
 
const (
Line 3,114 ⟶ 3,480:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>expected true for US0378331005, got false
Line 3,124 ⟶ 3,490:
=={{header|Wren}}==
{{libheader|Wren-str}}
{{libheader|Wren-traititerate}}
{{libheader|Wren-fmt}}
The Luhn test method is reproduced here for convenience.
<langsyntaxhighlight ecmascriptlang="wren">import "./str" for Char
import "./traititerate" for Stepped
import "./fmt" for Conv, Fmt
 
var luhn = Fn.new { |s|
Line 3,166 ⟶ 3,532:
var ans = (isin.call(test)) ? "valid" : "not valid"
System.print("%(Fmt.s(-13, test)) -> %(ans)")
}</langsyntaxhighlight>
 
{{out}}
Line 3,180 ⟶ 3,546:
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">string 0; \use zero-terminated strings
 
func Luhn(Str); \Return 'true' if digits in Str pass Luhn test
Line 3,232 ⟶ 3,598:
CrLf(0);
];
]</langsyntaxhighlight>
 
{{out}}
Line 3,247 ⟶ 3,613:
=={{header|Yabasic}}==
{{trans|FreeBASIC}}
<langsyntaxhighlight Yabasiclang="yabasic">sub luhntest(cardnr$)
local i, j, s1, s2, l
Line 3,301 ⟶ 3,667:
if luhntest(test_str$) then print " Valid" else print " Invalid, checksum error" end if
loop
</syntaxhighlight>
</lang>
 
=={{header|zkl}}==
Uses the luhn test from [[Luhn_test_of_credit_card_numbers#zkl]] (copied here as it is short).
<langsyntaxhighlight lang="zkl">fcn validateISIN(isin){
RegExp(String("^","[A-Z]"*2,"[A-Z0-9]"*9,"[0-9]$")).matches(isin) and
luhnTest(isin.split("").apply("toInt",36).concat().toInt())
Line 3,312 ⟶ 3,678:
0 == (n.split().reverse().reduce(fcn(s,n,clk){
s + if(clk.inc()%2) n else 2*n%10 + n/5 },0,Ref(1)) %10)
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">println(" ISIN Valid?");
foreach isin in (T("US0378331005","US0373831005","U50378331005",
"US03378331005","AU0000XVGZA3","AU0000VXGZA3","FR0000988040")){
println(isin," --> ",validateISIN(isin));
}</langsyntaxhighlight>
{{out}}
<pre>
885

edits