Question: How can I verify that the format of a Peruvian RUC is valid?
What is the RUC? The Single Taxpayer Registry ( RUC ) is the computer registry where taxpayers from all over Peru are registered. It is the tax code for individuals and companies issued by SUNAT ( National Superintendence of Customs and Tax Administration ), with records since 1993 and regulated since 2004 [1] .
It is a unique key, of a permanent nature and mandatory use, for all natural or legal persons (national or foreign) [2] . SUNAT maintains the taxpayer registry, associating the RUC with personal data [3] .
Each taxpayer is identified with an 11-digit number. The first 2 digits identify the type of person, the next 8 are the DNI or the number assigned to the company, and the last one is a verification digit [4] [5] .
What I tried: I used the same code that SUNAT uses on its website to validate a RUC. However, it accepts incorrect RUCs and would appear to have redundant calculations.
//Validación de SUNAT
function valruc(valor){
valor = trim(valor)
if ( esnumero( valor ) ) {
if ( valor.length == 8 ){
suma = 0
for (i=0; i<valor.length-1;i++){
digito = valor.charAt(i) - '0';
if ( i==0 ) suma += (digito*2)
else suma += (digito*(valor.length-i))
}
resto = suma % 11;
if ( resto == 1) resto = 11;
if ( resto + ( valor.charAt( valor.length-1 ) - '0' ) == 11 ){
return true
}
} else if ( valor.length == 11 ){
suma = 0
x = 6
for (i=0; i<valor.length-1;i++){
if ( i == 4 ) x = 8
digito = valor.charAt(i) - '0';
x--
if ( i==0 ) suma += (digito*x)
else suma += (digito*x)
}
resto = suma % 11;
resto = 11 - resto
if ( resto >= 10) resto = resto - 10;
if ( resto == valor.charAt( valor.length-1 ) - '0' ){
return true
}
}
}
return false
}
function trim(cadena){
cadena2 = "";
len = cadena.length;
for ( var i=0; i <= len ; i++ )
if (cadena.charAt(i) != " "){
cadena2+=cadena.charAt(i);
}
return cadena2;
}
function esnumero(campo){
return (!(isNaN( campo )));
}
//Prueba
var ruc = '12345678903',
valido = valruc(ruc);
console.log('El RUC', ruc,
'es', (valido?'válido':'inválido'),
'para SUNAT.');
Objective: I am interested in validating the format of a RUC entered by a user, which can accept characters such as hyphens or other punctuation marks between the digits. I would use it as a preliminary stage before submitting a form.
Additionally, if there was a way to check if the RUC exists and is active, it would be even better.
I'm testing in JavaScript, but it can be in any popular language. The important thing is the algorithm.
Tests: I found the following list of manufacturing companies in companies.regioncallao.gob.pe (? PDF) that can be used as test data.
F̲u̲e̲n̲t̲e̲s̲:
① Legislative Decree No. 943 - http://www.elperuano.com.pe/NormasElperuano/2015/06/16/1251160-1.html
② SUNAT - Single Taxpayer Registry - http://www.sunat. gob.pe/legislacion/ruc/
③ RUC law regulation (?PDF) - http://mariano.freevar.com/ruc/REGLAMENTO%20DE%20LA%20LEY%20DEL%20RUC.pdf
④ What is the SUNAT ? What is the RUC? - http://conexiontributaria.blogspot.com.ar/2011/10/que-es-la-sunat-que-es-el-ruc-que_9779.html
⑤ Accounting forum - other RUC digits - http://www .perucontable.com/modules/newbb/viewtopic.php?post_id=57226
Code:
We use 3 functions (each calls the next if the result is valid):
validarInput(input)
rucValido(ruc)
obtenerDatosSUNAT(ruc)
Demo para móviles
Description:
The first step is to remove the characters we are not interested in (
-.,[]() \t\r\n\f
):Then, we check that we have an integer left:
And with the integer, we call the main function:
Inside the function, we see that they are 11 digits and that they start at 10, 15, 16, 17 or 20:
And, if all of the above is true, we can verify that the last digit (verifier) is correct.
How is the verification digit of a RUC validated?
SUNAT uses an adaptation of the method for control codes called Module 11 or ISBN 10 . It is a widely used method in these cases to detect errors in a single digit, or single or double exchanges (essentially, typing errors). Consists in:
suma % 11
).11 - resto
).if (ruc % 10 == complemento % 10)
).In other words, for each digit, we are going to add the last digit of the RUC (
ruc % 10
) and multiply it by its factor (i % 7 + (i/7|0) + 1
) -yes, this gives us 1, 2, 3, 4, 5, 6, 7, 2, 3, 4 , 5, for each value ofi
.In each iteration of
i
, we remove the last digit (ruc = ruc/10|0
).It should be noted that, to simplify the operation even more, we include the check digit in the same account (with factor 1 for
i=0
). We only need to adjust in cases where values greater than 9 are obtained in step 4. If it is 10 or 11, it means that the last digit is 0 or 1, and in those cases 1 is subtracted from the total sum (suma = -(ruc%10<2)
).So we are left with:
And it is checked when:
If this last condition is true, then the check digit is checked, and the RUC is valid.