Why does my CNPJ validation pass this invalid value?

7

I have a problem in a JS validation, in case it does not pass any invalid CNPJ value, but when typed only 000.000.000 / 0000.00 it lets it 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); 


    }
  }
}
    
asked by anonymous 15.01.2015 / 17:34

4 answers

7

Do this, my friend. 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 delete all the non-numeric characters of the last CNPJ as a parameter, considering that the person who invoked the function may have used a mask in the field.

The if statement in if (cnpj.length != 14)return false; checks if the number of numerals in the string (considering it has already been cleared) equals the correct number - 14.

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

Lines 23 to 49 check the two verifiers, verifying their validity according to the CNPJ algorithm. If not, validation returns false by closing the function.

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

Source: link

    
15.01.2015 / 17:46
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 tested the function by passing different parameters such as arrays, objects, or numbers. As errors occurred, I decided to slightly increase the initial part of the algorithm in the parameter validation:

  • Check first whether the value is empty, undefined or null. There's no need to do anything before that, or let it go.
  • Check if the parameter is different from a string (may have been a number, array, object, etc.)
  • Converts to string, after all cnpj may have been passed as number, and is required for the .replace () method below to function properly
  • Now apply replace () and proceed
  • I apologize for not being able to comment directly on his response, I use StackOverflow sparingly and my low reputation does not yet allow.

    I hope it's useful. Hugs to all!

        
    15.03.2016 / 23:01
    2

    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 operation and validation on the link link

        
    02.12.2016 / 15:14
    0

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

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

    The way is, in addition to implementing the official algorithm, also include an if that invalidates 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;
    }
    
        
    15.01.2015 / 18:04