Function to validate a CPF in R [closed]

-6

Please, I need a function in R to validate a CPF, ie check if a number passed as a parameter is a valid CPF.

    
asked by anonymous 29.09.2017 / 21:06

1 answer

9

Well, since no one answered, although I agree with the above comments, today is Sunday, here it goes. In the first place, I might have included some information about this CPF. Read Rafael Cunha's comment again. I who am Portuguese had never even heard of such a thing. In the Wikipedia I found all the necessary information including the algorithm that I will use below. That should have been your job.

Code.
The code below are three functions. The first, cpf_dig_controle calculates the control digits or verifiers of an 8-digit number. The function is vectorized to accept numeric vectors as input. If by chance the input is of class character the function in principle also does not choke but I do not guarantee it.

cpf_dig_controle <- function(y){
    v1 <- 0L
    v2 <- 0L
    z <- as.integer(rev(strsplit(as.character(y), "")[[1]]))
    for(i in seq_along(z)){
        v1 <- v1 + z[i]*(9 - (i %% 10))
        v2 <- v2 + z[i]*(9 - ((i + 1) %% 10))
    }
    v1 <- (v1 %% 11) %% 10
    v2 <- v2 + v1*9
    v2 <- (v2 %% 11) %% 10
    c(v1, v2)
}

Next come two functions, one to generate CPF numbers, with proper formatting and another to check their validity.

cpf_gerar <- function(x){
    g <- function(y, v){
        z <- strsplit(as.character(y), "")[[1]]
        z <- as.integer(c(z, v))
        res <- sprintf(fmt = "%d%d%d.%d%d%d.%d%d%d-%02d",
                             z[1], z[2], z[3], z[4], z[5],
                             z[6], z[7], z[8], z[9], z[10])
        res
    }
    v <- lapply(x, cpf_dig_controle)
    result <- sapply(seq_along(x), function(i) g(x[i], v[[i]]))
    result
}

cpf_validar <- function(x){
    f <- function(y){
        z <- unlist(strsplit(y, "\."))
        v <- substr(z[3], 3, 6)
        v <- as.integer(unlist(strsplit(v, "-")))
        z[3] <- substr(z[3], 1, 2)
        z <- as.integer(paste(z, collapse = ""))
        list(x = z, v = v)
    }
    result <- lapply(x, f)
    valido <- lapply(result, function(r) unlist(lapply(r$x, cpf_dig_controle)))
    valido <- sapply(seq_along(valido), function(i)
                    result[[i]]$v[1] == valido[[i]][1] & result[[i]]$v[2] == valido[[i]][2]
                )
    valido
}

cpf <- cpf_gerar(c(12345678, 87654321))
cpf
#[1] "123.456.786-02" "876.543.210-07"

cpf_validar(cpf)
#[1] TRUE TRUE

cpf_validar(c("123.456.786-02", "876.543.211-07"))
#[1]  TRUE FALSE
    
01.10.2017 / 23:43