• Nenhum resultado encontrado

Teoria dos Números – Aplicações Práticas na Computação

N/A
N/A
Protected

Academic year: 2019

Share "Teoria dos Números – Aplicações Práticas na Computação"

Copied!
8
0
0

Texto

(1)

Teoria dos Números – Aplicações Práticas na

Computação

Aqui apresentamos algumas aplicações da Teoria dos Números na Computação. Para saber mais detalhes, recomendamos a leitura das páginas 205 a 208 e de 241 a 244 do livro de K. Rosen e as páginas 424 a 440 do livro de E. R. Scheinerman (2a edição).

1. Criptografia

• Esta é a aplicação mais importante, provavelmente. A criptografia métodos para “esconder” (encriptar ou cifrar) o conteúdo de mensagens transmitidas pela internet. A aritmética modular e os números primos estão envolvidos em vários destes

métodos. Veremos dois.

• Em todos os métodos, assumiremos que cada símbolo (letras, pontuação, etc.) da mensagem tem um número natural que o representa. Por exemplo, se as mensagens usarem apenas as 11 letras de A a K, podemos adotar esta representação:

A B C D E F G H I J K

0 1 2 3 4 5 6 7 8 9 10

De fato, o computador representa textos simples (planos) usando uma representação numérica chamada de ASCII ou a representação UNICODE. (Clique nos links para mais detalhes).

1.1 Código de César

(2)

• A figura abaixo ilustra o processo para o nosso alfabeto completo (de A a Z):

• Por exemplo, podemos codificar mensagens do alfabeto de 11 letras (de A a K) definido antes usando um deslocamento de k=3 letras. Assim, cada letra x será codificada com a seguinte função:

C(x) = (x + 3) mod 11

Dessa forma, a letra A (representação: 0) será encriptada como um D (representação: 3) e a letra K (representação: 10) será encriptada como um C (representação: 2).

• Para decriptar um caractere y é muito simples, basta usar a função:

D(y) = (y - 3) mod 11

Assim, a letra D (representação: 3) torna-se novamente um A (representação: 0) e a letra C (representação: 2) volta a ser um K (representação: 10, pois (2-3) mod 11 = -1 mod 11 = 10).

• Os problemas com o código de César são:

(3)

o O código é fácil de quebrar (exemplo: para um hacker), pois é fácil descobrir o k que foi usado. É possível criar um programa que testa todas as possibilidades, por exemplo.

• Diferente do método de César, nos métodos ditos de criptografia de chave pública:

o Todo mundo pode saber a função de encriptação. Tal função é chamada de chave pública.

o Mas a função de decriptação é uma chave privada que só um dos lados deve conhecer. Idealmente, ela deve ser difícil de ser descoberta, mesmo conhecendo-se a chave pública.

• Um método de chave pública serve, por exemplo, para uma aplicação de banco pela internet ou qualquer outra que exija comunicação segura.

o O banco divulga a chave pública para o seu navegador, que ele usa para encriptar a sua senha (ou outra mensagem que você tenha enviado).

o A sua senha é enviada criptografada pela internet e, assim, se um hacker “escutar” os dados que você transmitiu, não vai descobrir sua senha.

o No servidor do banco, a senha (ou outra mensagem que você envie) é decriptada pela chave secreta que só o banco conhece.

• Veremos a seguir um método de criptografia de chave pública.

1.2 Cripto-Sistema de Rabin

• Criado por Michael Rabin, um ganhador do prêmio Turing (o “Nobel” da

(4)

• Vamos dar um exemplo adequado ao alfabeto de 11 letras definido antes. Não podemos fazer o resto da divisão por 11, porque 11 não é o produto de dois primos. Usando o valor 21 (que é 3 × 7), a codificação é feita assim:

C(x) = x2 mod 21

Assim, teremos:

o a letra A (representação: 0) é encriptada como o código 0 o a letra C (representação: 2) é encriptada como o código 4 o a letra K (representação: 10) é encriptada como o código 16

• Os dois números primos em questão (3 e 7, no exemplo) formam a chave privada. Conhecendo os dois, é possível decriptar rapidamente a mensagem.

o Não vamos ver como é feita a decriptação, porque usa várias técnicas de aritmética modular. Veja o livro de Scheinerman.

• Porém, se você não conhece os dois números primos usados e se os dois números primos forem “gigantes”, com centenas de algarismos cada, então o processo de decriptação será imensamente difícil.

o Será preciso fatorar o número (21, no exemplo) para obter os dois números primos que o compõem.

o Porém, fatoração é um problema para o qual ainda não existem algoritmos muito eficientes.

o Se o número for grande (o que não é o caso do exemplo acima), um hacker poderia levar milhões de anos tentando fatorá-lo!

(5)

• Um método mais preciso e que é bastante usado na prática é o método RSA. Se tiver

interesse, leia sobre ele no livro do Rosen ou do Scheinerman.

2. Geradores de Números Aleatórios

• Em algumas aplicações, é desejável que o programa se comporte de maneira aparentemente aleatória (ao acaso), apresentando alguma variação limitada nas suas saídas. Alguns exemplos:

o Em jogos (games) de futebol: o passe ou o chute nem sempre saem

perfeitos. A direção da bola pode variar (pouco ou muito, dependendo do jogador).

o Em simulações de trânsito: o percurso, a velocidade ou a velocidade de

reação dos carros devem variar entre si e devem variar um pouco a cada simulação.

o Em simulações em geral: tipicamente, deseja-se introduzir variações que

tornem a simulação mais realista.

o Em testes de software: para criar entradas diversificadas para testar se um

programa está funcionando corretamente.

• Esse tipo de variação pode ser obtido usando os chamados geradores de números pseudo-aleatórios. Eles geram uma sequência de números (um por vez, geralmente)

usando um método exato, mas é difícil prever os valores futuros da sequência (exceto para quem sabe o método).

• Um tipo de gerador de números aleatórios simples e muito usado é o gerador congruente linear, que pode ser criado assim:

o Primeiro escolha um valor semente (seed), para dar início à seqüência.

Exemplo:

(6)

o Para gerar o próximo valor (rn), multiplique o valor anterior (rn-1) por um valor inteiro a, some um valor c e tire o resto da divisão por m. Usando a=7, c=3, m=31, teríamos:

rn = (7.rn-1 + 3) mod 31

o A seqüência produzida seria:

2, 17, 29, 20, 19, 12, 25, 23, 9, 4, 0, 3, 24, 16, 22, 2, 17, 29, ...

• A sequência gerada é infinita, mas é cíclica. Os valores estão todos no intervalo de 0 a m-1. No máximo, este gerador gera exatamente os m valores distintos do intervalo citado, mas pode acontecer de nem todos os valores deste intervalo serem gerados.

o Para aumentar a quantidade de valores distintos gerados, o m deve ter um valor grande (232, por exemplo). Mas para gerar todos os m valores possíveis, é preciso obedecer mais alguns critérios na escolha dos valores de a, c e m. Vejam o Wikipedia para mais detalhes. (Desafio: crie, em Python,

um gerador que gere todos os m valores possíveis, para algum m de sua escolha entre 100 e 1000).

o No exemplo dado antes, os critérios não foram satisfeitos. Por isso, ele só gera 15 valores distintos, de forma cíclica. Veja que os três valores finais da seqüência listada já são a repetição dos três valores do início.

• A vantagem do gerador congruente linear é que ele é simples de implementar e usa um mínimo de memória. Por isso, são bastante usados e já vêm implementados por padrão em várias linguagens de programação.

• Porém, existem outros geradores melhores, que não veremos em detalhes.

3. Funções Hash

(7)

o Em alguns métodos de criptografia o Na compactação de arquivos

o Para implementar conjuntos (como os sets de Python e o HashSet de Java) o Para implementar dicionários (como os de Python e o HashMap de Java) o Etc.

• Vamos falar de funções hash usadas numa aplicação específica:

o Suponha que em uma aplicação, você deseja guardar as fichas de cadastro dos clientes de uma loja. Além disso, as fichas devem ser indexadas por CPF, ou seja, dado um CPF, você deve identificar rapidamente a ficha.

 Apenas para comparar: se você criar uma lista de “fichas de cadastro” de forma ineficiente, você vai ser obrigado a percorrer toda a lista, o que seria ineficiente.

o Suponha que você só quer manter N cadastros de pessoas na memória. O restante ficará guardado em um banco de dados (pode ser em arquivo).

 Por que fazer isso? Porque manter na memória torna o acesso mais rápido. Isso é um tipo de memória cache. Porém, nela, não cabem todas as fichas.

 Assim, quando for dado um CPF que não está na memória, você consulta o banco e põe a ficha na memória. Para isso, talvez você precise descartar (desalocar) outra ficha que estava na memória.

o O problema é: que estrutura usar para manter N pessoas indexadas pelos seus CPFs na memória de forma eficiente?

o Nós vamos usar um simples array de tamanho fixo N, indexado de 0 a N-1.

(8)

Hash(CPF) = CPF mod N

o Assim, você tem, para cada CPF, o índice do array onde a ficha do cliente pode ser guardada!

o Porém, pode haver colisão de hash: quando dois CPFs têm o mesmo valor

hash e, portanto, são associados ao mesmo índice do array.

o Se isso acontecer, uma estratégia que pode ser adotada é: você apaga o cadastro que estava antes naquele índice e guarda somente o novo cadastro. (Lembrando que o cadastro é apagado da memória, mas permanece armazenado no banco de dados).

• Uma idéia bem próxima a essa é usada para implementar tabelas hash, tais como os

dicionários de Python e o HashMap e Hashtable de Java. A diferença é que não há desalocação nestas estruturas.

o Neste caso, e se houver conflito: como resolver? Deixo para vocês pesquisarem!

“Longe de vós, toda amargura, e cólera, e ira,

e gritaria, e blasfêmias, e bem assim toda malícia.

Antes, sede uns para com os outros benignos,

compassivos, perdoando-vos uns aos outros,

Referências

Documentos relacionados

Análise econômica – descrição do modelo Foi construído um modelo de decisão para estimar a expectativa de vida e os custos cumulativos das es- tratégias para fechamento do

Na aplicação das políticas contábeis da Companhia e das controladas, a Administração deve fazer julgamentos e elaborar estimativas a respeito dos valores contábeis

The goal of this study was to obtain the in vitro sensitivity profile of dairy cattle ticks to six commercial acaricides in five small farms in northwestern São Paulo state,

[r]

O valor da reputação dos pseudônimos é igual a 0,8 devido aos fal- sos positivos do mecanismo auxiliar, que acabam por fazer com que a reputação mesmo dos usuários que enviam

O profissional de saúde, em particular o médico, possui a tendência de se deixar dominar pelos aspectos concretos e objetivos da ciência. Resultados obtidos por ensaios clínicos

Buscou-se descrever o perfil socioeconômico da amostra, assim como caracterizar o nível de endividamento dos pesquisados a partir de seus hábitos de consumo, investimento e

17 CORTE IDH. Caso Castañeda Gutman vs.. restrição ao lançamento de uma candidatura a cargo político pode demandar o enfrentamento de temas de ordem histórica, social e política