Talk:CUSIP

Latest comment: 5 years ago by Art LaPella in topic The Paper Crunch

Check digit algorithm edit

I'm having trouble with the check digit algorithm:

Consider Google: CUSIP 38259P102. Expanding P = 25 (16 + 9) gives 3825925102

We have: (3, 2, 9, 5, 0) and (8, 5, 2, 1) Since the last digit is in the first group we double that: 6 + 4 + (1 + 8) + (1 + 0) + 0 + 8 + 5 + 2 + 1 = 36

36 mod 10 = 6, 10 - 6 = 4.

But the check digit is 2.

Any thoughts?

24.215.233.224 03:35, 26 July 2007 (UTC) GRReply

The characters have to be separated before letters are expanded into their numeric equivalents:
  38259P10 = (3 + 2 + 9 + 1) + 2 * (8 + 5 + P + 0)
           = (3 + 2 + 9 + 1) + 2 * (8 + 5 + (2 + 5) + 0)
           = (3 + 2 + 9 + 1) + ((1 + 6) + (1 + 0) + (4 + (1 + 0)) + 0)
           = 15 + 13 = 28
and (10 - 28) mod 10 = 2. This is different from the ISIN check digit algorithm, in which the letter expansion occurs before alternate digits are collected. 67.87.115.207 06:13, 12 October 2007 (UTC)Reply
I've checked with a few example CUSIP #'s (like this one http://financialresearch.blog2blog.nl/38361/Converting+CUSIP+6+or+8+into+CUSIP+9.html) and it seems that the check digit for CUSIP's is the same for ISIN's. In both cases the letter expansion is supposed to occur before alternate digits are collected. So, the "Modulus 10 Double Add Double" pseudocode in this article is wrong, but the code in the ISIN article is right. I didn't want to correct it until someone confirms. Dirkbike (talk) 23:40, 4 August 2011 (UTC)Reply

Are CUSIP's ever reused?

Would it be possible to use language other than Perl for the code sample ? Should we consider Java, ECMA script or even Cobol ? Although these languages may be more "bloated" than Perl, they may be more friendly and may actually be usable. Regards 68.192.150.202 01:04, 25 May 2007 (UTC)Reply

We may be able to make the code more compact since the bNum is the same as

aNum except for the 2x multiply. So we may be able to do something like:

...
       $tt += aNum($t[2*$i],   1);
       $tt += aNum($t[2*$i+1], 2);
...

sub aNum{
    my $a = shift;
    my $x = $a;
    $x = ord($a)-ord('A')+10 if $a =~ /[A-Z]/;
    my $b = shift;
    $x = $b*$x;
    my $d = floor($x/10);
    return $x-$d*10+$d;
}
Problem solved. 164.55.254.106 18:03, 24 July 2007 (UTC)Reply

Removed code samples edit

I have removed the code samples. Whenever these are added to generic articles like these, they tend to turn into requires for "enter favorite language here". I can see this happened above. Code for CUSIP formatting is easy to find on the 'net, that's the proper place for it. I notice links to examples already exist. Maury 20:05, 15 October 2007 (UTC)Reply

Bug in CUSIP C code edit

The ISIN and CUSIP algorithms are bit different. In the linked CUSIP code replace this

       if (d1 < 10) {
           d1 *= (multiply ? 2 : 1);
           multiply = !multiply;
       } else {
           d2 = d1 / 10;
           d1 %= 10;
           d1 *= (multiply ? 2 : 1);
           d2 *= (multiply ? 1 : 2);
           sum += (d2 % 10) + (d2 / 10);
       }
       sum += (d1 % 10) + (d1 / 10);

With this

       if (multiply) d1 *= 2;
       multiply = !multiply;
       sum += (d1 / 10) + (d1 % 10); 

Have tried to advise owner of the site linked-to. User:mike_mueller_nz 12:13, 12 August 2008 (UTC)Reply

Following Mike's email, I have tested and corrected my example code. Regards, Chris —Preceding unsigned comment added by 80.176.91.102 (talk) 22:08, 12 August 2008 (UTC)Reply

Possible correction edit

I think the following text:

The resulting string of digits (numbers greater than 10 becoming two separate digits) are added up.

Should be replaced with

The resulting string of digits (numbers equal to or greater than 10 becoming two separate digits) are added up.  —Preceding unsigned comment added by Kintisheff (talkcontribs) 18:55, 17 May 2009 (UTC)Reply 

Java code doesn't validate CUSIPs edit

The Java code linked to doesn't actually validate CUSIPs, it just checks the check digit, so things like $$$$$$$$8 are reported as valid. I've looked around the site to try to inform the author, but don't see any way to do so short of creating an account, so I suggest removing the link to the Java code, and will do so in a few days unless there are objections.

Blm (talk) 17:20, 26 June 2009 (UTC)Reply

Ok, no objections, so I removed the link. —Preceding unsigned comment added by Blm (talkcontribs) 06:26, 2 July 2009 (UTC)Reply

The link to the Java code got re-added, so I deleted it again, and also looked at the VBA example, which has the same problem, so I deleted the link to it as well. The C code appears correct, at least it checks for the right length and the component characters are in the correct ranges, in addition to checking the check digit.

Blm (talk) 16:43, 7 May 2010 (UTC)Reply

Pseudocode correction edit

Regarding the section:

   if i is odd then
       v := v × 2

The value v should be multiplied by 2 if i is even, given that the for loop is not zero indexed. —Preceding unsigned comment added by Ichiro33s (talkcontribs) 16:51, 20 July 2010 (UTC)Reply

R code for getting check-digit from CUSIP8s edit

This might be helpful for R users. I wrote it myself, so if anybody wants to check it, feel free. I haven't included the special characters in the if-statements, since they're rarely needed - but adding them is trivial.

CUSIPcheck <- function(x){
if(nchar(x)!=8){stop("Provided CUSIP does not have length 8")}
v <- unlist(strsplit(x,""))
if(any(v %in% LETTERS)){
v[which(v %in% LETTERS)] <- which(LETTERS %in% v[which(v %in% LETTERS)])+9
v <- as.numeric(v)
}else{v <- as.numeric(v)}
out <- 0
for(i in 1:8){
if(i%%2==0){v[i]<-v[i]*2}
out <- out + v[i]%/%10 + v[i]%%10
}
(10-(out%%10))%%10
}

MamdouhMedhatCBS (talk) 15:16, 26 March 2012 (UTC)Reply

special characters for "PPN" edit

It's a bit odd to have sample code handling the non-alphanumeric characters when the article makes no mention of them when describing the format. The referenced .pdf from cusip.com says they are for PPN, but I haven't found any more information than that yet. (As someone above pointed out, it's also a bit silly to have code examples other than pseudo-code at all due to the language wars.) — Preceding unsigned comment added by Danny Rathjens (talkcontribs) 15:14, 12 February 2013 (UTC)Reply

Information for Non-Programmers edit

The below table works with this spreadsheet pseudo code -

IS_VALID_CUSIP=IF(LEN(CUSIP)<>9,"no",IF(ISNA(VLOOKUP(MID(CUSIP,9,1,0),A$2:A$11,1,FALSE)),"No",IF(MOD(10-MOD( VLOOKUP(MID(CUSIP,1,1),A$2:E$40,3,0)+VLOOKUP(MID(CUSIP,2,1),A$2:E$40,5,0)+ VLOOKUP(MID(CUSIP,3,1),A$2:E$40,3,0)+VLOOKUP(MID(CUSIP,4,1),A$2:E$40,5,0)+ VLOOKUP(MID(CUSIP,5,1),A$2:E$40,3,0)+VLOOKUP(MID(CUSIP,6,1),A$2:E$40,5,0)+ VLOOKUP(MID(CUSIP,7,1),A$2:E$40,3,0)+VLOOKUP(MID(CUSIP,8,1),A$2:E$40,5,0),10),10) =VALUE(MID(CUSIP,9,1)),"yes","NO")))

[A$1]CUSIP char. odd index digit sum even index even sum
0 0 0 0 0
1 1 1 2 2
2 2 2 4 4
3 3 3 6 6
4 4 4 8 8
5 5 5 10 1
6 6 6 12 3
7 7 7 14 5
8 8 8 16 7
9 9 9 18 9
A 10 1 20 2
B 11 2 22 4
C 12 3 24 6
D 13 4 26 8
E 14 5 28 1
F 15 6 30 3
G 16 7 32 5
H 17 8 34 7
I 18 9 36 9
J 19 0 38 1
K 20 2 40 4
L 21 3 42 6
M 22 4 44 8
N 23 5 46 0
O 24 6 48 2
P 25 7 50 5
Q 26 8 52 7
R 27 9 54 9
S 28 0 56 1
T 29 1 58 3
U 30 3 60 6
V 31 4 62 8
W 32 5 64 0
X 33 6 66 2
Y 34 7 68 4
Z 35 8 70 7
* 36 9 72 9
@ 37 0 74 1
# 38 1 76 3

Jim Gettman, 8.37.92.7 (talk) 21:55, 17 May 2016 (UTC)Reply

I disagree with that table, as explained in my talk section below. Art LaPella (talk) 06:44, 15 January 2017 (UTC)Reply

Phil Taylor: I've corrected the table - in the cases where the two digits add up to more than 10, the solution should be digit1+digit2. The initial "1" can be ignored because the next step is mod(sum,10). The sum of digits should not be applied iteratively. I also added the ,0 to VLOOKUP(..,..,..,0) as exact match is required and the table is not in sequence (*,@,# come before 0 in ascii sort order).

why is there an ISIN antitrust action in this CUSIP article? edit

Seems like it only belongs in the ISIN article? Gruntler (talk) 16:26, 21 June 2016 (UTC)Reply

The table still has a problem edit

@Jimgettman:

In this reference, page 6, Illustration 2, notice how the letter T is computed. T is the 20th letter so it's 29. It's in an even position, so it becomes 58. Next, the digits are included in the final total, 5+8. You could get the same result by substituting a 3, but not a 4 as in the table. If we substituted a 4 in Illustration 2, the total would be 38 not 47, and the check digit would come out to 2 not 3. Adding the digits 5+8 is not the same as 58 mod 9 = 4.

The pseudocode section agrees with me. sum := sum + int ( v div 10 ) + v mod 10 means that if v is 58, then we add v div 10 = 5 and v mod 10 = 8. Not 4. It doesn't say add v mod 9.

The Oracle Corporation example also agrees with me. Doing it my way:

6 8 3 8 9 X 1 0 5

6 8 3 8 9 33 1 0 5

6 16 3 16 9 66 1 0 5

6+1+6+3+1+6+9+6+6+1+0+5=50

Ends in a zero, valid CUSIP


If instead we use the table:

6 8 3 8 9 X 1 0 5

6 7 3 7 9 3 1 0 5

6+7+3+7+9+3+1+0+5=41

Doesn't end in a zero, invalid CUSIP. But it is the correct CUSIP.

The table in a previous talk section is wrong for the same reason.

In an odd position, J, S, and @ should be zero, and T and # should be 1. In an even position, E, N, and W should be zero, J, S, and @ should be 1, O and X should be 2, T and # should be 3, and Y should be 4. Art LaPella (talk) 05:29, 15 January 2017 (UTC)Reply

No objections, so I made that edit. Art LaPella (talk) 15:00, 18 January 2017 (UTC)Reply
Thank you to Art L. I will review this in depth to follow and confirm his examples. Jimgettman (talk) 21:19, 18 January 2017 (UTC)Reply

The Paper Crunch edit

Existing reference hyperlink is dead.

Broken link: http://www.marketminder.com/c/the-paper-crunch/205435a0-df00-47a3-889a-611ae4ac102b.aspx

New link: https://www.fisherinvestments.com/en-us/marketminder/the-paper-crunch — Preceding unsigned comment added by 199.250.8.34 (talk) 20:23, 6 June 2018 (UTC)Reply

Thank you, done Art LaPella (talk) 01:29, 7 June 2018 (UTC)Reply