CUSIP: Difference between revisions

44,128 bytes added ,  1 month ago
 
(48 intermediate revisions by 29 users not shown)
Line 17:
 
;Example pseudo-code below.
<syntaxhighlight lang=text>algorithm Cusip-Check-Digit(cusip) is
Input: an 8-character CUSIP
 
Line 43:
return (10 - (sum mod 10)) mod 10
end function</langsyntaxhighlight>
 
;See related tasks:
Line 49:
* [[Validate_International_Securities_Identification_Number|ISIN]]
<br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang=11l>F cusip_check(=cusip)
I cusip.len != 9
X.throw ValueError(‘CUSIP must be 9 characters’)
 
cusip = cusip.uppercase()
V total = 0
L(i) 8
V v = 0
V c = cusip[i]
I c.is_digit()
v = Int(c)
E I c.is_alpha()
V p = c.code - ‘A’.code + 1
v = p + 9
E I c == ‘*’
v = 36
E I c == ‘@’
v = 37
E I c == ‘#’
v = 38
 
I i % 2 != 0
v *= 2
 
total += v I/ 10 + v % 10
V check = (10 - (total % 10)) % 10
R String(check) == cusip.last
 
V codes = [‘037833100’,
‘17275R102’,
‘38259P508’,
‘594918104’,
‘68389X106’,
‘68389X105’]
L(code) codes
print(code‘: ’(I cusip_check(code) {‘valid’} E ‘invalid’))</syntaxhighlight>
 
{{out}}
<pre>
037833100: valid
17275R102: valid
38259P508: valid
594918104: valid
68389X106: invalid
68389X105: valid
</pre>
 
=={{header|360 Assembly}}==
<langsyntaxhighlight lang=360asm>* CUSIP 07/06/2018
CUSIP CSECT
USING CUSIP,R13 base register
Line 131 ⟶ 181:
PG DC CL80'CUSIP ......... is... valid'
YREGS
END CUSIP</langsyntaxhighlight>
{{out}}
<pre>
Line 140 ⟶ 190:
CUSIP 68389X106 isn't valid
CUSIP 68389X105 is valid
</pre>
 
=={{header|Action!}}==
{{libheader|Action! Tool Kit}}
<syntaxhighlight lang=Action!>INCLUDE "D2:CHARTEST.ACT" ;from the Action! Tool Kit
 
BYTE FUNC Verify(CHAR ARRAY code)
BYTE i,c,v
CARD sum
 
IF code(0)#9 THEN
RETURN (0)
ELSEIF IsDigit(code(1))=0 THEN
RETURN (0)
FI
 
sum=0
FOR i=2 TO code(0)
DO
c=code(i)
IF IsDigit(c) THEN
v=c-'0
ELSEIF IsAlpha(c) THEN
v=ToUpper(c)-'A+10
ELSEIF c='* THEN
v=36
ELSEIF c='@ THEN
v=37
ELSEIF c='# THEN
v=38
ELSE
RETURN (0)
FI
 
IF (i&1)=0 THEN
v==*2
FI
 
sum==+v/10+v MOD 10
OD
 
v=(10-(sum MOD 10)) MOD 10
IF v#code(1)-'0 THEN
RETURN (0)
FI
RETURN (1)
 
PROC Test(CHAR ARRAY code)
Print(code)
IF Verify(code) THEN
PrintE(" is valid")
ELSE
PrintE(" is invalid")
FI
RETURN
 
PROC Main()
Put(125) PutE() ;clear the screen
Test("037833100")
Test("17275R102")
Test("38259P508")
Test("594918104")
Test("68389X106")
Test("68389X105")
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/CUSIP.png Screenshot from Atari 8-bit computer]
<pre>
037833100 is valid
17275R102 is valid
38259P508 is valid
594918104 is valid
68389X106 is invalid
68389X105 is valid
</pre>
 
=={{header|Ada}}==
<langsyntaxhighlight lang=Ada>with Ada.Text_IO;
 
procedure Cusip_Test is
Line 196 ⟶ 320:
end if;
end loop;
end Cusip_Test;</langsyntaxhighlight>
{{Out}}
<pre>037833100: valid
Line 207 ⟶ 331:
 
=={{header|ALGOL 68}}==
<langsyntaxhighlight lang=algol68>BEGIN
# returns TRUE if cusip is a valid CUSIP code #
OP ISCUSIP = ( STRING cusip )BOOL:
Line 255 ⟶ 379:
test cusip( "68389X106" );
test cusip( "68389X105" )
END</langsyntaxhighlight>
{{out}}
<pre>
Line 268 ⟶ 392:
=={{header|ALGOL W}}==
Based on Algol 68
<langsyntaxhighlight lang=algolw>begin % returns true if cusip is a valid CUSIP code %
logical procedure isCusip ( string(9) value cusip ) ;
begin
Line 302 ⟶ 426:
testCusip( "68389X105" )
end testCases
end.</langsyntaxhighlight>
{{out}}
<pre>
Line 312 ⟶ 436:
68389X105 valid
</pre>
 
=={{header|AppleScript}}==
<syntaxhighlight lang=applescript>use AppleScript version "2.4"
use framework "Foundation"
use scripting additions
 
 
-- isCusip :: String -> Bool
on isCusip(s)
set cs to "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ*&#"
set ns to mapMaybe(elemIndex(cs), s)
script go
on |λ|(f, x)
set fx to apply(f, x)
(fx div 10) + (fx mod 10)
end |λ|
end script
9 = length of ns and item -1 of ns = (10 - (sum(zipWith(go, ¬
cycle({my identity, my double}), ¬
take(8, ns))) mod 10)) mod 10
end isCusip
 
 
-------------------------- TEST ---------------------------
on run
script test
on |λ|(s)
s & " -> " & isCusip(s)
end |λ|
end script
unlines(map(test, ¬
{"037833100", "17275R102", "38259P508", ¬
"594918104", "68389X106", "68389X105"}))
end run
 
-- 037833100 -> true
-- 17275R102 -> true
-- 38259P508 -> true
-- 594918104 -> true
-- 68389X106 -> false
-- 68389X105 -> true
 
 
-------------------- GENERIC FUNCTIONS --------------------
 
-- Just :: a -> Maybe a
on Just(x)
-- Constructor for an inhabited Maybe (option type) value.
-- Wrapper containing the result of a computation.
{type:"Maybe", Nothing:false, Just:x}
end Just
 
 
-- Nothing :: Maybe a
on Nothing()
-- Constructor for an empty Maybe (option type) value.
-- Empty wrapper returned where a computation is not possible.
{type:"Maybe", Nothing:true}
end Nothing
 
 
-- Tuple (,) :: a -> b -> (a, b)
on Tuple(a, b)
-- Constructor for a pair of values, possibly of two different types.
{type:"Tuple", |1|:a, |2|:b, length:2}
end Tuple
 
 
-- apply ($) :: (a -> b) -> a -> b
on apply(f, x)
-- The value of f(x)
mReturn(f)'s |λ|(x)
end apply
 
 
-- cycle :: [a] -> Generator [a]
on cycle(xs)
script
property lng : 1 + (length of xs)
property i : missing value
on |λ|()
if missing value is i then
set i to 1
else
set nxt to (1 + i) mod lng
if 0 = ((1 + i) mod lng) then
set i to 1
else
set i to nxt
end if
end if
return item i of xs
end |λ|
end script
end cycle
 
 
-- double :: Num -> Num
on double(x)
2 * x
end double
 
 
-- elemIndex :: Eq a => [a] -> a -> Maybe Int
on elemIndex(xs)
script
on |λ|(x)
set lng to length of xs
repeat with i from 1 to lng
if x = (item i of xs) then return Just(i - 1)
end repeat
return Nothing()
end |λ|
end script
end elemIndex
 
 
-- identity :: a -> a
on identity(x)
-- The argument unchanged.
x
end identity
 
 
-- foldl :: (a -> b -> a) -> a -> [b] -> a
on foldl(f, startValue, xs)
tell mReturn(f)
set v to startValue
set lng to length of xs
repeat with i from 1 to lng
set v to |λ|(v, item i of xs, i, xs)
end repeat
return v
end tell
end foldl
 
 
-- length :: [a] -> Int
on |length|(xs)
set c to class of xs
if list is c or string is c then
length of xs
else
(2 ^ 29 - 1) -- (maxInt - simple proxy for non-finite)
end if
end |length|
 
 
-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
-- The list obtained by applying f
-- to each element of xs.
tell mReturn(f)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, i, xs)
end repeat
return lst
end tell
end map
 
 
-- The mapMaybe function is a version of map which can throw out
-- elements. In particular, the functional argument returns
-- something of type Maybe b. If this is Nothing, no element is
-- added on to the result list. If it just Just b, then b is
-- included in the result list.
-- mapMaybe :: (a -> Maybe b) -> [a] -> [b]
on mapMaybe(mf, xs)
script
property g : mReturn(mf)
on |λ|(a, x)
set mb to g's |λ|(x)
if Nothing of mb then
a
else
a & (Just of mb)
end if
end |λ|
end script
foldl(result, {}, xs)
end mapMaybe
 
 
-- min :: Ord a => a -> a -> a
on min(x, y)
if y < x then
y
else
x
end if
end min
 
 
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
-- 2nd class handler function lifted into 1st class script wrapper.
if script is class of f then
f
else
script
property |λ| : f
end script
end if
end mReturn
 
 
-- sum :: [Num] -> Num
on sum(xs)
script add
on |λ|(a, b)
a + b
end |λ|
end script
foldl(add, 0, xs)
end sum
 
 
-- take :: Int -> [a] -> [a]
-- take :: Int -> String -> String
on take(n, xs)
set c to class of xs
if list is c then
if 0 < n then
items 1 thru min(n, length of xs) of xs
else
{}
end if
else if string is c then
if 0 < n then
text 1 thru min(n, length of xs) of xs
else
""
end if
else if script is c then
set ys to {}
repeat with i from 1 to n
set v to |λ|() of xs
if missing value is v then
return ys
else
set end of ys to v
end if
end repeat
return ys
else
missing value
end if
end take
 
 
-- unlines :: [String] -> String
on unlines(xs)
-- A single string formed by the intercalation
-- of a list of strings with the newline character.
set {dlm, my text item delimiters} to ¬
{my text item delimiters, linefeed}
set str to xs as text
set my text item delimiters to dlm
str
end unlines
 
 
-- zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
on zipWith(f, xs, ys)
set lng to min(|length|(xs), |length|(ys))
if 1 > lng then return {}
set xs_ to take(lng, xs) -- Allow for non-finite
set ys_ to take(lng, ys) -- generators like cycle etc
set lst to {}
tell mReturn(f)
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs_, item i of ys_)
end repeat
return lst
end tell
end zipWith</syntaxhighlight>
{{Out}}
<pre>037833100 -> true
17275R102 -> true
38259P508 -> true
594918104 -> true
68389X106 -> false
68389X105 -> true</pre>
 
=={{header|Arturo}}==
{{trans|Ruby}}
<syntaxhighlight lang=rebol>validCUSIP?: function [cusip][
s: 0
alpha: `A`..`Z`
 
loop.with:'i chop cusip 'c [
v: 0
 
case ø
when? [numeric? c] -> v: to :integer to :string c
when? [in? c alpha] -> v: (index alpha c) + 1 + 9
when? [c = `*`] -> v: 36
when? [c = `@`] -> v: 37
when? [c = `#`] -> v: 38
else []
 
if odd? i -> v: 2 * v
 
s: s + (v / 10) + (v % 10)
]
check: (10 - (s % 10)) % 10
 
return check = to :integer to :string last cusip
]
 
loop ["037833100" "17275R102" "38259P508" "594918104" "68389X106" "68389X105"] 'cusip [
print [cusip "=>" (validCUSIP? cusip)? -> "VALID" -> "INVALID"]
]</syntaxhighlight>
 
{{out}}
 
<pre>037833100 => VALID
17275R102 => VALID
38259P508 => VALID
594918104 => VALID
68389X106 => INVALID
68389X105 => VALID</pre>
 
=={{header|AutoHotkey}}==
<syntaxhighlight lang=AutoHotkey>Cusip_Check_Digit(cusip){
sum := 0, i := 1, x := StrSplit(cusip)
while (i <= 8) {
c := x[i]
if c is digit
v := c
else if c is alpha
v := Asc(c) - 64 + 9
else if (c = "*")
v := 36
else if (c = "@")
v := 37
else if (c = "#")
v := 38
if (i/2 = Floor(i/2))
v *= 2
sum += Floor(v/10) + Mod(v, 10)
i++
}
return (Mod(10 - Mod(sum, 10), 10) = x[9])
}</syntaxhighlight>
Examples:<syntaxhighlight lang=AutoHotkey>data =
(
037833100
17275R102
38259P508
594918104
68389X106
68389X105
)
 
output := "Cusip`t`tValid`n"
loop, Parse, data, `n, `r
output .= A_LoopField "`t" Cusip_Check_Digit(A_LoopField) "`n"
MsgBox % output</syntaxhighlight>
{{out}}
<pre>Cusip Valid
037833100 1
17275R102 1
38259P508 1
594918104 1
68389X106 0
68389X105 1</pre>
 
=={{header|AWK}}==
<langsyntaxhighlight lang=AWK>
# syntax: GAWK -f CUSIP.AWK
BEGIN {
Line 356 ⟶ 853:
return(substr(n,9,1) == x ? 1 : 0)
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 366 ⟶ 863:
68389X105 1
</pre>
 
=={{header|BASIC}}==
==={{header|FreeBASIC}}===
<syntaxhighlight lang=freebasic>' version 04-04-2017
' compile with: fbc -s console
 
sub cusip(input_str As String)
 
Print input_str;
If Len(input_str) <> 9 Then
Print " length is incorrect, invalid cusip"
Return
End If
 
Dim As Long i, v , sum
Dim As UByte x
 
For i = 1 To 8
x = input_str[i-1]
Select Case x
Case Asc("0") To Asc("9")
v = x - Asc("0")
Case Asc("A") To Asc("Z")
v = x - Asc("A") + 1 + 9
Case Asc("*")
v= 36
Case Asc("@")
v = 37
Case Asc("#")
v = 38
Case Else
Print " found a invalid character, invalid cusip"
return
End Select
 
If (i And 1) = 0 Then v = v * 2
sum = sum + v \ 10 + v Mod 10
Next
 
sum = (10 - (sum Mod 10)) Mod 10
If sum = (input_str[8] - Asc("0")) Then
Print " is valid"
Else
Print " is invalid"
End If
 
End Sub
 
' ------=< MAIN >=------
 
Data "037833100", "17275R102", "38259P508"
Data "594918104", "68389X106", "68389X105"
 
Dim As String input_str
 
Print
For i As Integer = 1 To 6
Read input_str
cusip(input_str)
Next
 
' empty keyboard buffer
While InKey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End</syntaxhighlight>
{{out}}
<pre>037833100 is valid
17275R102 is valid
38259P508 is valid
594918104 is valid
68389X106 is invalid
68389X105 is valid</pre>
 
==={{header|VBA}}===
<syntaxhighlight lang=vb>Private Function Cusip_Check_Digit(s As Variant) As Integer
Dim Sum As Integer, c As String, v As Integer
For i = 1 To 8
c = Mid(s, i, 1)
If IsNumeric(c) Then
v = Val(c)
Else
Select Case c
Case "a" To "z"
v = Asc(c) - Asc("a") + 10
Case "A" To "Z"
v = Asc(c) - Asc("A") + 10
Case "*"
v = 36
Case "@"
v = 37
Case "#"
v = 38
Case Else
Debug.Print "not expected"
End Select
End If
If i Mod 2 = 0 Then v = v * 2
Sum = Sum + Int(v \ 10) + v Mod 10
Next i
Cusip_Check_Digit = (10 - (Sum Mod 10)) Mod 10
End Function</syntaxhighlight>{{out}}
<pre>037833100 is valid
17275R102 is valid
38259P508 is valid
594918104 is valid
68389X106 not valid
68389X105 is valid</pre>
 
==={{header|Visual Basic .NET}}===
{{trans|C#}}
<syntaxhighlight lang=vbnet>Module Module1
 
Function IsCUSIP(s As String) As Boolean
If s.Length <> 9 Then
Return False
End If
 
Dim sum = 0
For i = 0 To 7
Dim c = s(i)
 
Dim v As Integer
If "0" <= c AndAlso c <= "9" Then
v = Asc(c) - 48
ElseIf "A" <= c AndAlso c <= "Z" Then
v = Asc(c) - 55 ' Lower case letters are apparently invalid
ElseIf c = "*" Then
v = 36
ElseIf c = "#" Then
v = 38
Else
Return False
End If
 
If i Mod 2 = 1 Then
v *= 2 ' check if odd as using 0-based indexing
End If
sum += v \ 10 + v Mod 10
Next
Return Asc(s(8)) - 48 = (10 - (sum Mod 10)) Mod 10
End Function
 
Sub Main()
Dim candidates As New List(Of String) From {
"037833100",
"17275R102",
"38259P508",
"594918104",
"68389X106",
"68389X105"
}
 
For Each candidate In candidates
Console.WriteLine("{0} -> {1}", candidate, If(IsCUSIP(candidate), "correct", "incorrect"))
Next
End Sub
 
End Module</syntaxhighlight>
{{out}}
<pre>037833100 -> correct
17275R102 -> correct
38259P508 -> correct
594918104 -> correct
68389X106 -> incorrect
68389X105 -> correct</pre>
 
==={{header|Yabasic}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang=Yabasic>sub cusip(inputStr$)
local i, v, sum, x$
Print inputStr$;
If Len(inputStr$) <> 9 Print " length is incorrect, invalid cusip" : return
For i = 1 To 8
x$ = mid$(inputStr$, i, 1)
switch x$
Case "*": v = 36 : break
Case "@": v = 37 : break
Case "#": v = 38 : break
default:
if x$ >= "A" and x$ <= "Z" then
v = asc(x$) - Asc("A") + 10
elsif x$ >= "0" and x$ <= "9" then
v = asc(x$) - asc("0")
else
Print " found a invalid character, invalid cusip"
return
end if
End switch
If and(i, 1) = 0 v = v * 2
sum = sum + int(v / 10) + mod(v, 10)
Next
sum = mod(10 - mod(sum, 10), 10)
If sum = asc(mid$(inputStr$, 9, 1)) - Asc("0") Then
Print " is valid"
Else
Print " is invalid"
End If
End Sub
// ------=< MAIN >=------
Data "037833100", "17275R102", "38259P508"
Data "594918104", "68389X106", "68389X105", ""
Print
do
Read inputStr$
if inputStr$ = "" break
cusip(inputStr$)
loop
</syntaxhighlight>
 
=={{header|BCPL}}==
<syntaxhighlight lang=bcpl>get "libhdr"
 
let validcusip(c) = valof
$( let sum = 0
unless c%0 = 9 resultis false
for i = 1 to 8 do
$( let v = ( 2 - (i & 1) ) * valof
$( test '0' <= c%i <= '9'
then resultis c%i - '0'
or test 'A' <= c%i <= 'Z'
then resultis 10 + c%i - 'A'
or test c%i = '**'
then resultis 36
or test c%i = '@'
then resultis 37
or test c%i = '#'
then resultis 38
else resultis -1
$)
sum := sum + v/10 + v rem 10
$)
resultis (10 - (sum rem 10)) rem 10 = c%9 - '0'
$)
 
let show(c) be
writef("%S: %Svalid*N", c, validcusip(c) -> "", "in")
let start() be
$( show("037833100")
show("17275R102")
show("38259P508")
show("594918104")
show("68389X106")
show("68389X105")
$)</syntaxhighlight>
{{out}}
<pre>037833100: valid
17275R102: valid
38259P508: valid
594918104: valid
68389X106: invalid
68389X105: valid</pre>
 
=={{header|C}}==
Reads CUSIP strings from a file and prints results to console, usage printed on incorrect invocation.
<syntaxhighlight lang=C>
<lang C>
#include<stdlib.h>
#include<stdio.h>
Line 423 ⟶ 1,181:
return 0;
}
</syntaxhighlight>
</lang>
Input file :
<pre>
Line 449 ⟶ 1,207:
=={{header|C sharp|C#}}==
{{trans|Java}}
<langsyntaxhighlight lang=csharp>using System;
using System.Collections.Generic;
 
Line 465 ⟶ 1,223:
}
else if (c >= 'A' && c <= 'Z') {
v = c - 6455; // lower case letters apparently invalid
}
else if (c == '*') {
Line 496 ⟶ 1,254:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>037833100 -> correct
Line 507 ⟶ 1,265:
=={{header|C++}}==
{{trans|C#}}
<langsyntaxhighlight lang=cpp>#include <iostream>
#include <vector>
 
Line 521 ⟶ 1,279:
v = c - '0';
} else if ('A' <= c && c <= 'Z') {
v = c - '@A' + 10;
} else if (c = '*') {
v = 36;
} else if (c = '@') {
v = 37;
} else if (c = '#') {
v = 38;
Line 555 ⟶ 1,315:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>037833100 -> correct
Line 566 ⟶ 1,326:
=={{header|Caché ObjectScript}}==
 
<langsyntaxhighlight lang=cos>Class Utils.Check [ Abstract ]
{
 
Line 584 ⟶ 1,344:
}
 
}</langsyntaxhighlight>
{{out|Examples}}
<pre>USER>For { Read s Quit:s="" Write ": "_##class(Utils.Check).CUSIP(s), ! }
Line 597 ⟶ 1,357:
 
=={{header|Clojure}}==
<langsyntaxhighlight lang=Clojure>
(defn- char->value
"convert the given char c to a value used to calculate the cusip check sum"
Line 604 ⟶ 1,364:
(cond
(and (>= int-char (int \0)) (<= int-char (int \9))) (- int-char 48)
(and (>= int-char (int \A)) (<= int-char (int \Z))) (- int-char 6455)
(= c \*) 36
(= c \@) 37
Line 641 ⟶ 1,401:
"show some nice output for the Rosetta Wiki"
[]
(doseq [cusip ["037833100" "17275R102" "38259P508" "594918104" "68389X106" "68389X105" "EXTRACRD8"
"EXTRACRD8EXTRACRD9" "BADCUSIP!" "683&9X106" "68389x105" "683$9X106" "68389}105" "87264ABE4"]]
(println cusip (if (is-valid-cusip9? cusip) "valid" "invalid"))))
</syntaxhighlight>
</lang>
 
{{out}}
Line 655 ⟶ 1,415:
68389X106 invalid
68389X105 valid
EXTRACRD8 validinvalid
EXTRACRD9 valid
BADCUSIP! invalid
683&9X106 invalid
Line 661 ⟶ 1,422:
683$9X106 invalid
68389}105 invalid
87264ABE4 valid
</pre>
 
=={{header|CLU}}==
<syntaxhighlight lang=clu>valid_cusip = proc (s: string) returns (bool)
own chars: string := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ*@#"
if string$size(s) ~= 9 then return(false) end
sum: int := 0
for i: int in int$from_to(1,8) do
v: int := string$indexc(s[i], chars)-1
if v<0 then return(false) end
if i//2=0 then v := v*2 end
sum := sum + v/10 + v//10
end
check: int := (10 - sum // 10) // 10
return(check = string$indexc(s[9], chars)-1)
end valid_cusip
 
start_up = proc ()
po: stream := stream$primary_output()
cusips: array[string] := array[string]$[
"037833100",
"17275R102",
"38259P508",
"594918104",
"68389X106",
"68389X105"
]
for cusip: string in array[string]$elements(cusips) do
stream$puts(po, cusip || ": ")
if valid_cusip(cusip)
then stream$putl(po, "valid")
else stream$putl(po, "invalid")
end
end
end start_up</syntaxhighlight>
{{out}}
<pre>037833100: valid
17275R102: valid
38259P508: valid
594918104: valid
68389X106: invalid
68389X105: valid</pre>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang=lisp>(defun char->value (c)
(cond ((digit-char-p c 36))
((char= c #\*) 36)
Line 686 ⟶ 1,490:
(defun main ()
(dolist (cusip '("037833100" "17275R102" "38259P508" "594918104" "68389X106" "68389X105"))
(format t "~A: ~A~%" cusip (cusip-p cusip))))</langsyntaxhighlight>
{{out}}
<pre>037833100: T
Line 696 ⟶ 1,500:
 
=={{header|D}}==
<langsyntaxhighlight lang=D>import std.stdio;
 
void main(string[] args) {
Line 794 ⟶ 1,598:
}
 
/// Invoke with `cusip 037833100 17275R102 38259P508 594918104 68389X106 68389X105`</langsyntaxhighlight>
 
{{out}}
Line 804 ⟶ 1,608:
68389X106 : Invalid
68389X105 : Valid</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
Using sets to simplify string parsing
 
<syntaxhighlight lang="Delphi">
type TCUSIPInfo = record
ID,Company: string;
end;
 
var CUSIPArray: array [0..5] of TCUSIPInfo = (
(ID:'037833100'; Company: 'Apple Incorporated'),
(ID:'17275R102'; Company: 'Cisco Systems'),
(ID:'38259P508'; Company: 'Google Incorporated'),
(ID:'594918104'; Company: 'Microsoft Corporation'),
(ID:'68389X106'; Company: 'Oracle Corporation'),
(ID:'68389X105'; Company: 'Oracle Corporation'));
 
function IsValidCUSIP(Info: TCUSIPInfo): boolean;
{Calculate checksum on first 7 chars of CUSIP }
{And compare with the last char - the checksum char}
var I,V,Sum: integer;
var C: char;
begin
Sum:=0;
for I:=1 to Length(Info.ID)-1 do
begin
C:=Info.ID[I];
if C in ['0'..'9'] then V:=byte(C)-$30
else if C in ['A'..'Z'] then V:=(byte(C)-$40) + 9
else case C of
'*': V:=36;
'@': V:=37;
'#': V:=38;
end;
if (I and 1)=0 then V:=V*2;
Sum:=Sum + (V div 10) + (V mod 10);
end;
Sum:=(10 - (Sum mod 10)) mod 10;
Result:=StrToInt(Info.ID[Length(Info.ID)])=Sum;
end;
 
 
procedure TestCUSIPList(Memo: TMemo);
{Test every item in the CSUIP array}
var I: integer;
var S: string;
begin
for I:=0 to High(CUSIPArray) do
begin
if IsValidCUSIP(CUSIPArray[I]) then S:='Valid' else S:='Invalid';
Memo.Lines.Add(CUSIPArray[I].ID+' '+CUSIPArray[I].Company+': '+S);
end;
end;
 
</syntaxhighlight>
{{out}}
<pre>
037833100 Apple Incorporated: Valid
17275R102 Cisco Systems: Valid
38259P508 Google Incorporated: Valid
594918104 Microsoft Corporation: Valid
68389X106 Oracle Corporation: Invalid
68389X105 Oracle Corporation: Valid
 
</pre>
 
 
=={{header|Dyalect}}==
Line 809 ⟶ 1,681:
{{trans|Go}}
 
<langsyntaxhighlight lang=dyalect>func isCusip(s) {
if s.lenLength() != 9 { return false }
var sum = 0
for i in 0..7 {
Line 816 ⟶ 1,688:
var v =
match c {
'0'..'9' => Integer(c.Order() - 48,
'A'..'Z' => Integer(c.Order() - 6455,
'*' => 36,
'@' => 37,
Line 826 ⟶ 1,698:
sum += v / 10 + v % 10
}
Integer(s[8].Order() - 48 == (10 - (sum % 10)) % 10
}
Line 837 ⟶ 1,709:
"68389X105"
]
 
for candidate in candidates {
var b =
Line 846 ⟶ 1,718:
}
print("\(candidate) -> \(b)")
}</langsyntaxhighlight>
 
{{out}}
Line 857 ⟶ 1,729:
68389X105 -> correct</pre>
 
=={{header|EasyLang}}==
<syntaxhighlight lang=easylang>
func check inp$ .
for i = 1 to 8
c = strcode substr inp$ i 1
if c >= 48 and c <= 57
v = c - 48
elif c >= 65 and c <= 91
v = c - 64 + 9
elif c = 42
v = 36
elif c = 64
v = 37
elif c = 35
v = 38
.
if i mod 2 = 0
v *= 2
.
sum += v div 10 + v mod 10
.
return if (10 - (sum mod 10)) mod 10 = number substr inp$ 9 1
.
for s$ in [ "037833100" "17275R102" "38259P508" "594918104" "68389X106" "68389X105" ]
write s$ & " is "
if check s$ = 1
print "valid"
else
print "invalid"
.
.
</syntaxhighlight>
 
 
=={{header|Excel}}==
===LAMBDA===
 
Binding the names ISCUSIP and CUSIPMAP to the following lambda expressions in the Name Manager of the Excel WorkBook:
 
(See [https://www.microsoft.com/en-us/research/blog/lambda-the-ultimatae-excel-worksheet-function/ LAMBDA: The ultimate Excel worksheet function])
 
<syntaxhighlight lang=lisp>=LAMBDA(s,
LET(
ns, VLOOKUP(
CHARS(s), CUSIPMAP, 2, FALSE
),
AND(
9 = COLUMNS(ns),
LET(
firstEight, INITCOLS(ns),
ixs, SEQUENCE(1, 8),
evensDoubled, IF(ISEVEN(ixs),
2 * INDEX(firstEight, 1, ixs),
INDEX(firstEight, 1, ixs)
),
LASTCOL(ns) = MOD(
10 - MOD(
SUM(
QUOTIENT(evensDoubled, 10),
MOD(evensDoubled, 10)
),
10
),
10
)
)
)
)
)
 
 
CUSIPMAP
={"0",0;"1",1;"2",2;"3",3;"4",4;"5",5;"6",6;"7",7;"8",8;"9",9;"A",
10;"B",11;"C",12;"D",13;"E",14;"F",15;"G",16;"H",17;"I",18;"J",19;"K",
20;"L",21;"M",22;"N",23;"O",24;"P",25;"Q",26;"R",27;"S",28;"T",29;"U",
30;"V",31;"W",32;"X",33;"Y",34;"Z",35;"*",36;"@",37;"#",38}</syntaxhighlight>
 
and also assuming the following generic bindings in the Name Manager for the WorkBook:
 
<syntaxhighlight lang=lisp>CHARS
=LAMBDA(s,
MID(
s,
SEQUENCE(1, LEN(s), 1, 1),
1
)
)
 
 
INITCOLS
=LAMBDA(xs,
INDEX(
xs,
SEQUENCE(
1,
COLUMNS(xs) - 1,
1,
)
)
)
 
 
LASTCOL
=LAMBDA(xs,
INDEX(
xs,
SEQUENCE(ROWS(xs), 1, 1, 1),
COLUMNS(xs)
)
)</syntaxhighlight>
 
{{Out}}
{| class="wikitable"
|-
|||style="text-align:right; font-family:serif; font-style:italic; font-size:120%;"|fx
! colspan="2" style="text-align:left; vertical-align: bottom; font-family:Arial, Helvetica, sans-serif !important;"|=ISCUSIP(A2)
|- style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff;"
|
| A
| B
|- style="text-align:right;"
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 1
| style="text-align:right; font-weight:bold" | Strings
| style="font-weight:bold" | CUSIP verdicts
|- style="text-align:right;"
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 2
| style="text-align:right; font-weight:bold" | 037833100
| style="background-color:#cbcefb;" | TRUE
|- style="text-align:right;"
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 3
| style="text-align:right; font-weight:bold" | 17275R102
| TRUE
|- style="text-align:right;"
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 4
| style="text-align:right; font-weight:bold" | 38259P508
| TRUE
|- style="text-align:right;"
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 5
| style="text-align:right; font-weight:bold" | 594918104
| TRUE
|- style="text-align:right;"
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 6
| style="text-align:right; font-weight:bold" | 68389X106
| FALSE
|- style="text-align:right;"
| style="text-align:center; font-family:Arial, Helvetica, sans-serif !important; background-color:#000000; color:#ffffff" | 7
| style="text-align:right; font-weight:bold" | 68389X105
| TRUE
|}
 
=={{header|F_Sharp|F#}}==
<syntaxhighlight lang=fsharp>
// Validate CUSIP: Nigel Galloway. June 2nd., 2021
let fN=function n when n>47 && n<58->n-48 |n when n>64 && n<91->n-55 |42->36 |64->37 |_->38
let cD(n:string)=(10-(fst((n.[0..7])|>Seq.fold(fun(z,n)g->let g=(fN(int g))*(n+1) in (z+g/10+g%10,(n+1)%2))(0,0)))%10)%10=int(n.[8])-48
["037833100";"17275R102";"38259P508";"594918104";"68389X103";"68389X105"]|>List.iter(fun n->printfn "CUSIP %s is %s" n (if cD n then "valid" else "invalid"))
</syntaxhighlight>
{{out}}
<pre>
CUSIP 037833100 is valid
CUSIP 17275R102 is valid
CUSIP 38259P508 is valid
CUSIP 594918104 is valid
CUSIP 68389X103 is invalid
CUSIP 68389X105 is valid
Real: 00:00:00.009
</pre>
=={{header|Factor}}==
<langsyntaxhighlight lang=factor>USING: combinators.short-circuit formatting kernel math
math.parser qw regexp sequences unicode ;
IN: rosetta-code.cusip
Line 875 ⟶ 1,918:
 
qw{ 037833100 17275R102 38259P508 594918104 68389X106 68389X105 }
[ dup cusip? "correct" "incorrect" ? "%s -> %s\n" printf ] each</langsyntaxhighlight>
{{out}}
<pre>
Line 891 ⟶ 1,934:
The source does not bother with the MODULE protocol of F90 and later, and so the type of function CUSIPCHECK must be declared in all routines wishing to invoke it. However, the F90 feature of having the END statement of a subroutine or function give its name is to valuable to ignore. The function returns a character code rather than an integer, since the presumption is that it is to be compared to the check character of the code being inspected, which is known as a character not an integer. This means some blather when extracting the eight characters to be presented to CUSIPCHECK and comparing the result to the ninth character, but the test can be done in one expression.
 
There is no checking that only valid characters are presented, nor that eight-character codes only are offered, though the compiler might complain if the function were to be invoked with a text literal of the wrong size. In the absence of such checks, there need be no added complications to support a scheme for reporting such errors. <langsyntaxhighlight lang=Fortran> CHARACTER*1 FUNCTION CUSIPCHECK(TEXT) !Determines the check sum character.
Committee on Uniform Security Identification Purposes, of the American (i.e. USA) Bankers' Association.
CHARACTER*8 TEXT !Specifically, an eight-symbol code.
Line 924 ⟶ 1,967:
END DO
 
END</langsyntaxhighlight>
 
Output: standard output is to I/O unit 6, and free-format (the *) will suffice for this. Each line output starts with a space (in case it is to go to a lineprinter, with carriage control), which is convenient for layout here.
Line 936 ⟶ 1,979:
This would have worked first time, except that a fymgre frmble caused the omission of the digit 2 from the text of VALID. The benefits of checking checksums reach to unexpected places!
 
=={{header|FreeBASIC}}==
<lang freebasic>' version 04-04-2017
' compile with: fbc -s console
 
=={{header|FutureBasic}}==
sub cusip(input_str As String)
<syntaxhighlight lang="futurebasic">
include "NSLog.incl"
 
local fn VerifyCUSIP( cusipStr as CFStringRef ) as CFStringRef
Print input_str;
NSUInteger i, v, sum = 0, count = len(cusipStr)
If Len(input_str) <> 9 Then
CFStringRef resultStr
Print " length is incorrect, invalid cusip"
Return
if count != 9 then exit fn = @"Invalid length"
End If
for i = 0 to 7
unichar x = fn StringCharacterAtIndex( cusipStr, i )
select x
case _"*" : v = 36
case _"@" : v = 37
case _"#" : v = 38
case else
if ( x >= _"0" and x <= _"9" )
v = x - _"0"
else
if ( x >= _"A" and x <= _"Z" )
v = x - _"A" + 10
else
exit fn = fn StringWithFormat( @"Invalid character: %c", x )
end if
end if
end select
if ( i and 1 ) then v = v * 2
sum += (v / 10) + (v mod 10)
next
sum = ((10-(sum mod 10)) mod 10)
if (sum == ( fn StringCharacterAtIndex( cusipStr, 8 ) - _"0" ))
resultStr = @"Valid"
else
resultStr = @"Invalid"
end If
end fn = resultStr
 
NSLog( @"0378331009: %@", fn VerifyCUSIP( @"0378331009" ) ) // Invalid length expected
Dim As Long i, v , sum
NSLog( @"037833100: %@", fn VerifyCUSIP( @"037833100" ) ) // Valid expected
Dim As UByte x
NSLog( @"17275R102: %@", fn VerifyCUSIP( @"17275R102" ) ) // Valid expected
NSLog( @"38259P508: %@", fn VerifyCUSIP( @"38259P508" ) ) // Valid expected
NSLog( @"594918104: %@", fn VerifyCUSIP( @"594918104" ) ) // Valid expected
NSLog( @"68389X106: %@", fn VerifyCUSIP( @"68389X106" ) ) // Invalid expected
NSLog( @"68389X105: %@", fn VerifyCUSIP( @"68389X105" ) ) // Valid expected
NSLog( @"683&9X105: %@", fn VerifyCUSIP( @"683&9X105" ) ) // Invalid character expected: &
 
HandleEvents
For i = 1 To 8
</syntaxhighlight>
x = input_str[i-1]
{{output}}
Select Case x
<pre>
Case Asc("0") To Asc("9")
0378331009: Invalid length
v = x - Asc("0")
037833100: Valid
Case Asc("A") To Asc("Z")
17275R102: Valid
v = x - Asc("A") + 1 + 9
38259P508: Valid
Case Asc("*")
594918104: Valid
v= 36
68389X106: Invalid
Case Asc("@")
68389X105: Valid
v = 37
683&9X105: Invalid character: &
Case Asc("#")
</pre>
v = 38
Case Else
Print " found a invalid character, invalid cusip"
return
End Select
 
If (i And 1) = 0 Then v = v * 2
sum = sum + v \ 10 + v Mod 10
Next
 
sum = (10 - (sum Mod 10)) Mod 10
If sum = (input_str[8] - Asc("0")) Then
Print " is valid"
Else
Print " is invalid"
End If
 
End Sub
 
' ------=< MAIN >=------
 
Data "037833100", "17275R102", "38259P508"
Data "594918104", "68389X106", "68389X105"
 
Dim As String input_str
 
Print
For i As Integer = 1 To 6
Read input_str
cusip(input_str)
Next
 
' empty keyboard buffer
While InKey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End</lang>
{{out}}
<pre>037833100 is valid
17275R102 is valid
38259P508 is valid
594918104 is valid
68389X106 is invalid
68389X105 is valid</pre>
 
=={{header|Go}}==
<langsyntaxhighlight lang=go>package main
 
import "fmt"
Line 1,023 ⟶ 2,059:
v = int(c) - 48
case c >= 'A' && c <= 'Z':
v = int(c) - 6455
case c == '*':
v = 36
Line 1,059 ⟶ 2,095:
}
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,073 ⟶ 2,109:
=={{header|Groovy}}==
{{trans|Java}}
<langsyntaxhighlight lang=groovy>class Cusip {
private static Boolean isCusip(String s) {
if (s.length() != 9) return false
Line 1,084 ⟶ 2,120:
v = c - 48
} else if (c >= ('A' as char) && c <= ('Z' as char)) {
v = c - 6455 // lower case letters apparently invalid
} else if (c == '*' as char) {
v = 36
Line 1,112 ⟶ 2,148:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>037833100 -> correct
Line 1,122 ⟶ 2,158:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang=haskell>import Data.List(elemIndex)
 
data Result = Valid | BadCheck | TooLong | TooShort | InvalidContent deriving Show
 
prependMaybe :: Maybe a -> Maybe [a] -> Maybe [a]
prependMaybe (Just v) (Just vs) = Just (v:vs)
prependMaybe _ _ = Nothing
 
-- convert a list of Maybe to a Maybe list.
-- result is Nothing if any of values from the original list are Nothing
allMaybe :: [Maybe a] -> Maybe [a]
allMaybe = foldr prependMaybe (Just []) sequence
 
toValue :: Char -> Maybe Int
Line 1,169 ⟶ 2,201:
]
 
main = mapM_ putStrLn (fmap (\s -> s ++ ": " ++ show (checkCUSIP s)) testData)</langsyntaxhighlight>
 
{{out}}
Line 1,180 ⟶ 2,212:
</pre>
 
Or, makingpicking some alternativeother selectionspossibilities from Haskell's rich libraries:
<langsyntaxhighlight lang=Haskell>import qualified Data.Map as M (Map, fromList, lookup)
import Data.Maybe (fromMaybe)
 
-------------------------- CUSIP -------------------------
 
cusipMap :: M.Map Char Int
cusipMap =
cusipMap = M.fromList $ zip (['0' .. '9'] ++ ['A' .. 'Z'] ++ "*@#") [0 ..]
M.fromList $
zip (['0' .. '9'] <> ['A' .. 'Z'] <> "*@#") [0 ..]
 
cusipValid :: String -> Bool
cusipValid s =
let ns = (fromMaybe [] . traverse (`M.lookup` cusipMap)) s
in (9 == length ns) &&
&& let qrSum =
sum $
([quot, rem] <*> zipWith id (cycle [id, (* 2)]) (take 8[quot, ns)) <*> [10rem]
in last ns == rem (10 - rem qrSum 10) 10 <*> zipWith
id
(cycle [id, (* 2)])
(take 8 ns)
)
<*> [10]
in last ns == rem (10 - rem qrSum 10) 10
 
--------------------------- TEST -------------------------
main :: IO ()
main =
mapM_
(print . ((,) <*> cusipValid))
[ "037833100",
, "17275R102",
, "38259P508",
, "594918104",
, "68389X106",
, "68389X105"
]</langsyntaxhighlight>
{{Out}}
<pre>("037833100",True)
Line 1,216 ⟶ 2,259:
 
=={{header|Icon}} and {{header|Unicon}}==
<langsyntaxhighlight lang=Icon># cusip.icn -- Committee on Uniform Security Identification Procedures
 
procedure main()
Line 1,255 ⟶ 2,298:
t[chars[n]] := (n - 1)
return t
end</langsyntaxhighlight>
 
{{out}}<pre>037833100 : valid.
Line 1,267 ⟶ 2,310:
=={{header|J}}==
One-liner:
<langsyntaxhighlight lang=j> ccd =. 10 | 10 - 10 | [: +/ [: , 10 (#.^:_1) (8 $ 1 2) * '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ*@#' i. ]
ccd '68389X10'
5</langsyntaxhighlight>
 
More verbose version that checks for correct input:
<langsyntaxhighlight lang=j> CUSIPcheckdigit =. 3 : 0
assert. 8 = $ y NB. Only accept an 8-element long list
assert. */ y e. '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ*@#' NB. Only accept characters from the list of 38
Line 1,281 ⟶ 2,324:
)
addCUSIPcheckdigit =: , CUSIPcheckdigit
verifyCUSIPcheckdigit =: {: = CUSIPcheckdigit@}:</langsyntaxhighlight>
 
Examples:
<langsyntaxhighlight lang=j> addCUSIPcheckdigit '68389X10'
68389X105
verifyCUSIPcheckdigit '68389X106'
Line 1,299 ⟶ 2,342:
│68389X106│0│
│68389X105│1│
└─────────┴─┘</langsyntaxhighlight>
 
=={{header|Java}}==
{{trans|Kotlin}}
Uses Java 9
<langsyntaxhighlight lang=Java>import java.util.List;
 
public class Cusip {
Line 1,317 ⟶ 2,360:
v = c - 48;
} else if (c >= 'A' && c <= 'Z') {
v = c - 6455; // lower case letters apparently invalid
} else if (c == '*') {
v = 36;
Line 1,335 ⟶ 2,378:
public static void main(String[] args) {
List<String> candidates = List.of(
"037833100", "17275R102", "38259P508", "594918104", "68389X106", "68389X105", "EXTRACRD8",
"EXTRACRD9", "BADCUSIP!", "683&9X106", "68389x105", "683$9X106", "68389}105", "87264ABE4"
"17275R102",
"38259P508",
"594918104",
"68389X106",
"68389X105"
);
for (String candidate : candidates) {
Line 1,346 ⟶ 2,385:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>037833100 -> correct
Line 1,354 ⟶ 2,393:
68389X106 -> incorrect
68389X105 -> correct
EXTRACRD8 -> incorrect
EXTRACRD9 -> correct
BADCUSIP! -> incorrect
683&9X106 -> incorrect
68389x105 -> incorrect
683$9X106 -> incorrect
68389}105 -> incorrect
87264ABE4 -> correct
</pre>
 
=={{header|JavaScript}}==
<langsyntaxhighlight lang=javascript>(() => {
'use strict';
 
Line 1,785 ⟶ 2,832:
// MAIN ---
return main();
})();</langsyntaxhighlight>
{{Out}}
<pre>037833100 -> true
Line 1,793 ⟶ 2,840:
68389X106 -> false
68389X105 -> true</pre>
 
=={{header|jq}}==
''Adapted from [[#Wren|Wren]]''
{{works with|jq}}
'''Also works with gojq, the Go implementation of jq, and with jackson-jq and fq.'''
<syntaxhighlight lang=jq>
def isCusip:
length == 9 and
explode as $s
| {sum: 0, i: 0}
| until(. == false or .i == 8;
$s[.i] as $c
| (if ($c >= 48 and $c <= 57) # '0' to '9'
then $c - 48
elif ($c >= 65 and $c <= 90) # 'A' to 'Z'
then $c - 55
elif $c == 42 # '*'
then 36
elif $c == 64 # '@'
then 37
elif $c == 35 # '#'
then 38
else false # return false
end ) as $v
| if $v == false then false
else # check if odd as using 0-based indexing
(if (.i%2 == 1) then 2 * $v else $v end) as $v
| .sum += (($v/10)|floor) + $v%10
| .i += 1
end )
| if . == false then false
else $s[8] - 48 == (10 - (.sum%10)) % 10
end;
 
def candidates: [
"037833100",
"17275R102",
"38259P508",
"594918104",
"68389X106",
"68389X105"
];
 
candidates[]
| "\(.) -> \(if isCusip then "correct" else "incorrect" end)"
</syntaxhighlight>
{{output}}
<pre>
037833100 -> correct
17275R102 -> correct
38259P508 -> correct
594918104 -> correct
68389X106 -> incorrect
68389X105 -> correct
</pre>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
<langsyntaxhighlight lang=julia>module CUSIP
 
function _lastdigitcusip(input::AbstractString)
Line 1,829 ⟶ 2,931:
for code in ("037833100", "17275R102", "38259P508", "594918104", "68389X106", "68389X105")
println("$code is ", CUSIP.checkdigit(code) ? "correct." : "not correct.")
end</langsyntaxhighlight>
 
{{out}}
Line 1,840 ⟶ 2,942:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang=scala>// version 1.1.0
 
fun isCusip(s: String): Boolean {
Line 1,849 ⟶ 2,951:
var v = when (c) {
in '0'..'9' -> c.toInt() - 48
in 'A'..'Z' -> c.toInt() - 6455 // lower case letters apparently invalid
'*' -> 36
'@' -> 37
Line 1,872 ⟶ 2,974:
for (candidate in candidates)
println("$candidate -> ${if(isCusip(candidate)) "correct" else "incorrect"}")
}</langsyntaxhighlight>
 
{{out}}
Line 1,886 ⟶ 2,988:
=={{header|langur}}==
If we don't strictly follow the pseudo-code, we can do this.
<syntaxhighlight lang=langur>val .isCusip = fn(.s) {
 
if .s is not string or len(.s) != 9 {
{{works with|langur|0.8.5}}
<lang langur>val .isCusip = f(.s) {
if not isString(.s) or len(.s) != 9 {
return false
}
 
val .basechars = cp2s('0'..'9') ~ cp2s('A'..'Z') ~ "*@#"
 
val .sum = for[=0] .i of 8 {
Line 1,899 ⟶ 2,999:
if not .v: return false
.v = .v[1]-1
if .i div 2: .v x*= 2
_for += .v \ 10 + .v rem 10
}
Line 1,906 ⟶ 3,006:
}
 
val .candidates = wfw/037833100 17275R102 38259P508 594918104 68389X106 68389X105/
 
for .c in .candidates {
writeln .c, ": ", if(.isCusip(.c): "good" ; "bad")
}</langsyntaxhighlight>
 
Following the pseudo-code would look more like the following.
 
{{works with|langur|0.8.5}}
{{trans|Go}}
<langsyntaxhighlight lang=langur>val .isCusip = ffn(.s) {
if not isString(.s) is not string or len(.s) != 9 {
return false
}
Line 1,925 ⟶ 3,023:
var .v = 0
 
givenswitch[and] .c {
# note: default op between conditions "and"
# Use "case or" to make given act like a switch in some other languages.
case >= '0', <= '9':
.v = .c-'0'
Line 1,941 ⟶ 3,037:
}
 
if .i div 2: .v x*= 2
_for += .v \ 10 + .v rem 10
}
Line 1,952 ⟶ 3,048:
for .c in .candidates {
writeln .c, ": ", if(.isCusip(.c): "good" ; "bad")
}</langsyntaxhighlight>
 
{{out}}
Line 1,964 ⟶ 3,060:
=={{header|Lua}}==
The checkDigit function is a line-for-line translation of the pseudo-code algorithm.
<langsyntaxhighlight lang=Lua>function checkDigit (cusip)
if #cusip ~= 8 then return false end
Line 1,973 ⟶ 3,069:
v = tonumber(c)
elseif c:match("%a") then
p = string.byte(c) - 6455
v = p + 9
elseif c == "*" then
Line 2,007 ⟶ 3,103:
print("INVALID")
end
end</langsyntaxhighlight>
{{out}}
<pre>037833100: VALID
Line 2,015 ⟶ 3,111:
68389X106: INVALID
68389X105: VALID</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<syntaxhighlight lang=Mathematica>ClearAll[Cusip]
rules = Thread[(ToString /@ Range[0, 9]) -> Range[0, 9]]~Join~
Thread[CharacterRange["A", "Z"] -> Range[26] + 9]~Join~
Thread[Characters["*@#"] -> {36, 37, 38}];
Cusip[cusip_String] := Module[{s = cusip, sum = 0, c, value, check},
If[StringLength[s] != 9,
Print["Cusip must be 9 characters!"];
False
,
s = Characters[ToUpperCase[s]];
Do[
c = s[[i]];
value = c /. rules;
If[EvenQ[i], value *= 2];
sum += Floor[value/10] + Mod[value, 10];
,
{i, 8}
];
check = Mod[(10 - Mod[sum, 10]), 10];
s[[-1]] === ToString[check]
]
]
Cusip /@ {"037833100", "17275R102", "38259P508", "594918104", "68389X106", "68389X105"}</syntaxhighlight>
{{out}}
<pre>{True, True, True, True, False, True}</pre>
 
=={{header|MiniScript}}==
<syntaxhighlight lang="miniscript">isCusip = function(s)
if s.len != 9 then return false
sum = 0
for i in range(0, 7)
c = s[i]
v = 0
if c >= "0" and c <= "9" then
v = code(c) - 48
else if c >= "A" and c <= "Z" then
v = code(c) - 55
else if c == "*" then
v = 36
else if c == "@" then
v = 37
else if c == "#" then
v = 38
else
return false
end if
if i%2 == 1 then v *= 2 // check if odd as using 0-based indexing
sum += floor(v/10) + v%10
end for
return code(s[8]) - 48 == (10 - (sum%10)) % 10
end function
 
candidates = [
"037833100", "17275R102", "38259P508",
"594918104", "68389X106", "68389X105",
]
for candidate in candidates
s = "valid"
if not isCusip(candidate) then s = "invalid"
print candidate + " -> " + s
end for</syntaxhighlight>
 
{{out}}
<pre>037833100 -> valid
17275R102 -> valid
38259P508 -> valid
594918104 -> valid
68389X106 -> invalid
68389X105 -> valid
</pre>
 
=={{header|Modula-2}}==
<langsyntaxhighlight lang=modula2>MODULE CUSIP;
FROM FormatString IMPORT FormatString;
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;
Line 2,092 ⟶ 3,260:
 
ReadChar
END CUSIP.</langsyntaxhighlight>
{{out}}
<pre>CUSIP Verdict
Line 2,103 ⟶ 3,271:
 
=={{header|Nanoquery}}==
<langsyntaxhighlight lang=Nanoquery>def cusip_checksum(cusip)
alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
num = "0123456789"
Line 2,140 ⟶ 3,308:
end
end
end</langsyntaxhighlight>
 
{{out}}
Line 2,151 ⟶ 3,319:
 
=={{header|Nim}}==
<langsyntaxhighlight lang=Nim>import strutils
 
proc cusipCheck(cusip: string): bool =
Line 2,159 ⟶ 3,327:
var
sum, v = 0
for i, c in cusip[0 ..< ^12]:
if c.isDigit:
v = parseInt($c)
Line 2,191 ⟶ 3,359:
echo code, ": ", if cusipCheck(code): "Valid" else: "Invalid"
 
main()</langsyntaxhighlight>
 
{{out}}
Line 2,204 ⟶ 3,372:
=={{header|Objeck}}==
{{trans|Kotlin}}
<langsyntaxhighlight lang=Objeck>class Cusip {
function : native : IsCusip(s : String) ~ Bool {
if(s->Size() <> 9) {
Line 2,218 ⟶ 3,386:
v := c - 48;
} else if (c >= 'A' & c <= 'Z') {
v := c - 6455; # lower case letters apparently invalid
} else if (c = '*') {
v := 36;
Line 2,261 ⟶ 3,429:
};
}
}</langsyntaxhighlight>
 
Output:
Line 2,275 ⟶ 3,443:
=={{header|Perl}}==
 
<langsyntaxhighlight lang=perl>$cv{$_} = $i++ for '0'..'9', 'A'..'Z', '*', '@', '#';
 
sub cusip_check_digit {
Line 2,301 ⟶ 3,469:
);
 
print "$_ $test_data{$_}" . cusip_check_digit($_) . "\n" for sort keys %test_data;</langsyntaxhighlight>
{{out}}
<pre>037833100 Apple Incorporated
Line 2,311 ⟶ 3,479:
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>sequence cch = {}
<span style="color: #004080;">sequence</span> <span style="color: #000000;">cch</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
 
function CusipCheckDigit(string cusip)
<span style="color: #008080;">function</span> <span style="color: #000000;">CusipCheckDigit</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">cusip</span><span style="color: #0000FF;">)</span>
integer s = 0, c, v
<span style="color: #004080;">integer</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">v</span>
if length(cch)=0 then
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cch</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
cch = repeat(-1,256)
<span style="color: #000000;">cch</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">256</span><span style="color: #0000FF;">)</span>
for i='0' to '9' do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'0'</span> <span style="color: #008080;">to</span> <span style="color: #008000;">'9'</span> <span style="color: #008080;">do</span>
cch[i] = i-'0'
<span style="color: #000000;">cch</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #008000;">'0'</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
for i='A' to 'Z' do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'A'</span> <span style="color: #008080;">to</span> <span style="color: #008000;">'Z'</span> <span style="color: #008080;">do</span>
cch[i] = i-55
<span style="color: #000000;">cch</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">55</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
cch['*'] = 36
<span style="color: #000000;">cch</span><span style="color: #0000FF;">[</span><span style="color: #008000;">'*'</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">36</span>
cch['@'] = 37
<span style="color: #000000;">cch</span><span style="color: #0000FF;">[</span><span style="color: #008000;">'@'</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">37</span>
cch['#'] = 38
<span style="color: #000000;">cch</span><span style="color: #0000FF;">[</span><span style="color: #008000;">'#'</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">38</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if length(cusip)!=9 or find('\0',cusip) then return 0 end if
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cusip</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">9</span> <span style="color: #008080;">or</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'\0'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cusip</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
for i=1 to 8 do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span>
c := cusip[i]
<span style="color: #000000;">c</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">cusip</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
v := cch[c]
<span style="color: #000000;">v</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">cch</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span>
if v=-1 then return 0 end if
<span style="color: #008080;">if</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if remainder(i,2)=0 then
<span style="color: #008080;">if</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
v *= 2
<span style="color: #000000;">v</span> <span style="color: #0000FF;">*=</span> <span style="color: #000000;">2</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
s += floor(v/10)+mod(v,10)
<span style="color: #000000;">s</span> <span style="color: #0000FF;">+=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">v</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)+</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">v</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
return cusip[9]=mod(10-mod(s,10),10)+'0'
<span style="color: #008080;">return</span> <span style="color: #000000;">cusip</span><span style="color: #0000FF;">[</span><span style="color: #000000;">9</span><span style="color: #0000FF;">]=</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">-</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">),</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)+</span><span style="color: #008000;">'0'</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
sequence tests = {"037833100", -- Apple Incorporated
<span style="color: #004080;">sequence</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"037833100"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- Apple Incorporated</span>
"17275R102", -- Cisco Systems
<span style="color: #008000;">"17275R102"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- Cisco Systems</span>
"38259P508", -- Google Incorporated
<span style="color: #008000;">"38259P508"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- Google Incorporated</span>
"594918104", -- Microsoft Corporation
<span style="color: #008000;">"594918104"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- Microsoft Corporation</span>
"68389X106", -- Oracle Corporation (incorrect)
<span style="68389X105color: #008000;"}>"68389X106"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- Oracle Corporation (incorrect)</span>
<span style="color: #008000;">"68389X105"</span><span style="color: #0000FF;">}</span> <span style="color: #000080;font-style:italic;">-- Oracle Corporation</span>
 
for i=1 to length(tests) do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
string ti = tests[i]
<span style="color: #004080;">string</span> <span style="color: #000000;">ti</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>
printf(1,"%s : %s\n",{ti,{"invalid","valid"}[CusipCheckDigit(ti)+1]})
<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;">ti</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"invalid"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"valid"</span><span style="color: #0000FF;">}[</span><span style="color: #000000;">CusipCheckDigit</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]})</span>
end for</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 2,362 ⟶ 3,532:
 
=={{header|PHP}}==
<langsyntaxhighlight lang=PHP>function IsCusip(string $s) {
if (strlen($s) != 9) return false;
$sum = 0;
Line 2,400 ⟶ 3,570:
"68389X105");
 
foreach ($cusips as $cusip) echo $cusip . " -> " . (IsCusip($cusip) ? "valid" : "invalid") . "\n";</langsyntaxhighlight>
{{out}}
<pre>
Line 2,411 ⟶ 3,581:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight lang=PicoLisp>(de cusip (Str)
(let (Str (mapcar char (chop Str)) S 0)
(for (I . C) (head 8 Str)
Line 2,439 ⟶ 3,609:
"38259P508"
"68389X106"
"68389X105" ) ) )</langsyntaxhighlight>
{{out}}
<pre>(T T T NIL T)</pre>
 
=={{header|PowerShell}}==
<syntaxhighlight lang=PowerShell>
function Get-CheckDigitCUSIP {
[CmdletBinding()]
[OutputType([int])]
Param ( # Validate input
[Parameter(Mandatory=$true, Position=0)]
[ValidatePattern( '^[A-Z0-9@#*]{8}\d$' )] # @#*
[ValidateScript({$_.Length -eq 9})]
[string]
$cusip
)
$sum = 0
0..7 | ForEach { $c = $cusip[$_] ; $v = $null
if ([Char]::IsDigit($c)) { $v = [char]::GetNumericValue($c) }
if ([Char]::IsLetter($c)) { $v = [int][char]$c - [int][char]'A' +10 }
if ($c -eq '*') { $v = 36 }
if ($c -eq '@') { $v = 37 }
if ($c -eq '#') { $v = 38 }
if($_ % 2){ $v += $v }
$sum += [int][Math]::Floor($v / 10 ) + ($v % 10)
}
[int]$checkDigit_calculated = ( 10 - ($sum % 10) ) % 10
return( $checkDigit_calculated )
}
 
function Test-IsCUSIP {
[CmdletBinding()]
[OutputType([bool])]
Param (
[Parameter(Mandatory=$true, Position=0)]
[ValidatePattern( '^[A-Z0-9@#*]{8}\d$' )]
[ValidateScript({$_.Length -eq 9})]
[string]
$cusip
)
[int]$checkDigit_told = $cusip[-1].ToString()
$checkDigit_calculated = Get-CheckDigitCUSIP $cusip
($checkDigit_calculated -eq $checkDigit_told)
}
 
$data = @"
037833100`tApple Incorporated
17275R102`tCisco Systems
38259P508`tGoogle Incorporated
594918104`tMicrosoft Corporation
68389X106`tOracle Corporation (incorrect)
68389X105`tOracle Corporation
"@ -split "`n"
$data |%{ Test-IsCUSIP $_.Split("`t")[0] }
</syntaxhighlight>{{out}}<pre>
True
True
True
True
False
True
</pre>
 
=={{header|Python}}==
Line 2,447 ⟶ 3,676:
Requires Python 3.6 for the string template literal in the print statement.
 
<langsyntaxhighlight lang=python>#!/usr/bin/env python3
 
import math
Line 2,489 ⟶ 3,718:
for code in codes:
print(f'{code} -> {cusip_check(code)}')
</syntaxhighlight>
</lang>
Output:
<pre>037833100 -> True
Line 2,502 ⟶ 3,731:
{{Works with|Python|3.7}}
Composing a set of pure functions, including a number of general and reusable abstractions:
<langsyntaxhighlight lang=python>'''CUSIP'''
 
from itertools import (cycle, islice, starmap)
Line 2,661 ⟶ 3,890:
# MAIN ---
if __name__ == '__main__':
main()</langsyntaxhighlight>
{{Out}}
<pre>Test for validity as a CUSIP string:
Line 2,671 ⟶ 3,900:
'68389X106' -> False
'68389X105' -> True</pre>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang=Quackery> [ -1 split 0 peek char 0 -
swap 0 swap
witheach
[ [ dup char 0 char 9 1+ within iff
[ char 0 - ] done
dup char A char Z 1+ within iff
[ char A - 10 + ] done
dup char * = iff
[ drop 36 ] done
dup char @ = iff
[ drop 37 ] done
dup char # = iff
[ drop 38 ] done
$ "Unexpected character '" swap
join $ "' in CUSIP." join fail ]
i^ 1 & if [ 2 * ]
10 /mod + + ]
10 mod 10 swap - 10 mod = ] is cusip ( $ --> b )
[ dup echo$ cusip iff
[ say " is correct." ]
else [ say " is incorrect." ]
cr ] is task ( $ --> )
$ "037833100 17275R102 38259P508 594918104 68389X106 68389X105"
nest$ witheach task</syntaxhighlight>
 
{{out}}
 
<pre>037833100 is correct.
17275R102 is correct.
38259P508 is correct.
594918104 is correct.
68389X106 is incorrect.
68389X105 is correct.
</pre>
 
=={{header|Racket}}==
 
<langsyntaxhighlight lang=racket>#lang racket
(require srfi/14)
 
Line 2,710 ⟶ 3,978:
(check-true (CUSIP? "594918104"))
(check-false (CUSIP? "68389X106"))
(check-true (CUSIP? "68389X105")))</langsyntaxhighlight>
 
no output indicates all tests passed.
Line 2,718 ⟶ 3,986:
{{works with|Rakudo|2017.01}}
 
<syntaxhighlight lang=raku perl6line>sub divmod ($v, $r) { $v div $r, $v mod $r }
my %chr = (flat 0..9, 'A'..'Z', <* @ #>) Z=> 0..*;
 
Line 2,735 ⟶ 4,003:
68389X106
68389X105
></langsyntaxhighlight>
{{out}}
<pre>037833100: True
Line 2,746 ⟶ 4,014:
=={{header|REXX}}==
===idiomatic===
<langsyntaxhighlight lang=rexx>/*REXX program validates that the last digit (the check digit) of a CUSIP is valid. */
@.=
parse arg @.1 .
Line 2,777 ⟶ 4,045:
$=$ + #%10 + #//10
end /*k*/
return (10- $//10) // 10</langsyntaxhighlight>
'''output''' &nbsp; when using the default input:
<pre>
Line 2,789 ⟶ 4,057:
 
===conciser function===
<langsyntaxhighlight lang=rexx>/*REXX program validates that the last digit (the check digit) of a CUSIP is valid. */
@.=
parse arg @.1 .
Line 2,814 ⟶ 4,082:
$=$ + #%10 + #//10
end /*k*/
return (10-$//10) // 10</langsyntaxhighlight>
'''output''' &nbsp; is the same as the idiomatic REXX version. <br><br>
 
=={{header|Ring}}==
<langsyntaxhighlight lang=ring>
# Project : CUSIP
 
Line 2,847 ⟶ 4,115:
ok
if x >= ascii("A") and x <= ascii("Z")
v = x - 64 55
flag = 1
ok
Line 2,876 ⟶ 4,144:
see inputstr + " is invalid" + nl
ok
</syntaxhighlight>
</lang>
Output:
<pre>
Line 2,885 ⟶ 4,153:
68389X106 is invalid
68389X105 is valid
</pre>
 
=={{header|RPL}}==
{{works with|Halcyon Calc|4.2.7}}
{| class="wikitable"
! RPL code
! Comment
|-
|
SWAP ROT DUP2 ≤ OVER 5 ROLL ≤ AND
SWAP NUM ROT NUM - 1 + 0 '''IFTE'''
≫ ''''BTWEEN'''' STO
0
1 8 '''FOR''' j
OVER j DUP SUB → c
≪ '''IF''' c "0" "9" '''BTWEEN'''
'''THEN''' LAST 1 -
'''ELSE IF''' c "A" "Z" '''BTWEEN'''
'''THEN''' LAST
9 +
'''ELSE IF''' "*@#" c POS
'''THEN''' LAST 35 +
'''END END END'''
j 2 MOD SWAP DUP DUP + '''IFTE'''
10 / LAST MOD SWAP IP + +
≫ '''NEXT'''
10 SWAP 10 MOD - 10 MOD
SWAP 9 DUP SUB STR→ ==
≫ ''''CUSIP?'''' STO
|
'''BTWEEN''' ''( "char" "from" "to" -- pos )''
evaluate "from" ≤ "char ≤ "to"
if yes, return relative position from "from"
'''CUSIP?''' ''( "CUSIP" -- boolean )''
sum := 0
for 1 ≤ i ≤ 8 do
c := the ith character of cusip
if c is a digit then
v := numeric value of the digit c
else if c is a letter then
p := ordinal position of c in the alphabet (A=1...)
v := p + 9
else if c = "*", "@", "#" then
v := 36, 37, 38
if i is even then v := v × 2
sum := sum + int ( v div 10 ) + v mod 10
repeat
get (10 - (sum mod 10)) mod 10
return true if equal to 9th digit
|}
{{in}}
<pre>
≪ { "037833100" "17275R102" "38259P508" "594918104" "68389X106" "68389X105" } → tests
≪ {} 1 tests SIZE FOR n
tests n GET n CUSIP? "Yes" "No" IFTE + NEXT
≫ ≫ EVAL
</pre>
{{out}}
<pre>
1: { "Yes" "Yes" "Yes" "Yes" "No" "Yes" }
</pre>
 
=={{header|Ruby}}==
===Following pseudocode===
<langsyntaxhighlight lang=ruby>
#!/usr/bin/env ruby
 
Line 2,929 ⟶ 4,264:
end
 
</syntaxhighlight>
</lang>
 
Output:
Line 2,942 ⟶ 4,277:
===More concise===
Since it uses methods like chain, to_h, sum, and infinite Range syntax (0..), this needs a Ruby version > 2.5
<langsyntaxhighlight lang=Ruby>
TABLE = ("0".."9").chain("A".."Z", %w(* @ #)).zip(0..).to_h
 
Line 2,954 ⟶ 4,289:
CUSIPs = %w(037833100 17275R102 38259P508 594918104 68389X106 68389X105)
CUSIPs.each{|cusip| puts "#{cusip}: #{valid_CUSIP? cusip}"}
</syntaxhighlight>
</lang>
 
=={{header|Rust}}==
 
<langsyntaxhighlight lang=rust>fn cusip_check(cusip: &str) -> bool {
if cusip.len() != 9 {
return false;
Line 2,999 ⟶ 4,334:
println!("{} -> {}", code, cusip_check(code))
}
}</langsyntaxhighlight>
 
Output:
Line 3,012 ⟶ 4,347:
=={{header|Scala}}==
{{Out}}See it running in your browser by [https://scalafiddle.io/sf/jwxwWpq/0 ScalaFiddle (JavaScript, non JVM)] or by [https://scastie.scala-lang.org/OBrz9l14Rm2C6tV8tiwhWg Scastie (JVM)].
<langsyntaxhighlight lang=Scala>object Cusip extends App {
 
val candidates = Seq("037833100", "17275R102", "38259P508", "594918104", "68389X106", "68389X105")
Line 3,027 ⟶ 4,362:
var v = 0
if (c >= '0' && c <= '9') v = c - 48
else if (c >= 'A' && c <= 'Z') v = c - 6455 // lower case letters apparently invalid
else if (c == '*') v = 36
else if (c == '@') v = 37
Line 3,039 ⟶ 4,374:
}
 
}</langsyntaxhighlight>
 
=={{header|SNOBOL4}}==
<langsyntaxhighlight lang=snobol4>#!/usr/local/bin/snobol4 -r
* cusip.sno
* -- Committee on Uniform Security Identification Procedures
Line 3,091 ⟶ 4,426:
68389X10
68389X1059
68389x105</langsyntaxhighlight>
{{out}}
<pre>037833100 valid.
Line 3,105 ⟶ 4,440:
=={{header|Swift}}==
 
<langsyntaxhighlight lang=swift>struct CUSIP {
var value: String
 
Line 3,171 ⟶ 4,506:
print("Valid")
}
}</langsyntaxhighlight>
 
{{out}}
Line 3,184 ⟶ 4,519:
=={{header|Tcl}}==
=== Direct translation of pseudocode ===
<langsyntaxhighlight lang=Tcl>proc ordinal-of-alpha {c} { ;# returns ordinal position of c in the alphabet (A=1, B=2...)
lsearch {_ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z} [string toupper $c]
}
Line 3,221 ⟶ 4,556:
set cusip [string range $cusip 0 end-1]
expr {$last eq [Cusip-Check-Digit $cusip]}
}</langsyntaxhighlight>
 
=== More idiomatic Tcl ===
<langsyntaxhighlight lang=Tcl>proc check-cusip {code} {
if {[string length $code] != 9} {
return false
Line 3,240 ⟶ 4,575:
}
expr {$sum % 10 == 0}
}</langsyntaxhighlight>
 
=== Common test harness ===
<langsyntaxhighlight lang=Tcl>proc test {} {
foreach {cusip name} {
037833100 "Apple Incorporated"
Line 3,256 ⟶ 4,591:
}
}
test</langsyntaxhighlight>
 
=== Output ===
Line 3,267 ⟶ 4,602:
Oracle Corporation valid</pre>
 
=={{header|VBAV (Vlang)}}==
{{trans|Go}}
<lang vb>Private Function Cusip_Check_Digit(s As Variant) As Integer
<syntaxhighlight lang="v (vlang)">fn is_cusip(s string) bool {
Dim Sum As Integer, c As String, v As Integer
Forif is.len != 19 To{ 8return false }
mut sum c := Mid(s, i, 1)0
for i in 0..8 If IsNumeric(c) Then{
c v := Val(c)s[i]
Elsemut v :=0
match true Select Case c{
c >= '0'[0] && Casec "a"<= To'9'[0] "z"{
v = Asc(c) - Asc("a") + 1048
}
Case "A" To "Z"
c >= 'A'[0] && c v <= Asc(c) - Asc("A") +'Z'[0] 10{
Casev "*"= c - 55
}
v = 36
c == '*'[0] Case "@"{
v = 37
Case "#"
v = 38
Case Else
Debug.Print "not expected"
End Select
End If
If i Mod 2 = 0 Then v = v * 2
Sum = Sum + Int(v \ 10) + v Mod 10
Next i
Cusip_Check_Digit = (10 - (Sum Mod 10)) Mod 10
End Function</lang>{{out}}
<pre>037833100 is valid
17275R102 is valid
38259P508 is valid
594918104 is valid
68389X106 not valid
68389X105 is valid</pre>
 
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<lang vbnet>Module Module1
 
Function IsCUSIP(s As String) As Boolean
If s.Length <> 9 Then
Return False
End If
 
Dim sum = 0
For i = 0 To 7
Dim c = s(i)
 
Dim v As Integer
If "0" <= c AndAlso c <= "9" Then
v = Asc(c) - 48
ElseIf "A" <= c AndAlso c <= "Z" Then
v = Asc(c) - 64 ' Lower case letters are apparently invalid
ElseIf c = "*" Then
v = 36
}
ElseIf c = "#" Then
c == '@'[0] {
v = 37
}
c == '#'[0] {
v = 38
}
Else
else Return False{
End If return false
}
 
If i Mod 2 = 1 Then
v *= 2 ' check if odd as using 0-based indexing
End If
sum += v \ 10 + v Mod 10
Next
Return Asc(s(8)) - 48 = (10 - (sum Mod 10)) Mod 10
End Function
 
Sub Main()
Dim candidates As New List(Of String) From {
"037833100",
"17275R102",
"38259P508",
"594918104",
"68389X106",
"68389X105"
}
if i % 2 == 1 { v *= 2 } // check if odd as using 0-based indexing
sum += v/10 + v%10
}
return int(s[8]) - 48 == (10 - (sum%10)) % 10
}
fn main() {
candidates := [
"037833100",
"17275R102",
"38259P508",
"594918104",
"68389X106",
"68389X105",
]
for candidate in candidates {
mut b :=' '
if is_cusip(candidate) {
b = "correct"
} else {
b = "incorrect"
}
println("$candidate -> $b")
}
}</syntaxhighlight>
 
For Each candidate In candidates
Console.WriteLine("{0} -> {1}", candidate, If(IsCUSIP(candidate), "correct", "incorrect"))
Next
End Sub
 
End Module</lang>
{{out}}
<pre>
<pre>037833100 -> correct
037833100 -> correct
17275R102 -> correct
38259P508 -> correct
594918104 -> correct
68389X106 -> incorrect
68389X105 -> correct</pre>
</pre>
 
=={{header|Wren}}==
{{trans|Go}}
<langsyntaxhighlight ecmascriptlang="wren">var isCusip = Fn.new { |s|
if (s.count != 9) return false
var sum = 0
Line 3,371 ⟶ 4,678:
v = c - 48
} else if (c >= 65 && c <= 90) { // 'A' to 'Z'
v = c - 6455
} else if (s[i] == "*") {
v = 36
Line 3,398 ⟶ 4,705:
var b = (isCusip.call(candidate)) ? "correct" : "incorrect"
System.print("%(candidate) -> %(b)")
}</langsyntaxhighlight>
 
{{out}}
Line 3,410 ⟶ 4,717:
</pre>
 
=={{header|YabasicXPL0}}==
<syntaxhighlight lang=XPL0>string 0; \use zero-terminated strings
{{trans|FreeBASIC}}
 
<lang Yabasic>sub cusip(inputStr$)
func Valid(Cusip); \Return 'true' if valid CUSIP code
local i, v, sum, x$
char Cusip;
int Print inputStr$Sum, I, C, V;
[Sum:= 0;
If Len(inputStr$) <> 9 Print " length is incorrect, invalid cusip" : return
for I:= 0 to 8-1 do
For i = 1 To[C:= 8Cusip(I);
x$ = mid$ChOut(inputStr$, i0, 1C);
switchcase x$of
C>=^0 & CaseC<=^9: "*"V: v = 36 : breakC-^0;
C>=^A & CaseC<=^Z: "@"V: v = 37 : breakC-^A+10;
C=^*: Case "#"V: v = 38 : break36;
C=^@: defaultV:=37;
if x$ >C=^#: "A" and x$ <V:= "Z" then38
other v V:= asc(x$) - Asc("A") + 101;
if I&1 then elsif x$ >V:= "0" and x$ <= "9" thenV*2;
Sum:= Sum + V/10 + v = asc(x$) - ascrem("0");
else];
C:= Cusip(I);
Print " found a invalid character, invalid cusip"
ChOut(0, C);
return
V:= rem( (10-rem(Sum/10)) / 10 );
end if
return V = C-^0;
End switch
];
 
If and(i, 1) = 0 v = v * 2
int Cusip, N;
sum = sum + int(v / 10) + mod(v, 10)
[Cusip:= ["037833100",
Next
"17275R102",
sum = mod(10 - mod(sum, 10) "38259P508", 10)
"594918104",
If sum = asc(mid$(inputStr$, 9, 1)) - Asc("0") Then
Print " is valid68389X106",
"68389X105"];
Else
for N:= 0 to 6-1 do
Print " is invalid"
[Text(0, if Valid(Cusip(N))
End If
then " is valid"
else " is invalid");
End Sub
CrLf(0);
];
// ------=< MAIN >=------
]</syntaxhighlight>
 
Data "037833100", "17275R102", "38259P508"
{{out}}
Data "594918104", "68389X106", "68389X105", ""
<pre>
037833100 is valid
Print
17275R102 is valid
do
38259P508 is valid
Read inputStr$
594918104 is valid
if inputStr$ = "" break
68389X106 is invalid
cusip(inputStr$)
68389X105 is valid
loop
</langpre>
 
=={{header|Zig}}==
<syntaxhighlight lang=zig>const std = @import("std");
const print = std.debug.print;
 
pub fn CusipCheckDigit(cusip: *const [9:0]u8) bool {
var i: usize = 0;
var sum: i32 = 0;
while (i < 8) {
const c = cusip[i];
var v: i32 = undefined;
if (c <= '9' and c >= '0') {
v = c - 48;
}
else if (c <= 'Z' and c >= 'A') {
v = c - 55;
}
else if (c == '*') {
v = 36;
}
else if (c == '@') {
v = 37;
}
else if (c == '#') {
v = 38;
}
else {
return false;
}
if (i % 2 == 1) {
v *= 2;
}
sum = sum + @divFloor(v, 10) + @mod(v, 10);
i += 1;
}
return (cusip[8] - 48 == @mod((10 - @mod(sum, 10)), 10));
}
 
pub fn main() void {
const cusips = [_]*const [9:0]u8 {
"037833100",
"17275R102",
"38259P508",
"594918104",
"68389X106",
"68389X105"
};
for (cusips) |cusip| {
print("{s} -> {}\n", .{cusip, CusipCheckDigit(cusip)});
}
}
</syntaxhighlight>
 
=={{header|zkl}}==
<langsyntaxhighlight lang=zkl>fcn cusipCheckDigit(cusip){
var [const] vs=[0..9].chain(["A".."Z"],T("*","@","#")).pump(String);
try{
Line 3,469 ⟶ 4,828:
((10 - sum%10)%10 == cusip[8].toInt()) and cusip.len()==9
}catch{ False }
}</langsyntaxhighlight>
<langsyntaxhighlight lang=zkl>foreach cusip in (T("037833100", "17275R102",
"38259P508", "594918104", "68389X106", "68389X105")){
println(cusip,": ",cusipCheckDigit(cusip));
}</langsyntaxhighlight>
{{out}}
<pre>
890

edits