namio 0 Denunciar post Postado Agosto 1, 2005 Prezados colegas: Segue abaixo código fonte de um novo tipo de dados que criei para a validação de cpfs. Na verdade, trata-se de uma estrutura (struct), desenvolvida em C#, para tratar dados do tipo CPF. a melhor maneira de utilizá-la, é criar um novo projeto de classes e colocar o código abaixo dentro deste projeto; compilar, gerando assim uma dll e utilizar esta dll nos códigos de vocês; podendo este código ser VB, C# ou qualquer outro que possa interagir com a plataforma .NET. Em particular, testei em VB e C# e a estrutura se comportou perfeitamente. using System;using System.Text.RegularExpressions;namespace Digitos{ /// <summary> /// Representa um número de CPF /// </summary> [Serializable] public struct Cpf : ICloneable { private static string _cpf; /// <summary> /// Retorna os dígitos verificadores do CPF /// </summary> /// <value>String</value> public string Digitos { get { if (_cpf.Length == 0) return string.Empty; return _cpf.Substring(9, 2); } } /// <summary> /// Retorna os nove primeiros dígitos do CPF /// </summary> public string Raiz { get { if (_cpf.Length == 0) return string.Empty; return _cpf.Substring(0, 9); } } /// <summary> /// Inicializa uma nova instância da estrutura Cpf /// </summary> /// <param name="obj">Objeto do tipo string contendo o número do CPF.</param> private Cpf(string obj) { _cpf = obj; } /// <summary> /// Valida o CPF /// </summary> /// <returns>Retorna true se o CPF informado for um CPF válido. Caso contrário, retorna false</returns> public bool IsValid() { if (_cpf.Trim().Length < 11) return false; int d1 = Cpf.CalculaDigitos(_cpf.Substring(0, 9)); int d2 = Cpf.CalculaDigitos(_cpf.Substring(1, 9)); d1 = ((d1 % 11) < 2) ? 0 : 11 - (d1 % 11); d2 = ((d2 % 11) < 2) ? 0 : 11 - (d2 % 11); string cpf = _cpf.Substring(0, 9) + d1.ToString() + d2.ToString(); return (_cpf.CompareTo(cpf) == 0); } /// <summary> /// Retorna um CPF com os dígitos verificadores corrigidos, a partir de um CPF inválido, passado por cpf. /// </summary> /// <param name="cpf">CPF cujos dígitos deverão ser calculados</param> /// <returns>Um CPF com os dígitos verificadores corrigidos</returns> public static Cpf Fix(Cpf cpf) { if (cpf.ToString().Length == 0) throw new ArgumentException("cpf"); if (! cpf.IsValid()) { string raiz = cpf.Raiz; int d1 = Cpf.CalculaDigitos(raiz); d1 = ((d1 % 11) < 2) ? 0 : 11 - (d1 % 11); string resultado = raiz + d1.ToString(); int d2 = Cpf.CalculaDigitos(resultado.Substring(1)); d2 = ((d2 % 11) < 2) ? 0 : 11 - (d2 % 11); return resultado + d2.ToString(); } return cpf; } /// <summary> /// Método recursivo utilizado pelo método IsValid() para calculo dos dígitos verificadores /// <see cref="IsValid"/> /// </summary> /// <param name="raiz"> /// String de nove posições, contendo os nove dígitos necessários para o cálculo de cada um /// dos dois dígitos verificadores do CPF /// </param> /// <returns>Objeto do tipo Int32, contendo o valor calculado para raiz</returns> private static int CalculaDigitos(string raiz) { if (raiz.Length == 1) return (int.Parse(raiz) * 2); return (int.Parse(raiz.Substring(0, 1)) * (raiz.Length + 1) + CalculaDigitos(raiz.Substring(1))); } /// <summary> /// Converte um valor string em CPF /// </summary> /// <param name="valor">string contendo o valor a ser convertido em CPF</param> /// <returns>Um objeto do tipo Cpf a partir de valor</returns> public static Cpf Parse(string valor) { Cpf temp = valor; return temp; } /// <summary> /// Representa o valor desta instância convertido em uma string com o seguinte formato: /// xxx.xxx.xxx-xx /// </summary> /// <returns>Uma string representando o valor desta instância formatado com pontos e hífen</returns> public string Format() { return this.Format(Convert.ToChar("."), Convert.ToChar("-")); } /// <summary> /// Representa o valor desta instância convertido em uma string, formatado com os separadores /// especificados. /// </summary> /// <param name="sep1"> /// Caractere utilizado para separar os nove primeiros dígitos do CPF em grupos de três dígitos /// </param> /// <param name="sep2"> /// Caractere utilizado para separar os três grupos de três dígitos do CPF dos dígitos verificadores /// </param> /// <returns> /// Uma string representando o valor desta instância formatado com os separadores indicados /// </returns> /// <example> /// <code> /// using System; /// using System.Globalization; /// public class MainClass /// { /// public static void Main(string[] args) /// { /// Cpf valor = "34587647588"; /// /// Console.WriteLine(valor.Format()); /// Console.WriteLine(valor.Format(Convert.ToChar(" "), Convert.ToChar("/")); /// /** Output. /// * /// * 345.876.475-88 /// * 345 876 475/88 /// */ /// } /// } /// </code> /// </example> public string Format(char sep1, char sep2) { if (_cpf.Trim().Length == 0) return _cpf; string padrao = @"^(\d{3})(\d{3})(\d{3})(\d{2})"; string cpf = string.Empty; Regex r = new Regex(padrao); Match m = r.Match(_cpf); return m.Groups[1].Value + sep1 + m.Groups[2].Value + sep1 + m.Groups[3].Value + sep2 + m.Groups[4].Value; } /// <summary> /// Retorna o valor desta instância convertido para string /// </summary> /// <returns>Uma string representando o valor desta instância</returns> public override string ToString() { return _cpf; } /// <summary> /// Inicializa uma nova instância da estrutura Cpf a partir de uma string /// </summary> /// <param name="valor">Uma string contendo um número válido para CPF</param> /// <returns>Uma nova instância da estrutura Cpf</returns> /// <remarks> /// valor deve conter um número com no mínimo 11 dígitos. Se valor contiver mais que nove dígitos, /// serão utilizados somente os nove primeiros dígitos. /// <para> /// Se valor contiver um número de CPF formatado (i.e. 234.567.456-99), os caracteres de formatação /// serão descartados. Somente os caracteres numéricos serão mantidos. /// </para> /// </remarks> /// <exception cref="System.InvalidCastException"> /// Se valor contiver menos que nove caracteres numéricos ou se algum dos caracteres, com exceção dos /// caracteres separadores (existentes em suas devidas posições), não for um número válido /// </exception> /// <example> /// <code>Cpf cpf = "385.456.432.67"; // Ok</code> /// <code>Cpf cpf = "38545643267"; // Ok</code> /// <code>Cpf cpf = "234$564.567*77; // Ok</code> /// <code>Cpf cpf = "324a456a234b55; // erro</code> /// <code>Cpf cpf = "123.a45.456-99 // erro</code> /// </example> public static implicit operator Cpf(string valor) { string padrao = @"^(\d{3})\W?(\d{3})\W?(\d{3})\W?(\d{2})"; Regex r = new Regex(padrao); Match m = r.Match(valor); if (!m.Success) throw new InvalidCastException("valor não é um número de CPF válido"); return new Cpf(m.Groups[1].Value + m.Groups[2].Value + m.Groups[3].Value + m.Groups[4].Value); } /// <summary> /// Retorna o valor de cpf convertido para string /// </summary> /// <param name="cpf">CPF a ser representado em string</param> /// <returns></returns> public static implicit operator string(Cpf cpf) { return _cpf; } /// <summary> /// Cria uma nova instância de Cpf com o mesmo valor de cpf /// </summary> /// <param name="cpf">O CPF a ser copiado</param> /// <returns>Um novo CPF com o mesmo valor de cpf</returns> public static Cpf Copy(Cpf cpf) { int tamanho = cpf.ToString().Length; if (tamanho == 0) throw new ArgumentNullException("cpf"); return new Cpf(cpf.ToString()); } #region ICloneable Members /// <summary> /// Retorna uma referência desta instância de Cpf /// </summary> /// <returns>Esta instância de Cpf</returns> /// <remarks> /// O valor retornado não é uma cópia independente desta instância. É simplesmente uma outra visão /// do mesmo dado. Utilize o método Copy para criar um objeto Cpf separado, com o mesmo /// valor desta instância. /// </remarks> public object Clone() { return this; } #endregion }}Um exemplo da utilização desta estrutura seria, em C#: private void Button1_Click(object sender, System.EventArgs e) { PLibrary.Cpf cpf = this.TextBox1.Text; if (!cpf.IsValid()) { this.Label2.Text = string.Format("CPF Inválido<br>Propriedades do CPF:<br>" + "Raiz: {0}<br>Dígitos: {1}<br>" + "CPF sem formatação: {2}<br>" + "CPF com formatação padrão: {3}<br>" + "CPF com formatação xxx-xxx-xxx/xx: {4}<br>", cpf.Raiz, cpf.Digitos, cpf, cpf.Format(), cpf.Format(Convert.ToChar("-"), Convert.ToChar("/"))); this.Button2.Visible = true; } else { this.Label2.Text = string.Format("CPF Válido<br>Propriedades do CPF:<br>" + "Raiz: {0}<br>Dígitos: {1}<br>" + "CPF sem formatação: {2}<br>" + "CPF com formatação padrão: {3}<br>" + "CPF com formatação xxx-xxx-xxx/xx: {4}<br>", cpf.Raiz, cpf.Digitos, cpf, cpf.Format(), cpf.Format(Convert.ToChar("-"), Convert.ToChar("/"))); this.Button2.Visible = false; } }Como vocês podem ver, este é o código de resposta ao evento click do botão Button1 de um formulário. Ele pega o texto digitado dentro do textbox TextBox1, converte-o para a variável cpf, do tipo CPF e testa a sua validade através do método IsValid(). O resto do código serve simplesmente para ilustrar as demais propriedades e métodos da estrutura. Existe ainda o método Fix(), que corrige um cpf invélido. Ainda falta, nesta estrutura a sobrescrição dos operadores de igualdade e diferença; permitindo, assim, comparar dois cpfs, da seguinte maneira: if (cpf1 == cpf2){ ...}ou if (cpf1 == '345.567.765-99'){ ...}Mas isso deixo de exercício para vocês http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif Abaixo está um exemplo de utilização da estrutura em VB: Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim cpf As PLibrary.Cpf cpf = PLibrary.Cpf.Parse(Me.TextBox1.Text) If (Not cpf.IsValid()) Then Me.Label2.Text = String.Format("CPF Inválido<br>Propriedades do CPF:<br>" & _ "Raiz: {0}<br>Dígitos: {1}<br>" & _ "CPF sem formatação: {2}<br>" & _ "CPF com formatação padrão: {3}<br>" & _ "CPF com formatação xxx-xxx-xxx/xx: {4}<br>", _ cpf.Raiz, cpf.Digitos, cpf, cpf.Format(), _ cpf.Format(Convert.ToChar("-"), Convert.ToChar("/"))) Me.Button2.Visible = True Else Me.Label2.Text = String.Format("CPF Válido<br>Propriedades do CPF:<br>" & _ "Raiz: {0}<br>Dígitos: {1}<br>" & _ "CPF sem formatação: {2}<br>" & _ "CPF com formatação padrão: {3}<br>" & _ "CPF com formatação xxx-xxx-xxx/xx: {4}<br>", _ cpf.Raiz, cpf.Digitos, cpf, cpf.Format(), _ cpf.Format(Convert.ToChar("-"), Convert.ToChar("/"))) Me.Button2.Visible = False End If End SubUm forte abraço a todos, Nâmio Evangelista Cavalcante Compartilhar este post Link para o post Compartilhar em outros sites
rOcKLoCo 0 Denunciar post Postado Agosto 1, 2005 muito bacana Nâmio... Parabéns...depois irei estudar esse código... B) Att,Carlos Compartilhar este post Link para o post Compartilhar em outros sites
namio 0 Denunciar post Postado Agosto 1, 2005 Beleza, Carlos.Qualquer dúvida sinta-se a vontade para perguntar.estou implementando a dll, incluindo uma Interface para o desenvolvimento de estruturas para cálculo de dígitos e mais outras estruturas:Uma para cálculo do CNPJ e outra para cálculo da Inscrição Estadual.Se você tiver alguma sugestão para incluir na dll, me comunica.Depois posso passar os fontes para você ou, se desejar, a dll já compilada.Um forte abraço,Nâmio Evangelista Cavalcante. Compartilhar este post Link para o post Compartilhar em outros sites