Delphi = C #: Generic function to return collection bill DV

-1

I'm having problems with a Custom Module 11 function (which correctly returns the billing slip from any bank) that I already had in Delphi, and how I need to implement it on a C # system.

So I tried to make the C # version of it, but it is with logic or syntax error, since I do not have much affinity with C #.

It is worth mentioning that from the sequential flow point of view compared to the Delphi version, in my opinion, it is correct.

Follows:

     /// <summary>
    /// Remove a primeira ocorrência da substring em uma string completa
    /// </summary>
    /// <param name="source">String completa</param>
    /// <param name="remove">String para ser removida</param>
    /// <returns>Retorna a nova string sem os caracteres que foram retirados</returns>

    public static string RemoveFirst(this string source, string remove)
    {
        int index = source.IndexOf(remove);
        return (index < 0)
            ? source
            : source.Remove(index, remove.Length);
    }


            /// <summary>
            /// Valida o dígito verificador da linha digitável
            /// </summary>
            /// <param name="Valor">Linha Digitável</param>
            /// <param name="Base"></param>
            /// <param name="Resto"></param>
            /// <returns>Retorna o dígito verificador correspondente a linha digitável avaliada</returns>

            public static string Modulo11LinhaDigitavel(string Valor, int Base = 9, bool Resto = false)
            {

                int peso = 2;
                int soma = 0;
                int contador, digito, i;
                string retorno = "";

                for (i = 1; i <= Valor.Length; i++)
                {
                    int pos = Valor[i].ToString().IndexOf("0123456789");

                    if (pos < 0)

                        RemoveFirst(Valor, Valor[i].ToString());

                }

                Valor = Valor.Substring(0, 4) + // 1 e 4
                              Valor.Substring(32, 15) + // 33 e 15
                              Valor.Substring(4, 5) +  // 5 e 5
                              Valor.Substring(10, 10) + // 11 e 10
                              Valor.Substring(21, 10); // 22 e 10

                                                   // 1 e 4                    // 6 e 39
                Valor = Valor.Substring(0, 4) + Valor.Substring(5, 39);

                for (contador = Valor.Length; contador >= 0; contador--)
                {
                    soma = soma + (Convert.ToInt32(Valor[contador]) * peso);

                    if (peso < Base)
                    {
                        peso = peso + 1;
                    }
                    else
                    {
                        peso = 2;
                    }
                }

                if (Resto)
                {
                    retorno = (soma % 11).ToString();
                    return retorno;
                }
                else
                {
                    digito = 11 - (soma % 11);

                    if (digito > 9) 
                    { 

                        digito = 0;

                        retorno =  digito.ToString();

                        return retorno;
                    }
                }

                if (retorno == "0") { retorno = "1"; }

                return retorno;
            }

// Uma vez funcionado, teria que retornar 5, que é o DV da linha digitável abaixo em questão        

       static void Main(string[] args)
        {

            Console.WriteLine(Modulo11LinhaDigitavel("10490.05539 03698.700006 00091.449587 5 55490000028531"));
            Console.ReadKey();

        }

The Delphi version can be viewed here

    
asked by anonymous 27.04.2016 / 00:39

1 answer

3

Not to be left without an answer I gave an improvement. I fixed some errors. I had things that the code translation was completely wrong, or had performance issues, and the style was not C #. He had unnecessary things too. It may not be the desired result, but now at least it runs without error and has a better basis to debug and find if something is wrong. It looks like this:

public static string Modulo11LinhaDigitavel(string valor, int digitoBase = 9, bool resto = false) {
    var linha = new StringBuilder(valor.Length);
    for (var i = 0; i < valor.Length; i++) {
        if ("0123456789".IndexOf(valor[i]) >= 0) {
            linha.Append(valor.Substring(i, 1));
        }
    }
    var linhaOrdenada = linha.ToString();
    linhaOrdenada = linhaOrdenada.Substring(0, 4) + 
                    linhaOrdenada.Substring(32, 15) + 
                    linhaOrdenada.Substring(4, 5) +  
                    linhaOrdenada.Substring(10, 10) + 
                    linhaOrdenada.Substring(21, 10); 
    linhaOrdenada = linhaOrdenada.Substring(0, 4) + linhaOrdenada.Substring(5, 39);
    var soma = 0;
    var peso = 2;
    for (var i = linhaOrdenada.Length - 1; i >= 0; i--) {
        soma += Convert.ToInt32(linhaOrdenada.Substring(i, 1)) * peso;
        if (peso < digitoBase) {
            peso++;
        } else {
            peso = 2;
        }
    }
    var retorno = "";
    if (resto) {
        retorno = (soma % 11).ToString();
    } else {
        var digito = 11 - (soma % 11);
        if (digito > 9) { 
            digito = 0;
        }
        retorno = digito.ToString();
    }
    if (retorno == "0") { return "1"; }
    return retorno;
}

See working on dotNetFiddle .

Taking the manual and making your own code can do a lot less work. This algorithm is not good, could be done better.

    
27.04.2016 / 02:12