Why does my CNPJ validation pass this invalid value?

Asked

Viewed 6,781 times

7

I have a problem with a JS validation, in case it does not pass any invalid CNPJ value, but when typed only 000.000.000/0000.00 it lets pass normally.

function ValidaCNPJ(cnpj) {

  var i = 0;
  var l = 0;
  var strNum = "";
  var strMul = "0000000000000";
  var character = "";
  var iValido = 1;
  var iSoma = 0;
  var strNum_base = "";
  var iLenNum_base = 0;
  var iLenMul = 0;
  var iSoma = 0;
  var strNum_base = 0;
  var iLenNum_base = 0;

  if (cnpj == "")
    return false;

  l = cnpj.length;
  for (i = 0; i < l; i++) {
    caracter = cnpj.substring(i,i+1)
    if ((caracter >= '0') && (caracter <= '9'))
       strNum = strNum + caracter;
  };

  if(strNum.length != 14)
    return false;

  strNum_base = strNum.substring(0,12);
  iLenNum_base = strNum_base.length - 1;
  iLenMul = strMul.length - 1;
  for(i = 0;i < 12; i++)
    iSoma = iSoma +
            parseInt(strNum_base.substring((iLenNum_base-i),(iLenNum_base-i)+1),10) *
            parseInt(strMul.substring((iLenMul-i),(iLenMul-i)+1),10);

  iSoma = 11 - (iSoma - Math.floor(iSoma/11) * 11);
  if(iSoma == 11 || iSoma == 10)
    iSoma = 0;

  strNum_base = strNum_base + iSoma;
  iSoma = 0;
  iLenNum_base = strNum_base.length - 1
  for(i = 0; i < 13; i++)
    iSoma = iSoma +
            parseInt(strNum_base.substring((iLenNum_base-i),(iLenNum_base-i)+1),10) *
            parseInt(strMul.substring((iLenMul-i),(iLenMul-i)+1),10)

  iSoma = 11 - (iSoma - Math.floor(iSoma/11) * 11);
  if(iSoma == 11 || iSoma == 10)
    iSoma = 0;
  strNum_base = strNum_base + iSoma;
  if(strNum != strNum_base) {
    return false
  }else{
    return true;
  }
}

window.onload = function (){
  var cnpj = document.getElementById('reg_billing_cnpj');

  cnpj.onblur = function(){
    var valid = ValidaCNPJ(this.value);
    if(valid == false){

      alert("Informe um CNPJ válido");
      cnpj.focus(); 
      return (false); 


    }
  }
}
  • I’d put a cnpj.replace(/[^\d+]/g, '') to work with numerical values only :)

4 answers

7


Do it, buddy. It works perfectly for me:

function validarCNPJ(cnpj) {

    cnpj = cnpj.replace(/[^\d]+/g,'');

    if(cnpj == '') return false;

    if (cnpj.length != 14)
        return false;

    // LINHA 10 - Elimina CNPJs invalidos conhecidos
    if (cnpj == "00000000000000" || 
        cnpj == "11111111111111" || 
        cnpj == "22222222222222" || 
        cnpj == "33333333333333" || 
        cnpj == "44444444444444" || 
        cnpj == "55555555555555" || 
        cnpj == "66666666666666" || 
        cnpj == "77777777777777" || 
        cnpj == "88888888888888" || 
        cnpj == "99999999999999")
        return false; // LINHA 21

    // Valida DVs LINHA 23 -
    tamanho = cnpj.length - 2
    numeros = cnpj.substring(0,tamanho);
    digitos = cnpj.substring(tamanho);
    soma = 0;
    pos = tamanho - 7;
    for (i = tamanho; i >= 1; i--) {
      soma += numeros.charAt(tamanho - i) * pos--;
      if (pos < 2)
            pos = 9;
    }
    resultado = soma % 11 < 2 ? 0 : 11 - soma % 11;
    if (resultado != digitos.charAt(0))
        return false;

    tamanho = tamanho + 1;
    numeros = cnpj.substring(0,tamanho);
    soma = 0;
    pos = tamanho - 7;
    for (i = tamanho; i >= 1; i--) {
      soma += numeros.charAt(tamanho - i) * pos--;
      if (pos < 2)
            pos = 9;
    }
    resultado = soma % 11 < 2 ? 0 : 11 - soma % 11;
    if (resultado != digitos.charAt(1))
          return false; // LINHA 49

    return true; // LINHA 51

}

In cnpj = cnpj.replace(/[^\d]+/g,'');, we have deleted all non-numerical characters from the CNPJ passed as parameter, considering that whoever invoked the function may have used a possible mask in the field.

The if instruction in if (cnpj.length != 14)return false; checks whether the number number of the string (considering it already clean) is equal to the correct amount - 14.

The lines 10 to 21 check whether the string is formed only by equal values. This verification is necessary since if we apply the CNPJ algorithm on the number "22.222.222/2222-22" in theory the check digits are correct, even if this is NOT a valid number.

Lines 23 through 49 check the two check digits, verifying their validity according to the CNPJ algorithm. If no, the validation returns false by terminating the function.

If the algorithm reaches line 51 we have a valid CNPJ and the true value is returned.

Source: http://www.geradorcnpj.com/javascript-validar-cnpj.htm

  • Is still passing the 000.

  • I EDITED THE ANSWER

  • Thank you Rafael, this implementation worked, thank you very much!

  • Mark as positive :)

3

There is a more compact function to validate CNPJ:

function is_cnpj(c) {
    var b = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];

    if ((c = c.replace(/[^\d]/g, "")).length != 14)
        return false;

    if (/0{14}/.test(c))
        return false;

    for (var j = 0; j < 2; ++j) {
        for (var i = 0, n = 0; i < 12 + j; n += c[i] * b[++i - j]);
        if (c[12 + j] != ((n %= 11) < 2) ? 0 : 11 - n)
            return false;
    }

    return true;
};

You can test the operation and validation on the link http://araujo.cc/blog/funcao-javascript-para-validar-cnpj.html

  • 1

    Quiet. For me, less code is better read, updated my gist and the answer. =)

  • 1

    Thinking better here, despite having more code, I think that the first function was with a better reading... sla, now I was in doubt haha

  • 1

    Bele, you’re right haha! but apparently it’s working.

2

Just adding a bit of improvement to the @Lollipop response, just below the explanation:

function validarCNPJ(cnpj) {
	
    if(cnpj == '' || cnpj == undefined || cnpj == null) {
        return false;
    }
	
    if (typeof(cnpj) != 'string') {
	cnpj = cnpj.toString();
    }
	
    cnpj = cnpj.replace(/[^\d]+/g,'');
  
    // (Restante ok...)

I did tests with the function by passing different parameters such as arrays, objects or Numbers. As errors occurred, I decided to increment a little the initial part of the algorithm in the parameter validation:

  1. Check first of all if the value is empty, undefined or null. There is no need to do anything before that, nor to let go.
  2. Check if the parameter is different from a string (may have come a number, array, Object, etc.)
  3. Converts to string, after all cnpj may have been passed as number, and it is necessary for the . replace() method below to work correctly
  4. Now apply replace() and proceed

I apologize for not being able to comment directly on his reply, I use little Stackoverflow and my low reputation still does not allow.

I hope it will be useful. Hugs to all!

  • Thank you, Wesley.

0

Although there is no CNPJ or CPF with all digits repeated, the official logic of validating the check digit of these documents declares them as valid.

Note that not only a sequence of zeros will pass but also a sequence of one or of two or of any digit.

The way is, in addition to implementing the official algorithm, to include a if invalidating the document if all digits are equal.

Some ways to do this:

function todosDigitosSaoIguais(cnpj) {
    var cnpj_arr = cnpj.split("");
    var first = cnpj_arr[0];
    return cnpj_arr.every(function(element) {
        return element === first;
    });
}

Or:

function todosDigitosSaoIguais(cnpj) {
    for(var i = 1; i < cnpj.length; i++)
    {
        if(cnpj[i] !== cnpj[0])
            return false;
    }
    return true;
}
  • 2

    I don’t usually mind negative votes but in this case I was curious... what’s wrong with the answer?

  • 2

    This way of checking trivial cases is even better than the answer accepted IMO. They must have been negative because a string does not have the Every method but an array so you need to do cnpj.split('').every

  • @renatoargh I had tested the code on the Chrome console and it worked. Still I changed it; thank you. In any case, I do not believe that the negative votes are because the other option always works and they would also have edited or commented. If they could not add anything other than the vote I conclude that it was mere lack of knowledge of the cause.

  • 1

    So if it worked you probably tested a different version kkkk. Anyway now that you’ve edited I’ve voted in and I’ll improve my algorithm to treat these trivial cases as well!

  • I did not negatively and I do not understand the herd either, but perhaps the problem is that your answer contains only the relevant part and not the full function. It would look better with the final result already included.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.