Skip to content

Instantly share code, notes, and snippets.

@jplazcano87
Last active January 16, 2023 23:44
Show Gist options
  • Save jplazcano87/d74b9fb4e93e9fb49cda8f254b6dd80c to your computer and use it in GitHub Desktop.
Save jplazcano87/d74b9fb4e93e9fb49cda8f254b6dd80c to your computer and use it in GitHub Desktop.
Rut validator chile
import Foundation
enum RutError: ErrorType{
case InvalidRut(message : String)
}
class FormValidator: NSObject {
static func validateRut(value : String) throws ->String {
//clean rut
var rut = value.stringByReplacingOccurrencesOfString(".", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
rut = rut.stringByReplacingOccurrencesOfString("-", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
rut = rut.uppercaseString
//check length
if (rut.characters.count < 8 || rut.characters.count > 9 ) {
throw RutError.InvalidRut(message: "Rut ingresado no válido")
}
let rutRegEx = "^(\\d{1,3}(\\.?\\d{3}){2})\\-?([\\dkK])$"
let rutTest = NSPredicate(format:"SELF MATCHES %@", rutRegEx)
if (!rutTest.evaluateWithObject(rut)) {
throw RutError.InvalidRut(message: "Rut ingresado no válido")
}
let rutToValidate = getRutAndDv(rut)
let rutWithoutVerifier = rutToValidate.0
let verifiedDigit = rutToValidate.1
let calculatedVerifiedDigit = getVerifiedDigit(rutWithoutVerifier)
if (verifiedDigit != calculatedVerifiedDigit) {
throw RutError.InvalidRut(message: "Rut ingresado no válido")
}
return rut
}
static func getRutAndDv (value : String) -> (String, String) {
if (value.isEmpty || value.characters.count < 2) {
return ("","")
}
var rut = value.stringByReplacingOccurrencesOfString(".", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
rut = rut.stringByReplacingOccurrencesOfString("-", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
let verifiedDigit = Array(rut.characters)[rut.characters.count-1]
let range : Range<String.Index> = rut.startIndex..<rut.endIndex.advancedBy(-1)
let rutWithoutVerifiedDigit = rut.substringWithRange(range)
return (rutWithoutVerifiedDigit, String(verifiedDigit))
}
static func getVerifiedDigit (rut : String) -> String {
var acumulado : Int = 0
var ti : Int = 2
for index in (rut.characters.count-1).stride(through: 0, by: -1) {
let n = Array(rut.characters)[index]
let nl = String(n)
guard let vl = Int(nl) else {
return ""
}
acumulado += vl * ti
if (ti == 7) {
ti = 1
}
ti += 1
}
let resto : Int = acumulado % 11
let numericDigit : Int = 11 - resto
var digito : String = ""
if (numericDigit <= 9){
digito = String(numericDigit);
}else if (numericDigit == 10){
digito = "K"
}else{
digito = "0"
}
return digito
}
}
//para invocar
do{
let validator = try FormValidator.validateRut("16242343-5") //cambiar por string de rut a validar
}catch RutError.InvalidRut(let message) {
showMessage("Error", message: message, action: nil)
}catch{
DDLogError("an error ocurred during rut validation")
}
@jplazcano87
Copy link
Author

Hola , gracias por compartir el gist !

Como la expresión regular acepta k y K y la función validateDV returna siempre K
Este if puede marcar como invalido los rut que tengan la k en minúscula 👀

if (rutDV != calculatedDV){

Saludos 👋

bastaría un uppercase dentro de la función para que no se vea afectada por eso, gracias por notarlo

Saludos

@escurradeveloper
Copy link

y ¿ Cómo puedo escribir en el textfield y vaya apareciendo automaticamente esto: 22.435.545-K ?

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