26 lines
740 B
R
26 lines
740 B
R
library(stringr)
|
|
|
|
cusip_checkdigit <- function(s){
|
|
sum <- 0
|
|
chars <- str_split_1(s,"")
|
|
for(i in 1:8){
|
|
if(str_detect(chars[i],"[0-9]")) v <- as.numeric(chars[i])
|
|
else if(str_detect(chars[i],"[A-Z]")) v <- 9+which(LETTERS==chars[i])
|
|
else v <- switch(chars[i], "*"=36, "@"=37, "#"=38)
|
|
if(i%%2==0) v <- 2*v
|
|
sum <- sum+v%/%10+v%%10
|
|
}
|
|
return((10-(sum%%10))%%10)
|
|
}
|
|
|
|
cusip_isvalid <- function(s){
|
|
if(str_length(s)!=9){
|
|
stop("CUSIP must have exactly 9 characters")
|
|
}
|
|
checksum <- cusip_checkdigit(s) |> as.character()
|
|
ifelse(endsWith(s, checksum), "Valid CUSIP", "Invalid CUSIP")
|
|
}
|
|
|
|
test_cusips <- c("037833100","17275R102","38259P508","594918104","68389X106","68389X105")
|
|
sapply(test_cusips, cusip_isvalid)
|