Is the calculation of RENAVAN correct? Can you improve something?

Asked

Viewed 368 times

2

Hello, I am searching on the internet and found on that website a code in C# of how to calculate RENAVAM, I moved a little, but I can’t find anywhere that explains how RENAVAM calculus actually works so I don’t know if this logic is correct.

Code no. NET Fiddle

Code:

public static bool isRENAVAM(string RENAVAM)
        {
            if (string.IsNullOrEmpty(RENAVAM.Trim()))
                return false;

            int[] d = new int[11];
            //sequencia para calcular o RENAVAM
            string sequencia = "3298765432";
            string SoNumero = Regex.Replace(RENAVAM, "[^0-9]", string.Empty);

            if (string.IsNullOrEmpty(SoNumero))
                return false;

            //verificando se todos os numeros são iguais 
            if (new string(SoNumero[0], SoNumero.Length) == SoNumero) 
                return false;

            SoNumero = Convert.ToInt64(SoNumero).ToString("00000000000");

            int v = 0;
        for (int i = 0; i < 11; i++)
            d[i] = Convert.ToInt32(SoNumero.Substring(i, 1));

        for (int i = 0; i < 10; i++)
            v += d[i] * Convert.ToInt32(sequencia.Substring(i, 1));

        v = (v * 10) % 11;
        v = (v != 10) ? v : 0;

        return (v == d[10]);
    }

My doubts are:

1. This code to calculate RENAVAM is correct?

2. What is the logic for calculating RENAVAM?

3. There’s something I can improve on that code?

  • 1

    1 - Test here with these numbers http://gerador.info/renavam 2 - Good question 3 -

  • @Paulohdsousa could post the code with the changes you would make and with the explanation of why would you change them? (Note. yes I am new in this world of programming '-')

  • I tested it several times and it worked, and I tested it with broken numbers and gave the right answers, I think I will use this code even, with its improvements

2 answers

4


An improvement in the code:

    public static bool IsRENAVAM(string RENAVAM)
    {
        if (string.IsNullOrEmpty(RENAVAM.Trim()))
            return false;

        var sequencia = new int[]{ 3, 2, 9, 8, 7, 6, 5, 4, 3, 2 };
        var soNumero = Regex.Replace(RENAVAM, "[^0-9]", string.Empty);

        if (string.IsNullOrEmpty(soNumero))
            return false;
        //verificando se todos os numeros são iguais 
        if (soNumero.Distinct().Count() ==1 )
            return false;

        var d = soNumero.ToCharArray().Select(i => int.Parse(i.ToString())).Take(11);
        var v = (d.Zip(sequencia, (n, seq) => n * seq).Sum() * 10) % 11;            
        v = (v != 10) ? v : 0;
        return (v == d.ElementAt(10));
    }
}

Using the Zip of Enumerable kills a loop which decreases cyclomatic complexity and number of lines, converting the string soNumero for a IEnumerable<int> is much more performatic than converting to long and to string again, link to understand a little better why I used Zip on an enumerator instead of foreach on an array

  • 3

    Could you explain why this way is better?

  • I, too, really, wanted to know why she’s better.

  • I’ve never heard of a method. Zip, thank you. + 1

1

Follow the slightly improved code

public static bool isRENAVAM(string RENAVAM)
        {
            if (string.IsNullOrEmpty(RENAVAM.Trim()))
                return false;

            string SoNumero = Regex.Replace(RENAVAM, "[^0-9]", string.Empty);

            if (string.IsNullOrEmpty(SoNumero) || new string(SoNumero[0], SoNumero.Length) == SoNumero)
                return false;

            int[] d = new int[11];
            string sequencia = "3298765432";

            SoNumero = Convert.ToInt64(SoNumero).ToString("00000000000");

            int v = 0;
        for (int i = 0; i < 11; i++)
            d[i] = Convert.ToInt32(SoNumero.Substring(i, 1));

        for (int i = 0; i < 10; i++)
            v += d[i] * Convert.ToInt32(sequencia.Substring(i, 1));

        v = (v * 10) % 11;
        v = (v != 10) ? v : 0;

        return (v == d[10]);
    }
  • ah yes, join the checks and declare what will not be used now after, thanks for the tip!

  • 1

    Could you explain why this way is better?

  • Not so much better, only put AFTER the Return variables that will be used only if you have correct the numbers and put the 2 checks in 1... ta more for a cleaning that way better.

Browser other questions tagged

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