Skip to content

Instantly share code, notes, and snippets.

@LeonardoCardoso
Created June 7, 2016 14:08
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LeonardoCardoso/3517ff69e4a45012fa6c8d9cbb506730 to your computer and use it in GitHub Desktop.
Save LeonardoCardoso/3517ff69e4a45012fa6c8d9cbb506730 to your computer and use it in GitHub Desktop.
Validar CPF em Swift
extension String {
var isCPF: Bool {
let cpf = self.stringByReplacingOccurrencesOfString(".", withString: "").stringByReplacingOccurrencesOfString("-", withString: "")
if cpf.characters.count == 11 {
let d1 = Int(cpf.substringWithRange(Range(cpf.startIndex.advancedBy(9) ..< cpf.startIndex.advancedBy(10))))
let d2 = Int(cpf.substringWithRange(Range(cpf.startIndex.advancedBy(10) ..< cpf.startIndex.advancedBy(11))))
var temp1 = 0, temp2 = 0
for i in 0...8 {
let char = Int(cpf.substringWithRange(Range(cpf.startIndex.advancedBy(i) ..< cpf.startIndex.advancedBy(i + 1))))
temp1 += char! * (10 - i)
temp2 += char! * (11 - i)
}
temp1 %= 11
temp1 = temp1 < 2 ? 0 : 11-temp1
temp2 += temp1 * 2
temp2 %= 11
temp2 = temp2 < 2 ? 0 : 11-temp2
if temp1 == d1 && temp2 == d2 {
return true
}
}
return false
}
}
@marcosatanaka
Copy link

Obrigado! Segue versão em Swift 5 para caso alguém precise:

extension String {

    var isCPF: Bool {
        let cpf = self.onlyNumbers()
        guard cpf.count == 11 else { return false }

        let i1 = cpf.index(cpf.startIndex, offsetBy: 9)
        let i2 = cpf.index(cpf.startIndex, offsetBy: 10)
        let i3 = cpf.index(cpf.startIndex, offsetBy: 11)
        let d1 = Int(cpf[i1..<i2])
        let d2 = Int(cpf[i2..<i3])

        var temp1 = 0, temp2 = 0

        for i in 0...8 {
            let start = cpf.index(cpf.startIndex, offsetBy: i)
            let end = cpf.index(cpf.startIndex, offsetBy: i+1)
            let char = Int(cpf[start..<end])

            temp1 += char! * (10 - i)
            temp2 += char! * (11 - i)
        }

        temp1 %= 11
        temp1 = temp1 < 2 ? 0 : 11-temp1

        temp2 += temp1 * 2
        temp2 %= 11
        temp2 = temp2 < 2 ? 0 : 11-temp2

        return temp1 == d1 && temp2 == d2
    }

    func onlyNumbers() -> String {
        guard !isEmpty else { return "" }
        return replacingOccurrences(of: "\\D",
                                    with: "",
                                    options: .regularExpression,
                                    range: startIndex..<endIndex)
    }

}

@wesleydst404
Copy link

Se digitar somente números repetidos a validação passa. Ex.: 11111111111.
De qualquer forma, obrigado.

@brunodelgado
Copy link

Versão atualizada que verifica também números repetidos.

extension String {
    var isCPF: Bool {
        let numbers = self.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
        guard numbers.count == 11 else { return false }

        let set = NSCountedSet(array: Array(numbers))
        guard set.count != 1 else { return false }

        let i1 = numbers.index(numbers.startIndex, offsetBy: 9)
        let i2 = numbers.index(numbers.startIndex, offsetBy: 10)
        let i3 = numbers.index(numbers.startIndex, offsetBy: 11)
        let d1 = Int(numbers[i1..<i2])
        let d2 = Int(numbers[i2..<i3])

        var temp1 = 0, temp2 = 0

        for i in 0...8 {
            let start = numbers.index(numbers.startIndex, offsetBy: i)
            let end = numbers.index(numbers.startIndex, offsetBy: i+1)
            let char = Int(numbers[start..<end])

            temp1 += char! * (10 - i)
            temp2 += char! * (11 - i)
        }

        temp1 %= 11
        temp1 = temp1 < 2 ? 0 : 11-temp1

        temp2 += temp1 * 2
        temp2 %= 11
        temp2 = temp2 < 2 ? 0 : 11-temp2

        return temp1 == d1 && temp2 == d2
    }
}

@jonhmendes
Copy link

Versão atualizada que verifica também números repetidos.

extension  String {
     var isCPF: Bool {
         let numbers =  self . componentes ( separados por : CharacterSet. decimalDigits . invertido ). números de guarda unidos ()
         . contagem == 11 else { return false }    

        let  set  =  NSCountedSet ( array : Array (numbers))
         guard  set . contagem  ! =  1  else { return  false }

        deixe i1 = números. índice (. números índiceInicial , offsetBy : 9 )
         deixe i2 = números. índice (. números índiceInicial , offsetBy : 10 )
         deixar i3 = números. índice (. números índiceInicial , offsetBy : 11 )
         deixe d1 =  Int (números [i1 .. < i2])
         deixar d2 =  Int(números [i2 .. < i3])

        var temp1 =  0 , temp2 =  0

        para i em  0 ... 8 {
             vamos começar = números. índice (. números índiceInicial , offsetBy : i)
             deixar finais = números. índice (. números índiceInicial , offsetBy : i + 1 )
             deixe de char =  Int (números [iniciar .. < final])

            temp1 + = char !  * ( 10  - i)
            temp2 + = char !  * ( 11  - i)
        }

        temp1 % =  11 
        temp1 = temp1 <  2  ?  0  :  11 - temp1

        temp2 + = temp1 *  2 
        temp2 % =  11 
        temp2 = temp2 <  2  ?  0  :  11 - temp2

        return temp1 == d1 && temp2 == d2
    }
}

um de CNPJ seria muito diferente disso?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment