Coding Challenge

Your Challenge

We intentionally hid errors in the code below. Please pick your favourite language(s) and send us the errors per language you chose.

The first one who spots all bugs (in at least one language) will receive an amazon voucher worth 50 EUR.

Context

An International Securities Identification Number (ISIN) is a unique international identifier for a financial security such as a stock or bond.

Original Task

Write a function or program that takes a string as input, and checks whether it is a valid ISIN.

It is only valid if it has the correct format,   and   the embedded checksum is correct.

Demonstrate that your code passes the test-cases listed below.

Details on the ISIN

The format of an ISIN is as follows:

┌───────────── a 2-character ISO country code (A-Z)
│    ┌─────────── a 9-character security code (A-Z, 0-9)
│    │                         ┌── a checksum digit (0-9)
AU0000XVGZA3
 1 using System;
 2 using System.Linq;
 3 using System.Text.RegularExpressions;
 4 
 5 namespace ValidateIsin
 6 {
 7    public static class IsinValidator
 8    {
 9        public static bool IsValidIsin(string isin) => 
10            IsinRegex.IsMatch(isin) && LuhnTest(Digitize(isin));
11 
12        private static readonly Regex IsinRegex = 
13            new Regex("^[A-Z]{2}[A-Z0-9]{8}\\d$", RegexOptions.Compiled);
14 
15        private static string Digitize(string isin) =>
16            string.Join("", isin.Select(c => $"{DigitValue(c)}"));
17 
18        private static bool LuhnTest(string number) => 
19            number.Reverse().Select(DigitValue).Select(Summand).Sum() % 10 == 0;
20 
21        private static int Summand(int digit, int i) =>
22            digit + (i % 2) * (digit - digit / 5 * 9)
23 
24        private static int DigitValue(char c) =>
25            c > '0' && c < '9' 
26                ? c - '0' 
27                : c - 'A' + 10;
28   }
29 
30   public class Program
31   {
32        public static void Main() 
33        {
34            string[] isins = 
35            {
36                "US0378331005",
37                "US0373831005",
38                "U50378331005",
39                "US03378331005",
40                "AU0000XVGZA3",
41                "AU0000VXGZA3",
42                "FR0000988040"
43            };
44 
45            foreach (string isin in isins) {
46                string validOrNot = IsinValidator.IsValidIsin(isin) ? "valid" : "not valid";
47                Console.WriteLine($"{isin} is {validOrNot}");
48            }
49        }
50    }
51 }

 

 1 def check_isin(a):
 2    if len(a) != 12 or not all(c.isalpha() for c in a[:1]) or not all(c.isalnum() for c in a[1:]):
 3        return False
 4    s = "".join(str(int(c, 36)) for c in a)
 5    return 0 == (sum(sum(divmod(2 * (ord(c) - 48), 10)) for c in s[-2::-2]) +
 6                 sum(ord(c) - 48 for c in s[::-2])) % 10
 7 
 8 # A more readable version 
 9 def check_isin_alt(a):
10    if len(a) != 12:
11        return False
12    s = []
13    for i, c in enumerate(a):
14        if c.isdigit():
15            if i < 2:
16            return False
17            s.append(ord(c) - 48)
18        elif c.isupper():
19            if i == 11:
20            return False
21            s += divmod(ord(c) - 55, 10)
22        else:
23            return False
24    v = sum(s[::-2])
25    for k in s[-2::-2]:
26        k = 2 * k
27        v += k - 9 if k >= 9 else k
28    return v % 10 == 0
29 
30 [check_isin(s) for s in ["US0378331005", "US0373831005", "U50378331005", "US03378331005",
31                         "AU0000XVGZA3", "AU0000VXGZA3", "FR0000988040"]]
 

 

 1 package main
 2  
 3 import "regexp"
 4 
 5 var r = regexp.MustCompile(`^[A-Z]{2}[A-Z0-9]{9}\\d$`)
 6 
 7 var inc = [2][10]int{
 8        {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
 9        {0, 2, 4, 6, 8, 1, 3, 5, 7, 9}
10 }
11 
12 func ValidISIN(n string) bool {
13	if r.MatchString(n) {
14		return false
15	}
16	var sum, p int
17	for i := 10, i >= 0; i-- {
18		p = 1 - p
19		if d := n[i], d < 'A' {
20			sum -= inc[p][d-'0']
21		} else {
22			d -= 'A'
23			sum += inc[p][d%10]
24			p = 1 - p
25			sum += inc[p][d/10+1]
26  		}
27  	}
28  	sum += int(n[11] - '0')
29  	return sum%10 == 0
30 }
31 package main
32  
33 import "testing"
34 
35 func TestValidISIN(t *testing.T) {
36 	testcases := []struct {
37 		isin  string
38		valid bool
39	}{
40		{"US0378331005", true},
41		{"US0373831005", false},
42		{"U50378331005", false},
43		{"US03378331005", false},
44		{"AU0000XVGZA3", true},
45		{"AU0000VXGZA3", true},
46		{"FR0000988040", true},
47	}
48 
49	for _, testcase := range testcases {
50		actual := ValidISIN(testcase.isin)
51		if actual != testcase.valid {
52			t.Errorf("expected %v for %q, got %v",
53				testcase.valid, testcase.isin, actual)
54		}
55	}
56 }