Comparant Python i PHP: Xor encryption
Escrit per Aaloy a 18 de July , 2010 a les 10:26 a.m.
Quan xerram de Python una de les coses en que es fa més èmfasi és la claretat i expressivitat del llenguatge, que ens permet posar les nostres idees en forma de codi de manera ràpida i a més entenedora.
També és important remarcar que Python sovint necessite moltes menys línies de codi per fer el mateix que altres llenguatges, ja no dic un C, C++ o Java, sinó que un PHP, ja sigui per la pròpia potència de Python o bé per que ja hi ha una llibreria estàndard que té implementada aquella funcionalitat que cercam.
Aquesta setmana estava fent una integració amb la passarel·la de pagament del BBVA i m'he trobat amb un d'aquests casos. Per a la comunicació de les dades BBVA signa l'enviament i ho encripta fent servir l'algoristme d'encriptació xor. A la docuentació hi ha un exemple de vàries planes de codi de com es fa això amb PHP i Java/JSP.
Podeu trobar un exemple de com es fa amb PHP al SicilianGirl o també a l'IES Puig Castellar
La implementació de l'encriptació XOR en PHP, treta d'un snippet de php és:
function XOREncryption($InputString, $KeyPhrase){
$KeyPhraseLength = strlen($KeyPhrase);
// Loop trough input string
for ($i = 0; $i < strlen($InputString); $i++){
// Get key phrase character position
$rPos = $i % $KeyPhraseLength;
// Magic happens here:
$r = ord($InputString[$i]) ^ ord($KeyPhrase[$rPos]);
// Replace characters
$InputString[$i] = chr($r);
}
return $InputString;
}En Python això es faria així:
from itertools import izip, cycle def xor_crypt_string(data, key): return ''.join(chr(ord(x) ^ ord(y)) for (x,y) in izip(data, cycle(key)))
Python és un llenguatge molt potent, i part d'aquesta potència és la possibilitat de fer servir la programació funcional i els iteradors.
Com el seu nom indica cycle va retornant elements d'un iterable de manera cíclica, és a dir que quan arriba al darrer torna a començar.
izip té un nom potser més confús, ja que no té res a veure amb el popular format de compressió, és un iterador que donats dos iterables (dues llistes de caràcters en el nostre cas) ens retorna cada vegada una parella d'elements on el primer element pertany a la primera llista i el segon element a la segona.
Fixau-vos que el cycle ens permet eliminar el codi que manté el comptador al PHP, és a dir $rPos i tot el relacionat amb ell.
Una altra raó més per fer servir Python! :)
Enllaços citats
Traducciones/Translations by apertium
7 comentaris, 0 trackbacks (URL) , Tags: Python
Comentaris
1 Comentari de Tomeu Borrás a les 11:07 del Sunday 18 Jul de 2010
Dolenta de collons.
1.- Ni un sol comentari al codi en python
2.- Codi spaguetti que anida en una sola linia diverses sentencies fins i tot un for (Cosa que es un atemptat fins i tot per al pseudo-codi).
Si vols també podem reduir el codi en php a una sola linia i llevar els comentaris però no serà un algoritme millor. Només serà mes curt.
No t'emprenyis però es que no me pareix molt bon exemple.
Salut
2 Comentari de aaloy a les 01:07 del Sunday 18 Jul de 2010
Tomeu en el cas Python és un cas clar que el comentari és redundant, sols diria quelcom com "Encripta/desencripta una cadena pel mètode xor" que és el que diu la funció. Els comentaris han de dir el que fa el codi i no com ho fa i aportar informació.
Del 2. El que veus no és spaguetty, és programació funcional i fixat que per mor del nom de les funcions queda totalment documentat. No és codi ofuscat, és codi clar però amb sintaxi funcional. És d'aquestes coses que té Python a la cartera, pots fer programació procedural, orientada a objectes i funcional i mesclar-ho com vulguis segons les teves necessitats.
Fitxa't que es llegeix molt bé:
''.join(chr(ord(x) ^ ord(y)) for (x,y) in izip(data, cycle(key)))
Per llegir-ho has de fer servir un llenguatge més matemàtic, però és el que expressariem realment amb l'algorisme:
La encriptació xor és el resultat de fer un xor binari damunt els elements de la cadena a encriptar amb la clau d'encriptació i tornar-ho a passar a cadena. L'algorisme a més fa servir iteradors per tot.
Aquest tipus de construcció és molt típica quan has de tractar amb conjunts i llistes. És diu list comprehension http://trespams.com/2008/01/31/aja-list-comprehension-explained/
La programació funcional no es fa servir tant a Python perquè tendeix a fer poc clar el codi, però quan mapeja directament un algorisme matemàtic està molt bé.
Per exemple, si teneim una llista de nombres i volen trobar sols els parells: parells = [x for x in llista if x%2 ==0], és molt més ràpid que un for i diria que molt més bo de seguir.
3 Comentari de Tomeu Borrás a les 01:07 del Sunday 18 Jul de 2010
Doncs jo no ho veig així.
Els comentaris al python no poden esser redundants quan en principi son inexistents.
Al manco ahuries d'explicar la importació de les llibreries izip i cycle, que es fa la substitució a tot el buffer per el corresponent xor.
En el referent a velocitat no ho he provat però creq que python i perdria bastants punts ja que encara que sigui implicit l'index del bucle internament el python segueix fent la iteració.
Realment no ho veig clar.
4 Comentari de DZPM a les 03:07 del Sunday 18 Jul de 2010
El que jo no veig clar es com un banc pot estar fent servir 'encriptació XOR' per passar dades... es bastant insegur, no?
5 Comentari de aaloy a les 05:07 del Sunday 18 Jul de 2010
Tomeu, quan escrius codi no expliques què fan les llibreries estàndard del llenguatge, per això són estàndard, podríem explicar que és l'encriptació XOR al cos de la funció, però tot això no lleva que es pugui fer amb una lína de codi.
Per una altra banda, els bucles fets amb aquest tipus d'iteració són molt més ràpids que els normals en Python.
DZPM aquesta encriptació sols és una petita part del que es fa. Després s'ha tornar a signar amb sha1. Supòs que ho consideren prou segur pel nombre d'operacions que pot fer cada comerç.
6 Comentari de guillem a les 06:07 del Sunday 18 Jul de 2010
M'encanta la programació funcional per l'absència quasi total de variables, evitant sempre l'esforç d'haver de trobar noms ocurrents per aquestes.
Ara en sèrio, sovint és més fàcil fins i tot entendre codi funcional que codi procedural, sobretot perquè en el funcional queda explícit directament en el codi.
7 Comentari de aaloy a les 08:07 del Friday 23 Jul de 2010
Com a referència deix un interessant estudi damunt els distints mètodes per a afegir cadenes de caràcters. Explica el perquè és millor el mètode del join.
http://www.skymind.com/~ocrow/python_string/
