Achei interessante o algoritmo dos dígitos verificadores do CPF (Cadastro de Pessoa Física) e apresento o código-fonte em C++.
Para gerar o binário é necessário 3 arquivos:
1. Definição da classe
$ cat Cpfnum.h
#ifndef CPFNUM_H
#define CPFNUM_H
class Cpfnum {
public:
Cpfnum();
Cpfnum(const Cpfnum& orig);
virtual ~Cpfnum();
int PrimeiroDigito(int, int, int, int, int ,int ,int, int, int);
int SegundoDigito (int, int, int, int, int ,int ,int, int, int, int);
private:
#endif /* CPFNUM_H */
2. Definições das funções-membros da classe
$ cat Cpfnum.cpp
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
#include <cstring>
using std::string;
#include "Cpfnum.h"
Cpfnum::Cpfnum() {
}
Cpfnum::Cpfnum(const Cpfnum& orig) {
}
Cpfnum::~Cpfnum() {
}
int Cpfnum::PrimeiroDigito(int v1,int v2,int v3,int v4,int v5,int v6,int v7,int v8,int v9)
{
int m1, m2, m3, m4, m5, m6, m7, m8, m9; // multiplicado
int soma, resto, v10;
m1=v1*10;
m2=v2*9;
m3=v3*8;
m4=v4*7;
m5=v5*6;
m6=v6*5;
m7=v7*4;
m8=v8*3;
m9=v9*2;
// somando m1 a m9
soma=m1+m2+m3+m4+m5+m6+m7+m8+m9;
// obtendo o 1° dígito verificador: divisão da soma por 11 e o resto é o 1° dígito verificador
resto=soma%11;
if (resto < 2)
v10=0;
else
v10=11-resto;
return v10;
}
int Cpfnum::SegundoDigito (int v1,int v2,int v3,int v4,int v5,int v6,int v7,int v8,int v9, int v10)
{
int m1, m2, m3, m4, m5, m6, m7, m8, m9, m10; // multiplicado
int soma, resto, v11;
// novos valores multiplicados após encontrar o 1° dígito verificador
m1=v1*11;
m2=v2*10;
m3=v3*9;
m4=v4*8;
m5=v5*7;
m6=v6*6;
m7=v7*5;
m8=v8*4;
m9=v9*3;
m10=v10*2;
// somando m1 a m10
soma=m1+m2+m3+m4+m5+m6+m7+m8+m9+m10;
// divisão da soma por 11. Aplica-se regra do resto para encontrar o 2° dígito verificador
resto=soma%11;
if (resto < 2)
v11=0;
else
v11=11-resto;
return v11;
}
3. Programa driver
$ cat main.cpp
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
#include <cstring>
using std::string;
#include <sstream>
using std::stringstream;
#include <cstdlib>
#include "Cpfnum.h"
//using namespace std;
int main(int argc, char** argv) {
string mystring;
string sv1, sv2, sv3, sv4, sv5, sv6, sv7, sv8, sv9, sv10, sv11; // sv10 = 1° dígito verificador e sv11 = 2° dígito verificador
int v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11; // valor
int pdv, sdv; // primeiro e segundo digito verificador
cout << "Entre com o número do CPF: ";
cin >> mystring;
sv1=mystring[0];
sv2=mystring[1];
sv3=mystring[2];
sv4=mystring[3];
sv5=mystring[4];
sv6=mystring[5];
sv7=mystring[6];
sv8=mystring[7];
sv9=mystring[8];
stringstream(sv1) >> v1;
stringstream(sv2) >> v2;
stringstream(sv3) >> v3;
stringstream(sv4) >> v4;
stringstream(sv5) >> v5;
stringstream(sv6) >> v6;
stringstream(sv7) >> v7;
stringstream(sv8) >> v8;
stringstream(sv9) >> v9;
if (mystring.length() < 9 || mystring.length() == 10 || mystring.length() > 11)
cout << "Você digitou " << mystring.length() << " caracteres. Digite 9 ou 11." << endl;
Cpfnum myCpfnum;
myCpfnum.PrimeiroDigito(v1, v2, v3, v4, v5, v6, v7, v8, v9);
myCpfnum.SegundoDigito(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
if (mystring.length() == 9)
{
v10=myCpfnum.PrimeiroDigito (v1, v2, v3, v4, v5, v6, v7, v8, v9);
v11=myCpfnum.SegundoDigito (v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
cout << v1 << v2 << v3 << v4 << v5 << v6 << v7 << v8 << v9 << "-" << v10 << v11 << endl;
}
if (mystring.length() == 11)
{
pdv=myCpfnum.PrimeiroDigito (v1, v2, v3, v4, v5, v6, v7, v8, v9);
sdv=myCpfnum.SegundoDigito (v1, v2, v3, v4, v5, v6, v7, v8, v9, pdv);
sv10=mystring[9];
sv11=mystring[10];
stringstream(sv10) >> v10;
stringstream(sv11) >> v11;
if ( (v10 == pdv ) && (v11 == sdv ) )
cout << "CPF válido!" << endl;
else
cout << "CPF inválido" << endl;
}
return 0;
}
Considerações finais:
Uma IDE (Integrated Development Environment) faz muita diferença no desenvolvimento. Meus primeiros programas foram elaborados com o Anjuta, mas passei a usar o NetBeans.
O Anjuta cria as classes sem muitas instruções (virtual) o que considero bom para começar o contato com C++. No entanto, nada impede de iniciar com NetBeans e ignorar algumas funções-membros.
As IDEs vem com as configurações que buscam o compilador para gerar o binário. Caso prefira colar os respectivos conteúdo nos três arquivos com os nomes sugeridos, a linha de comando é:
$ g++ Cpfnum.cpp main.cpp -o cpf.out -ansi
E para escrever este texto usei o BlueFish. Claro que não deixei de usar o VIM, principalmente porque um recurso essencial como colar em colunas só encontro nele.
Nenhum comentário:
Postar um comentário