none
Converter função php em c# para winform.(Agradeceria muito) RRS feed

  • Pergunta

  • Tarde, Alguem poderia me ajudar a converter esta função em php para c# para aplicação winform?

        

    function CalculaDv10($Numero) {
       $Numero = trim($Numero);

       if (empty($Numero) or ! is_numeric($Numero)) {
          return 0;
       }    

       $posicao1 = strlen($Numero)-1; 
       $multi    = 2;                  
       $acumula  = 0;                 

       while ($posicao1 >= 0) 
         {       
          $resultado = substr($Numero, $posicao1, 1) * $multi;
          $posicao2  = strlen($resultado) - 1;

          while ($posicao2 >= 0) {     
             $acumula = $acumula + substr($resultado, $posicao2, 1);
             $posicao2--;
          }

          $multi = (($multi == 2) ? 1 : 2);  

          $posicao1--; 
       }

       $Dv = bcmod($acumula, 10);

       $Dv = (10 - $Dv);

          if ($Dv == 10) {
          $Dv = 0; 
       }

       return $Numero . '-' . $Dv;

    quarta-feira, 4 de novembro de 2020 16:30

Respostas

  • Olá, Juliander! Segue a tradução que fiz:

    public string CalculaDiv10(string numero)
    {
        numero = numero.Trim();
        if(string.IsNullOrEmpty(numero) || !double.TryParse(numero, out double numeroAsDouble)) return "0";
        var posicao1 = numero.Length - 1;
        var multi = 2;
        var acumula = "0";
        while (posicao1 >= 0)
        {
            var resultado = string.Concat(Enumerable.Repeat(numero.Substring(posicao1, 1), multi));
            var posicao2 = resultado.Length - 1;
            while (posicao2 >= 0)
            {
                acumula += resultado.Substring(posicao2, 1);
                posicao2--;
            }
    
            multi = multi == 2 ? 1 : 2;
            posicao1--;
        }
    
    
        var dv = double.Parse(acumula) % 10;
        dv = 10 - dv;
        dv = dv == 10 ? 0 : dv;
    
        return $"{numero}-{dv}";
    }

    Compilei a função para os valores 70, 85, 98, 279 e 957, obtendo 70-3, 85-2, 98-1, 279-8, 957-1, respectivamente. Caso não estejam corretos você poderia postar um exemplo do que seria esperado como resultado?

    Att


    Confira meus cursos na Udemy em https://www.udemy.com/user/wallace-andrade/

    • Marcado como Resposta juliander quinta-feira, 5 de novembro de 2020 12:56
    quinta-feira, 5 de novembro de 2020 01:01
  • // Cálculo de dígito verificador módulo 10
    public int CalculaDAC10(string numeroStr)
    {
        using(var reader = new StringReader(numeroStr))
        {
            var buffer = new char[]{'0'};
            var fatorMultiplicador = 2;
            var produtos = new List<int>();
            
            // 1. Multiplicação pela seqüência 2, 1, 2, 1, ... da direita para a esquerda.
            while(reader.Peek() > 0)
            {
                // lê um caractere do número
                reader.ReadBlock(buffer, 0, 1); 
                // realiza multiplicação pelo fator e armazena em variável temporária
                var resultadoTemp = int.Parse(buffer[0].ToString()) * fatorMultiplicador;
                // lê cada digito do resultado anterior e armazena na lista de produtos
                foreach(var digito in resultadoTemp.ToString()) produtos.Add(int.Parse(digito.ToString()));
                fatorMultiplicador = fatorMultiplicador == 2 ? 1 : 2; // altera o fator para satisfazer o algoritmo
            }
    
            // 2. Soma dos dígitos do produto
            var resultado = produtos.Sum();
            // 3. Divisão do resultado da soma acima por 10
            // para obter o resto
            var resto = resultado % 10;
            // Quando o resto da divisão for 0, o DAC é 0;
            // caso contrário, o DAC é 10 subtraído do resto
            return resto == 0 ? resto : 10 - resto;
        }
    }
    
    private void button3_Click(object sender, EventArgs e)
    {
        string numerobar = textBox1.Text;
        string primeiroBloco = numerobar.Substring(0,11);
        string segundoBloco = numerobar.Substring(11, 11);
        string terceiroBloco = numerobar.Substring(22 ,11);
        string quartoBloco = numerobar.Substring(33, 11);
    
        // Calculando os DACs
        var dacPrimeiroBloco = CalculaDAC10(primeiroBloco);
        var dacSegundoBloco = CalculaDAC10(segundoBloco);
        var dacTerceiroBloco = CalculaDAC10(terceiroBloco);
        var dacQuartoBloco = CalculaDAC10(quartoBloco);
    
        // Exibindo numeros com DACs
        textBox2.Text = $"{primeiroBloco}-{dacPrimeiroBloco} {segundoBloco}-{dacSegundoBloco} {terceiroBloco}-{dacTerceiroBloco} {quartoBloco}-{dacQuartoBloco}";
    
    }

    Segundo a documentação que me passou implementei o método CalculaDAC10 e este retorna somente o Dígito de Auto Conferência (DAC). Dessa forma fica mais fácil reaproveitar o método em outras partes do teu código (aconselho até a criar uma classe separada para isso pois me parece que está no code behind do teu form).

    Agora basta ajustar conforme tua necessidade.

    Forte abraço!


    Confira meus cursos na Udemy em https://www.udemy.com/user/wallace-andrade/

    • Marcado como Resposta juliander quinta-feira, 5 de novembro de 2020 19:37
    quinta-feira, 5 de novembro de 2020 17:56

Todas as Respostas

  • Olá, Juliander! Segue a tradução que fiz:

    public string CalculaDiv10(string numero)
    {
        numero = numero.Trim();
        if(string.IsNullOrEmpty(numero) || !double.TryParse(numero, out double numeroAsDouble)) return "0";
        var posicao1 = numero.Length - 1;
        var multi = 2;
        var acumula = "0";
        while (posicao1 >= 0)
        {
            var resultado = string.Concat(Enumerable.Repeat(numero.Substring(posicao1, 1), multi));
            var posicao2 = resultado.Length - 1;
            while (posicao2 >= 0)
            {
                acumula += resultado.Substring(posicao2, 1);
                posicao2--;
            }
    
            multi = multi == 2 ? 1 : 2;
            posicao1--;
        }
    
    
        var dv = double.Parse(acumula) % 10;
        dv = 10 - dv;
        dv = dv == 10 ? 0 : dv;
    
        return $"{numero}-{dv}";
    }

    Compilei a função para os valores 70, 85, 98, 279 e 957, obtendo 70-3, 85-2, 98-1, 279-8, 957-1, respectivamente. Caso não estejam corretos você poderia postar um exemplo do que seria esperado como resultado?

    Att


    Confira meus cursos na Udemy em https://www.udemy.com/user/wallace-andrade/

    • Marcado como Resposta juliander quinta-feira, 5 de novembro de 2020 12:56
    quinta-feira, 5 de novembro de 2020 01:01
  • Ola bom dia @wallacemariadeandrade, obg.... isso seria para gerar dv do codigo barras de arrecadação.

    exemplo de entradas(sem espaços): 85670000000 65000064311 51934193800 00181093090

    saida esperada(sem espaços): 85670000000-8 65000064311-6 51934193800-8 00181093090-7

    Agradeço pela ajuda desde ja!



    • Editado juliander quinta-feira, 5 de novembro de 2020 12:55
    quinta-feira, 5 de novembro de 2020 11:20
  • ou seja entrarei com um  numero de 44 posiçoes, e a cada 11 posiçoes ele gera o dv, como no exemplo.

    Agradeço bastante pela ajuda, e acredito que isso ajudaria bastante a galera, porque procurei solução para essa implementação e nao achei nada, agora acho que ajudaria muito principalmente quem precisa da implementação para modulo 10... 

    como estabelecido pela especificação da febraban:

    https://cmsportal.febraban.org.br/Arquivos/documentos/PDF/Layout%20-%20C%C3%B3digo%20de%20Barras%20ATUALIZADO.pdf

    quinta-feira, 5 de novembro de 2020 11:25
  • tem como me ajudar a saida esta dando :

    fiz um subsring na entrada a cada 11 digitos( saida sem espaço):

    da aplicação: 85670000000-2  65000064311-4   51934193800-5  00181093090-0

    esperado:       85670000000-8  65000064311-6    51934193800-8   00181093090-7

    pank isso... ate coloquei o pdf abaixo das especificações!!!



    • Editado juliander quinta-feira, 5 de novembro de 2020 12:55
    quinta-feira, 5 de novembro de 2020 12:39
  •  // Cálculo de dígito verificador módulo 10
            double numeroAsDouble;
            public string CalculaDiv10(string numero)
            {
                numero = numero.Trim();
                if (string.IsNullOrEmpty(numero) || !double.TryParse(numero, out numeroAsDouble))
                {
                    return "0";
                }
                // Inicializa variáveis
                var posicao1 = numero.Length - 1; // Obtém a posição do último dígito da string
                var multi = 2;                   // Declara o multiplicador com o valor de 2
                var acumula = "0";                // Variável que acumulará a soma dos dígitos

                // Loop principal de cálculo
                while (posicao1 >= 0)
                {
                    var resultado = string.Concat(Enumerable.Repeat(numero.Substring(posicao1, 1), multi)); // Loop para multiplicar cada dígito da string por 2 ou 1, da direita para a esquerda
                    var posicao2 = resultado.Length - 1;                                                   // Loop para acumular a soma dos dígitos do resultado da multiplicação


                    // Loop para acumular a soma dos dígitos do resultado da multiplicação
                    while (posicao2 >= 0)                                                                   
                    {
                        acumula += resultado.Substring(posicao2, 1); 
                        posicao2--;
                    }

                    multi = multi == 2 ? 1 : 2;         // Alterna o multiplicador entre 2 e 1
                    posicao1--;                        // Controla a posição da string a ser processada
                }

                // Obtem o resto da divisão por dez:
                var dv = double.Parse(acumula) % 10;
                // Subtrai de 10 o resto obtido:
                dv = 10 - dv;
                // Se o resultado for dez, retorna zero:
                dv = dv == 10 ? 0 : dv;

                MessageBox.Show(numero + "-" + dv);
                textBox2.Text = textBox2.Text + numero + "-" + dv;
                return $"{numero}-{dv}";
                

            }
            private void button3_Click(object sender, EventArgs e)
            {
                string numerobar = textBox1.Text;
                string primeirobloco = numerobar.Substring(0,11);
                string segundobloco = numerobar.Substring(11, 11);
                string terceirobloco = numerobar.Substring(22 ,11);
                string quartobloco = numerobar.Substring(33, 11);
                CalculaDiv10(primeirobloco);
                CalculaDiv10(segundobloco);
                CalculaDiv10(terceirobloco);
                CalculaDiv10(quartobloco);

            }    
    quinta-feira, 5 de novembro de 2020 13:05
  • coloquei os comentarios no codigo tem cm me ajudar ajustar? a solução para a saida prevista?

    e pank...isso !!

    quinta-feira, 5 de novembro de 2020 13:11
  • Entendi aqui a regra... como esta no pdf, ele soma digito a digo, exemplo:

    se o resultado da multiplicação da intercalação de 2 e 1 for decimal--> 12, temos que separar para somar...

    1+2...

    entendeu?

    https://cmsportal.febraban.org.br/Arquivos/documentos/PDF/Layout%20-%20C%C3%B3digo%20de%20Barras%20ATUALIZADO.pdf

    vou implementar aqui...

    vlw msm!!!

    quinta-feira, 5 de novembro de 2020 15:29
  • // Cálculo de dígito verificador módulo 10
    public int CalculaDAC10(string numeroStr)
    {
        using(var reader = new StringReader(numeroStr))
        {
            var buffer = new char[]{'0'};
            var fatorMultiplicador = 2;
            var produtos = new List<int>();
            
            // 1. Multiplicação pela seqüência 2, 1, 2, 1, ... da direita para a esquerda.
            while(reader.Peek() > 0)
            {
                // lê um caractere do número
                reader.ReadBlock(buffer, 0, 1); 
                // realiza multiplicação pelo fator e armazena em variável temporária
                var resultadoTemp = int.Parse(buffer[0].ToString()) * fatorMultiplicador;
                // lê cada digito do resultado anterior e armazena na lista de produtos
                foreach(var digito in resultadoTemp.ToString()) produtos.Add(int.Parse(digito.ToString()));
                fatorMultiplicador = fatorMultiplicador == 2 ? 1 : 2; // altera o fator para satisfazer o algoritmo
            }
    
            // 2. Soma dos dígitos do produto
            var resultado = produtos.Sum();
            // 3. Divisão do resultado da soma acima por 10
            // para obter o resto
            var resto = resultado % 10;
            // Quando o resto da divisão for 0, o DAC é 0;
            // caso contrário, o DAC é 10 subtraído do resto
            return resto == 0 ? resto : 10 - resto;
        }
    }
    
    private void button3_Click(object sender, EventArgs e)
    {
        string numerobar = textBox1.Text;
        string primeiroBloco = numerobar.Substring(0,11);
        string segundoBloco = numerobar.Substring(11, 11);
        string terceiroBloco = numerobar.Substring(22 ,11);
        string quartoBloco = numerobar.Substring(33, 11);
    
        // Calculando os DACs
        var dacPrimeiroBloco = CalculaDAC10(primeiroBloco);
        var dacSegundoBloco = CalculaDAC10(segundoBloco);
        var dacTerceiroBloco = CalculaDAC10(terceiroBloco);
        var dacQuartoBloco = CalculaDAC10(quartoBloco);
    
        // Exibindo numeros com DACs
        textBox2.Text = $"{primeiroBloco}-{dacPrimeiroBloco} {segundoBloco}-{dacSegundoBloco} {terceiroBloco}-{dacTerceiroBloco} {quartoBloco}-{dacQuartoBloco}";
    
    }

    Segundo a documentação que me passou implementei o método CalculaDAC10 e este retorna somente o Dígito de Auto Conferência (DAC). Dessa forma fica mais fácil reaproveitar o método em outras partes do teu código (aconselho até a criar uma classe separada para isso pois me parece que está no code behind do teu form).

    Agora basta ajustar conforme tua necessidade.

    Forte abraço!


    Confira meus cursos na Udemy em https://www.udemy.com/user/wallace-andrade/

    • Marcado como Resposta juliander quinta-feira, 5 de novembro de 2020 19:37
    quinta-feira, 5 de novembro de 2020 17:56
  • sim fiz na correia precisava usar essa rotina com urgencia, cheguei a implementar o metodo , ficou meio esdruxo nao deu para pensar na melhores praticas... mas agora vou enxugar cm vc fez... ficou muito bom!!! 

    valeu msm... nota 10!!!

    quinta-feira, 5 de novembro de 2020 19:46