Validate International Securities Identification Number

From Rosetta Code
Revision as of 12:00, 23 February 2015 by rosettacode>TheWombat
Task
Validate International Securities Identification Number
You are encouraged to solve this task according to the task description, using any language you may know.

Calculate an International Securities Identification Number (ISIN)

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

It consists of an exchange identifier, usually a two character ISO country code, followed by nine characters to identify the security. If the security code is less then nine characters, it is left-padded with zeroes (ASCII character 48). The final character is a checksum between '0' and '9' (ASCII 48 to 57).

VB6

<lang VB6> Option Explicit

Function MakeIsinCode(Exchange As String, security As String)

   Dim numLeadingZeroes As Integer
   
   numLeadingZeroes = 9 - Len(security)
   
   Dim leader As String
   
   leader = Exchange & String(numLeadingZeroes, "0") & security
   
   MakeIsinCode = leader & CStr(IsinCheckDigit(leader))

End Function

Function IsinCheckDigit(ByVal security As String) As Integer

   Dim digits As String
   
   Dim i As Integer
   
   For i = 1 To Len(security)
       Dim ch As String
       
       ch = UCase(Mid(security, i, 1))
       
       If ch >= "A" And ch <= "Z" Then
           ' A to Z translated to "10", "11", .. "35"
           digits = digits & CStr(Asc(ch) - 55)
       ElseIf ch >= "0" And ch <= "9" Then
           digits = digits & ch
       Else
           Err.Raise 50001, , "Security must contain only letters and digits"
       End If
   Next
   
   Dim total As Integer
   Dim tmp As Integer
   
   total = 0
   
   'If rightmost even, "other" digits for doubling are 2,4,6. If rightmost odd, they're 1,3,5.
   'rightmost digit is always doubled, so start with it and work backwards
   Dim other As Boolean
   other = True
   
   For i = Len(digits) To 1 Step -1
       tmp = CInt(Mid(digits, i, 1))
       
       If other Then
           If tmp < 5 Then
               ' 0 to 4 map to 0,2,4,6,8
               total = total + (tmp * 2)
           Else
               ' 5 to 9 map to 1,3,5,7,9
               total = total + ((tmp * 2) - 9)
           End If
       Else
           total = total + tmp
       End If
       
       'Toggle doubling flag
       other = Not other
   Next
   
   'Last Mod 10 is to wrap 10 to zero
   IsinCheckDigit = (10 - (total Mod 10)) Mod 10

End Function


</lang>