Você está na página 1de 20

ELE038: Projeto Assistido por Computador

Primeiro trabalho

Esdras Vitor Silva Pinto


Professor: Renato Cardoso Mesquita
15-10-2015

I. Introduo
Neste primeiro trabalho prtico implementado uma interface grfica para uma aplicao que
cria chaves de segurana para um arquivo utilizando os algoritmos MD5 ou SHA1. O desenvolvimento da
interface grfica desenvolvido na plataforma Qt Creator. Para a gerao das chaves de segurana
mencionadas anteriormente, utiliza-se a aplicao File Checsum Integrity Verification (FCIV), a qual
disponvel gratuitamente no site da Microsoft.
II. Classes customizadas utilizadas na interface grfica
A.

Requisito de projeto

No paradigma da programao orientada a objetos, as classes desempenham um papel central no


desenvolvimento de uma aplicao, j que elas renem caractersticas e comportamentos de objetos reais
e abstratos que nos rodeiam. Desta forma, natural pensar que cada tela de uma interface pode ser
representada por uma classe, j que cada uma delas apresentar o seu prprio comportamento e
caractersticas. Para o projeto das telas da interface grfica, foram levadas em considerao os seguintes
requisitos de projeto:
- A interface grfica deve permitir ao usurio as seguintes funcionalidades:
- Criar chaves de segurana para um dado arquivo usando o algoritmo MD5 ou SHA1.
- Verifica a integridade de um arquivo por meio de comparao de chaves.
- Visualizar uma lista de log contendo o nome e as chaves dos arquivos que foram criados
utilizando a interface grfica. Adicionalmente, a lista de log deve tambm registrar a data
e a hora que a chave foi gerada.
Nas sees seguintes ser analisado o projeto das classes desenvolvidas para a interface grfica.
B.

Classes desenvolvidas para a interface grfica

A interface grfica consiste em cinco telas: Menu Principal, Menu Criar Chave Segurana, Menu Log,
Menu Verificar Integridade Arquivo, e Menu de Configuraes. Cada uma dessas telas est associada a
uma classe customizada, isto . classes que foram desenvolvidas especificamente para a aplicao da
interface grfica.
Essas classes customizadas so analisadas a seguir.
B.1.

Classe MenuPrincipal
A classe MenuPrincipal contm todos o widgets que formam a tela mostrada a seguir.

Figure 1: Tela do menu principal

A tela mostrada anteriormente a tela principal do programa, e ela contm as opes para todos
os recursos discutidos na seo II-A. A definio desta classe mostrada abaixo.
// Definio da classe do menu principal.
class MenuPrincipal : public QWidget
{
public:
// Widgets do menu principal.
...
// Instala os filtros de eventos do menu principal.
void instalarFiltrosDeEventos(QWidget *parent);

// Verifica se um dado objeto um CommandLinkButton membro do menu


principal.
// Retorna true se verdadeiro e false caso contrrio.
bool isMenuCommandLinkButton(QObject *obj);

};
Os mtodos desta classe so discutidos na seo IV (Viso geral do funcionamento do programa).
B.2.

Classe MenuCriarChaveSeguranca
A classe MenuCriarChaveSeguranca contm todos o widgets que formam a tela mostrada a

seguir. Essa tela permite ao usurio escolher um arquivo para a gerao da chave de segurana bem com a
escolha do algoritmo que ser utilizada na criao de tal chave.

Figure 2: Tela do menu criar chave de segurana

A definio desta classe mostrada abaixo.


// Definio da classe do menu Criar Chave de Segurana.
class MenuCriarChaveSeguranca : public QWidget
{
public:
// Widgets do menu criar chave de segurana.
...

// Contrutor da classe
MenuCriarChaveSeguranca(QWidget *parent = 0);
// Instala os filtros de eventos do menu criar chave de segurana.
void instalarFiltrosDeEventos(QWidget *parent);
// Verifica se um dado objeto um CommandLinkButton membro do menu
principal.
// Retorna true se verdadeiro e false caso contrrio.
bool isMenuCommandLinkButton(QObject *obj);
// Atualizar nome e directorio do arquivo
void atualizarArquivoInfo(QString arquivo);
};

O objetivo de cada mtodo presente nesta classe discutido na seo IV (Viso geral do
funcionamento do programa). Como pode ser visto na figura abaixo, a tela do menu de verificao de
chave de segurana muito semelhante tela de criao de chave. Sendo assim, esta tela pode ser
considerada como pertencente da classe MenuCriarChaveSegurana.

Figure 3: Tela do menu verificar integridade de arquivo

A aplicao da interface conta tambm com uma tela de configuraes, conforme mostrada
abaixo.

Figure 4: Tela do menu de configuraes.

Esta tela permite ao usurio informar interface grfica o diretrio da aplicao fciv.exe. Como a
gerao de chaves de segurana so feitas por esta aplicao, a interface grfica s conseguir operar
corretamente se o diretrio do arquivo fciv.exe for informado corretamente. Para isto, a tela de
configurao conta com um dialogo de arquivo que permite ao usurio indicar o diretrio da aplicao
fciv.exe.
Adicionalmente, a tela de configuraes pode tambm ser considerada como pertencente da
classe MnuCriarChaveSegurana, ja que ela guarda traos da tela de criao de chave de segurana, como
a seleo de arquivos e o boto de retornar ao menu principal.
B.4.

Classe FcivInterfaceGrafica
A classe FcivInterfaceGrafica est no topo da hierarquia dentre as classes mencionadas

anteriormente. Essa classe tem a funo de gerenciar a mudana de telas da interface bem como realizar a
comunio com a aplicao FCVI. A definio desta classe mostrada a seguir.
class FcivInterfaceGrafica : public QDialog
{
Q_OBJECT
public:

FcivInterfaceGrafica();
public slots:
// Realiza a leitura dos dados fornecidos pelo processo FCIV.
void readProcessData();
private:
// Filtro de eventos da interface.
bool FcivInterfaceGrafica::eventFilter(QObject *obj, QEvent *event);
// Verifica se o mouse esta dentro de um Widget.
bool isMouseDentroDoWidgest(QWidget *w, QMouseEvent *mouseEvent);
// Processa os eventos relacionados com o menu principal.
bool menuPrincipalProcessarEventos(QObject *obj, QEvent *event);
// Processa os eventos relacionados com o menu criar chave de segurana.
bool menuCriarChaveSegProcessarEventos(QObject *obj, QEvent *event);
// Processa os eventos relacionados com o menu log.
bool menuLogProcessarEventos(QObject *obj, QEvent *event);
// Processa os eventos relacionados com o menu Verificar Chave.
bool FcivInterfaceGrafica::menuVerificarChaveProcessarEventos(QObject
*obj, QEvent *event);
// Referncias para os menus.
MenuCriarChaveSeguranca *menuCriarChave;
MenuPrincipal *menuPrincipal;
MenuLog *menuLog;
MenuCriarChaveSeguranca *menuVerificarChave;
MenuCriarChaveSeguranca *menuConfig;
// Referncia para a lista dos menus
QStackedWidget *menus;
// Diretorio do processo responsvel pela implementao dos algoritmos
MD5 e ASH1
QString FCIVprocessDiretorio;
// Processo responsvel pela implementao dos algoritmos MD5 e ASH1
QProcess *processFCIV;
};

Os mtodos pertencentes a esta classe so analisadas na seo IV (Viso geral do funcionamento


do programa).
IV. Viso geral do funcionamento do programa
Nesta seo apresentada uma viso geral do programa, isto , os pontos mais importantes da
lgica da implementao da interface grfica so discutidos.

A.

Gerenciamento das telas de interface


Conforme discutido anteriormente, algumas classes foram criadas para representar as telas da

interface. Portanto, necessrio instanciar um objeto para cada uma dessas telas. Alm disso, como esses
objetos possuem diferentes telas, precisamos de um mecanismo que nos permita alterar uma tela para
outra. A opo adotada neste trabalho foi a de utilizar a classe QStackedWidget, j que ela nos permite
criar uma fila de telas sendo que apenas uma ficar ativa por vez. O fragmento de cdigo abaixo mostra o
construtor da classe FcivInterfaceGrafica, onde as telas de menus so criadas e algumas inicializaes
adicionais so feitas.
// Construtor da interface grfica do FCIV
FcivInterfaceGrafica::FcivInterfaceGrafica()
{
// Cria instncias para menus.
menuPrincipal = new MenuPrincipal;
menuCriarChave = new MenuCriarChaveSeguranca;
menuLog = new MenuLog;
menuVerificarChave = new MenuCriarChaveSeguranca;
menuConfig = new MenuCriarChaveSeguranca;
// Ativa o eventFilter para os menus
menuPrincipal->instalarFiltrosDeEventos(this);
menuCriarChave->instalarFiltrosDeEventos(this);
menuLog->instalarFiltrosDeEventos(this);
menuVerificarChave->instalarFiltrosDeEventos(this);
menuConfig->instalarFiltrosDeEventos(this);
// Instancia uma lista para armazenar os menus
menus = new QStackedWidget;
// Adiciona os menus na lista de menus
menus->addWidget(menuPrincipal);
menus->addWidget(menuCriarChave);
menus->addWidget(menuLog);
menus->addWidget(menuVerificarChave);
menus->addWidget(menuConfig);
// Instancia um layout do tipo grid para colocar os
// menus.
QGridLayout *gridLayout = new QGridLayout;
// Adiciona a fila de menus ao grid
gridLayout->addWidget(menus,0,0,1,1);
// Instancia o layout da janela principal
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addLayout(gridLayout);
mainLayout->setSpacing(6);

// Seta Layout da janela principal


setLayout(mainLayout);
// Conecta os slots dos objetos dos menus ao padro do QT.
QMetaObject::connectSlotsByName(this);
// Instancia e inicia o diretorio do processo responsvel pela
implementao dos algoritmos MD5 e ASH1
processFCIV = new QProcess(this);
FCIVprocessDiretorio = "./fciv.exe";

}
B.

Gerenciamento dos botes da interface


Cada tela possui seus botes particulares, e cada boto executar uma funo distinta. Para

permitir que possamos tratar os casos em que um dos botes da interface pressionado, ativamos o filtro
de eventos para todos os botes das telas de interface. A ativao do filtro de eventos permite que o
programa seja direcionado para um mtodo de tratamento desses eventos. Especificamente, qualquer
evento relacionado com os botes so direcionados para o mtodo FcivInterfaceGrafica::eventFilter(...).
Uma vez que os eventos relacionados com todas as telas so direcionados para o mesmo lugar, feito o
tratamento especfico para cada tela. O cdigo a seguir mostra a implementao do mtodo
FcivInterfaceGrafica::eventFilter(...).
// Filtro de eventos dos menus.
bool FcivInterfaceGrafica::eventFilter(QObject *obj, QEvent *event)
{
// Processa os eventos associados com os menus
if(menus->currentWidget() == menuPrincipal)
FcivInterfaceGrafica::menuPrincipalProcessarEventos(obj,event);
if(menus->currentWidget() == menuCriarChave)
FcivInterfaceGrafica::menuCriarChaveSegProcessarEventos(obj,event);
if(menus->currentWidget() == menuLog)
FcivInterfaceGrafica::menuLogProcessarEventos(obj,event);
if(menus->currentWidget() == menuVerificarChave)
FcivInterfaceGrafica::menuVerificarChaveProcessarEventos(obj,event);
if(menus->currentWidget() == menuConfig)
FcivInterfaceGrafica::menuConfiguracoesProcessarEventos(obj,event);
return QWidget::eventFilter(obj,event);

}
C.

Gerenciamento do Menu Principal

O gerenciamento do menu principal feito pelo mtodo FcivInterfaceGrafica


::menuPrincipalProcessarEventos(...). Quando o usurio clica no boto Criar Chave de Segurana, um
evento de clique do boto disparado, e, aps o tratamento deste evento, o programa ir mudar a tela do
aplicativo para a tela de criao de chave de segurana. O fragmento de cdigo a seguir executado
quando este boto clicado.
// Ativa a tela de criao de chave de segurana;
menus->setCurrentWidget(menuCriarChave);
// Inicializa o status dos widgets presentes no menu
menuCriarChave->gerarChaveDeSegurancaButton->setEnabled(false);
menuCriarChave->salvarChaveTxtButton->setVisible(false);
menuCriarChave->atualizarArquivoInfo("");
menuCriarChave->md5RadioButton->setChecked(true);
menuCriarChave->chaveLineEdit->clear();
menuCriarChave->arquivoChaveSeg.clear();

A implementao dos demais botes segue a mesma filosofia, onde a diferena se encontra na tela
que ser ativada bem como algumas inicializaes de rotina.
D.

Gerenciamento do Menu Criar Chave De Segurana


Todos os eventos relacionados com os botes so tratados pelo mtodo FcivInterfaceGrafica::

menuCriarChaveSegProcessarEventos(...). Quando o boto "Selecionar arquivo" pressionado, um


dilogo de arquivo aberto para permitir que o usurio escolha o arquivo no qual ser gerado a chave de
segurana. O cdigo que executa esta funo mostrado a seguir.
// Abre a tela de dialogo para a seleo do arquivo.
QString arquivoDiretorio;
arquivoDiretorio =
QFileDialog::getOpenFileName(0,QString(),QString(),0,0);
// Se um arquivo foi selecionado...
if(arquivoDiretorio != NULL)
{
// Atualiza o nome do arquivo e seu respectivo diretorio no menu
menuCriarChave->atualizarArquivoInfo(arquivoDiretorio);
// Habilita o botao de gerar chave de segurana.
menuCriarChave->gerarChaveDeSegurancaButton->setEnabled(true);

// Limpa a chave de segurana.


//menuCriarChave->arquivoChaveSeg.clear();
menuCriarChave->arquivoChaveSeg = "";
menuCriarChave->chaveLineEdit->clear();
menuCriarChave->chaveLineEdit->setEnabled(false);
}
else
{
// Mantm o ultimo arquivo selecionado.

}
Aps o usurio escolher o arquivo, ele tambm tem a opo de escolher o algoritmo de gerao da
chave de segurana. Aps a escolha do algoritmo, o usurio poder gerar a chave de segurana para o
arquivo selecionado clicando no boto "Gerar Chave de Segurana". Quando este boto clicado, a
interface grfica chama a aplicao FCIV para a gerao da chave de segurana. Para permitir a
comunio entre a interface grfica e a aplicao FCIV, utiliza-se a classe QProcess. O fragmento de
cdigo a seguir usado para inicializar um objeto da classe Qprocess, construir os argumentos da
aplicao FCIV e por fim executar esta aplicao com os argumentos fornecidos.
// Seleciona o canal de saida de dados padro do aplicativo
processFCIV->setReadChannel(QProcess::StandardOutput);
// Sempre que o canal de sada de dados padro do processo FCIV estiver
pronto para
// leitura, ser chamada um mtodo para ler esses dados.
connect(processFCIV,SIGNAL(readyReadStandardOutput()),this,SLOT(readProcessDa
ta()));
// Adiciona lista de argumentos o diretrio do arquivo que se deseja obter
a chave de segurana.
QStringList argumentos;
argumentos << menuCriarChave->arquivoDiretorio;
// Adiciona o algoritimo de gerao da chave de segurana lista de
argumentos.
if(menuCriarChave->md5RadioButton->isChecked())
{
argumentos << "-md5";
}
else
{
argumentos << "-sha1";
}
// Executa o processo FCIV para obter a chave de segurana para o arquivo.
processFCIV->start(FCIVprocessDiretorio,argumentos);

menuCriarChave->chaveLineEdit->setText("Erro ao executar fciv.exe. V em


configuraes");.

Uma vez que a aplicao FCIV concluda, um sinal emitido e coletado pelo slot
FcivInterfaceGrafica::readProcessData(). Internamente desse slot, feito todo processamento para se
obter a chave de segurana do arquivo. A implementao deste slot mostrado a seguir.
// Realiza a leitura dos dados fornecidos pelo processo FCIV.
void FcivInterfaceGrafica::readProcessData()
{
QString s;
s = processFCIV->readAllStandardOutput();
// Separa o diretorio em sub-diretorios individuais
QRegExp rx(" |\r\n");
QStringList strings = s.split(rx);
// Processa a string recebida e exibe a chave de segurana.
if(strings.count() > 10)
{
if(strings.at(9) != "")
{
QString chaveSeg = strings.at(9);
if(chaveSeg.count() == 32 || chaveSeg.count() == 40)
{
if(menus->currentWidget() == menuCriarChave)
{
if(chaveSeg.count() != menuCriarChave>arquivoChaveSeg.count())
{
// Atualiza a chave do objeto.
menuCriarChave->arquivoChaveSeg = chaveSeg;
// Exibe a chave para o usurio.
menuCriarChave->chaveLineEdit->setText(chaveSeg);
menuCriarChave->chaveLineEdit->setEnabled(true);
QDate date = QDate::currentDate();
QTime time = QTime::currentTime();
QFile file("log.txt");
if (!file.open(QIODevice::ReadWrite |
QIODevice::Text))
return;
QTextStream out(&file);
QString logAnterior = out.readAll();
out.seek(0);
out << "'" << menuCriarChave->arquivoNome << "'" <<
menuCriarChave->arquivoDiretorio <<"'" << menuCriarChave->arquivoChaveSeg <<

"'" << date.toString("dd.MM.yyyy") << "'"<< time.toString("hh:mm:ss") <<


logAnterior;
file.close();
}
}
// Verificao de integridade de um arquivo.
else if(menus->currentWidget() == menuVerificarChave)
{
// Verifica se a chave gerada para o arquivo coincide com
a chave
// fornecida pelo usurio.
if(chaveSeg == chaveVerificacao)
{
menuVerificarChave->gerarChaveDeSegurancaButton>setStyleSheet("background-color: green; color: white;");
menuVerificarChave->gerarChaveDeSegurancaButton>setText("Chaves iguais!");
qDebug() << "Chaves iguais";
}
else
{
menuVerificarChave->gerarChaveDeSegurancaButton>setStyleSheet("background-color: red; color: white;");
menuVerificarChave->gerarChaveDeSegurancaButton>setText("Chaves diferentes!");
qDebug() << "Chaves diferentes";
}
menuVerificarChave->chaveLineEdit>setText(chaveVerificacao);
}
}
else
{
if(menus->currentWidget() == menuVerificarChave)
{
menuVerificarChave->chaveLineEdit->setText("Erro ao
executar fciv.exe. V em configuraes");
}
}
}
}
strings.clear();
}

Como pode ser visto no cdigo acima, toda vez que gerado uma chave para um arquivo,
salvamos esta chave juntamente com outras informaes adicionais como nome do arquivo, diretrio, e
dentre outros, em um arquivo de texto. Desta forma, o usurio poder consultar todos os arquivos e suas
respectivas chaves que foram geradas anteriormente.

Finalmente, caso o usurio deseja voltar pra a tela principal, basta um clique no boto "Voltar
Menu principal".
E.

Gerenciamento do Menu Verificar Integridade de um arquivo


As funcionalidades deste menu so muito semelhantes s funcionalidades do menu Criar Chave

de Segurana. A diferena neste caso que, ao invs de gerar a chave para um arquivo e salvar no arquivo
de log, a chave gerada comparada com uma chave fornecida pelo usurio.
F.

Gerenciamento do Menu Visualizar Log


O menu de Visualizar Log, permite ao usurio consultar todos os arquivos e suas chaves

correspondentes que foram geradas anteriormente. Assim que o usurio clica no boto "Visualizar Log"
no menu principal, a tela da interface direcionada para a tela de log. Alem disto, lemos do arquivo de
log e exibimos estas informaes para o usurio. Estas tarefas so executadas pelo seguinte fragmento de
cdigo:
// Muda para a tela de log.
menus->setCurrentWidget(menuLog);
// Carrega o arquivo de log
QFile file("log.txt");
if (!file.open(QIODevice::ReadOnly| QIODevice::Text))
return false;
QTextStream out(&file);
QString log = out.readAll();
out.seek(0);
// Calcula o numero de logs presentes no arquivo.
QRegExp rx("'");
QStringList logStrings = log.split(rx);
// Monta a string de logs para ser exibida.
QString logDisplay;
logStrings.pop_front();
while(!logStrings.isEmpty())
{
logDisplay += "*** Arquivo: " + logStrings.takeFirst() + "
*** " +"\r\n\n";
logDisplay += "-Diretorio: \n" + logStrings.takeFirst() +
"\r\n\n";

logDisplay += "-Chave Segurana: \n" +


logStrings.takeFirst() + "\r\n\n";
logDisplay += "-Data: \n" + logStrings.takeFirst() +
"\r\n\n";
logDisplay += "-Hora: \n" + logStrings.takeFirst() +
"\r\n\n";
logDisplay += "*****************************************
\r\n\n";
}
// Exibe a lista de logs
menuLog->logMenuTextBrowser->setText(logDisplay);
qDebug() << "numStrings: " << logStrings.count() << endl;
// out.seek(0);
// out << logAnterior <<" " <<menuCriarChave->arquivoNome << " "
<< menuCriarChave->arquivoChaveSeg << " " << date.toString("dd.MM.yyyy") << "
"<< time.toString("hh:mm:ss") << "\r\n";
file.close();

V. Resultados: Demonstrao de funcionamento da interface grfica.


Primeiramente, importante informar interface grfica o diretrio da aplicao fciv.exe. Para
isto, o usurio pode utilizar o menu de configuraes, conforme mostrado abaixo.

Suponhamos que desejamos criar uma chave de segurana para um arquivo chamado myTest.txt,
cujo contedo PAC-UFMG-2015-2. Inicialmente, devemos entrar no menu de criao de chave de
segurana. Uma vez neste menu, selecionamos o arquivo desejado, conforme ilustrado a seguir.

Aps a escolha do arquivo, o usurio dever selecionar o algoritmo para a gerao da chave de
segurana. Uma vez escolhido o algoritmo, a chave de segurana gerada ao clicar no boto "Gerar chave
de segurana". Logo depois, a interface grfica mostra o valor da chave. Essa etapa mostrada nas figuras
abaixo.

Se, por exemplo, o usurio no tivesse informado o diretrio da aplicao fciv.exe, a interface
grfica iria procurar por esta aplicao no diretrio "c:/". Caso esta aplicao no esteja neste diretrio,
uma mensagem de erro seria exiba no lugar da chave, como ilustrado a seguir.

Para solucionar tal erro, basta informar o diretrio da aplicao fciv.exe no menu de
configuraes, conforme mostrado abaixo.

A interface grfica tambm disponibiliza o recurso de visualizao de log, que pode ser acessado
clicando-se no boto "Visualizar Log" no menu principal. Neste exemplo, ao clicar neste boto, aparecer

o log do arquivo myTest.txt utilizado anteriormente para a gerao da chave de segurana, como indicado
abaixo.

Finalmente, a interface grfica tambm conta com um recurso para comparao de chaves, isto ,
verificao da chave gerada para um arquivo contra uma chave fornecida pelo usurio. No menu de
verificao de chaves, o usurio pode escolher o arquivo que se deseja verificar bem como fornecer a
chave de comparao. Vamos escolher o arquivo myTest.txt e fornecer a chave de segurana gerada para
este arquivo anteriormente, conforme ilustrado a seguir.

A barra de status da verificao que se encontra na parte superior chave de segurana, indica
inicialmente que a verificao no foi iniciada. Ao clicar no boto "Verificar Integridade", o status da
verificao muda para chaves iguais, indicando que a chave fornecida coincide com a chave gerada para o
arquivo, conforme pode ser visto na figura abaixo.

Se modificarmos o arquivo myTest.txt para PAC-UFMG e repetirmos o procedimento acima


mantendo a chave antiga que geramos para myTest.txt, a verificao detectar que as chaves so
diferentes, e informar ao usurio que a chave fornecida pelo usurio no coincide com a chave gerada
para o arquivo. Esta situao ilustrada abaixo.

VI. Concluso
Neste trabalho prtico, desenvolveu-se uma interface grfica para uma aplicao que gera chaves
de segurana por meio dos algoritmos MD5 e SHA1. A interface grfica possuem todos os recursos que
foram levantados no inicio do projeto. Embora haja muitas melhorias que podem serem feitas no cdigo,
a interface grfica desenvolvida bem intuitiva e consideravelmente robusta, o que contribui para uma
boa experincia do usurio da interface.
Referncias
[1] Documentao das classes do Qt: doc.qt.io/qt-5/

[2] Duvidas e sugestes sobre Qt: http://stackoverflow.com/questions/

Você também pode gostar