Skip to content

Instantly share code, notes, and snippets.

@hlawrenz
Created May 5, 2014 19:41
Show Gist options
  • Save hlawrenz/a3d40dc8bd2aa83c8145 to your computer and use it in GitHub Desktop.
Save hlawrenz/a3d40dc8bd2aa83c8145 to your computer and use it in GitHub Desktop.
def invalid_cusip(cusip):
"""
:param cusip:
:type cusip: str
:return:
"""
cusip = cusip.upper()
if len(cusip) > 9:
return 'CUSIP is too long'
if re.search(r'[^A-Z0-9*@#]', cusip):
return 'CUSIP contains invalid characters'
cusip = cusip.zfill(9)
if not cusip[8].isdigit():
return 'CUSIP check digit out of range'
total = 0
for i in range(0, 7):
value = None
char = cusip[i]
if char.isdigit():
value = int(char)
elif char.isalpha():
value = ord(char) - ord('A') + 10
elif char == '*':
value = 36
elif char == '@':
value = 37
elif char == '#':
value = 38
if i % 2:
value *= 2
total += int(value / 10) + value % 10
if (10 - (total % 10)) % 10 == int(cusip[8]):
return False
else:
return 'CUSIP has bad check digit'
sub invalid_cusip {
my ( $cusip ) = @_;
$cusip = uc( $cusip );
if ( length( $cusip ) > 9 ) {
return 'CUSIP is too long';
}
if ( $cusip =~ /[^A-Z0-9*@#]/ ) {
return 'CUSIP contains invalid characters';
}
$cusip = sprintf( "%09s", $cusip );
my @chars = split( //, $cusip );
if ( $chars[8] !~ /\d/ ) {
return 'CUSIP check digit out of range';
}
my $total = 0;
for ( 0 .. 7 ) {
my $value;
my $char = $chars[$_];
if ( $char =~ /\d/ ) {
$value = $char;
} elsif ( $char =~ /[A-Z]/ ) {
$value = ord($char) - ord('A') + 10;
} elsif ( $char eq '*' ) {
$value = 36;
} elsif ( $char eq '@' ) {
$value = 37;
} elsif ( $char eq '#' ) {
$value = 38;
} else {
die "This can't happen";
}
$value *= 2 if $_ % 2;
$total += int( $value / 10 ) + $value % 10;
}
return ( $total % 10 + $chars[8] ) % 10 ? 'CUSIP has bad check digit' : 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment