Comme je n'ai pas (plus diraient certains) de blog, et que là je suis tellement
content de ce que j'ai trouvé que j'ai envi d'en informer le monde, et bien
voila, je m'adresse à toi, cher public (et non cher 'Nal).
Vous connaissez tous Python_(langage) comme étant le meilleur langage du
monde. Aussi vous devez savoir que les sources d'un bout de code python peuvent
être écrite dans n'importe quel Codage_des_caractères (genre ascii, UTF-8,
...).
Par exemple en faisant ceci :
# coding: utf8
print "Ceci est du code python encodé en utf8"
Jusqu'à présent je pensais qu'il s'agissait d'un comportement en dur dans
l'interpréteur en fait il n'en est rien, c'est beaucoup plus malin que cela.
Python définit un module codecs pour gérer les
différents codages de caractères, et c'est ce module qui est appelé par
l'interpréteur pour traduire en unicode le code que l'on a écrit. Chaque
encodage différent est représenté dans
/usr/lib/pythonX.Y/encodings par un fichier name.py
contenant les fonctions d'encodage et de décodage adaptées.
Ainsi il est possible d'écrire son code source dans n'importe quel encodage
supporté dans ce répertoire. Or il y en a un que j'utilise depuis longtemps
pour protéger ma vie privé (joke inside), c'est l'encodage [[ROT13]]. Un petit exemple en mode
interactif de python :
>>> u'Hello linuxfr.org'.encode('rot13')
'Uryyb yvahkse.bet'
>>> 'Uryyb yvahkse.bet'.decode('rot13')
u'Hello linuxfr.org'
Et là la question qui m'est venue ce matin c'est "Est il possible d'écrire un
code source en rot13 ?" Essayons :
Le code original:
for i in range(5):
print i, u"test"
La version rot13:
# coding: rot13
sbe v va enatr(5):
cevag v, h"grfg"
L'exécution :
$ python test_rot13.py
0 test
1 test
2 test
3 test
4 test
Petite remarque, si dans le code original l'on remplace u"test"
par "test", et bien cela fonctionne toujours, mais cela affiche
grfg en lieu et place de test. Cela vient d'une particularité de python. Les
chaînes commençant par u représentent une suite de caractère unicode encodés
dans le format du fichier. Ainsi lorsque python converti le code source en
unicode, il prend le contenu de la chaine, le décode avec l'encodage
spécifié, et forme ainsi une chaine unicode.
Dans le cas d'une chaine sans le préfixe u, il s'agit (en python 2), d'une
chaine d'octets purs qui doivent être insérés sans modifications dans le
programme. Ainsi cette chaine est convertie en unicode, donnant le code
"test". Mais lors de l'exécution, le parseur va lire cette chaîne
et se rappeler qu'en vrai il s'agit d'une chaine d'octets, et la reconvertir
dans l'encodage d'origine.
Comme dirait ma sainte grand-mère, Oh my god ! Bref, cette découverte m'a rendue
heureuse. Et soudain mon cerveau malade et pervers s'est demandé jusque où
cette perversion peut elle aller ?
Je regarde un peu comment ce système fonction, et globalement c'est tout simple, python commence le traitement du code source en ASCII, et dès qu'il trouve un #coding: name, il passe toute la suite du fichier à la moulinette de décodage, celle-ci devant normalement lui générer une chaine unicode correspondant à un code source python valide. Mais il n'est écrit nul part que le contenu du fichier doit être un code source python valide ! En fait n'importe quel contenu (voir même pas de contenu) est possible, si la fonction de décodage génère du code valide.
Ainsi je me suis lancé dans l'écriture d'un codec pour le [Brainfuck], langage idolé des foules. Je vous le copie paste en gros (attention, code ugly et hackish a mort, Don't do this at home kids !).
Le fichier /usr/lib/python2.6/encodings/bf.py :
import codecs
indent = 0
started = False
def bf_encode(input, errors='strict',
filename='', mode=0666):
return (str(input), len(input))
def bf_decode(input, errors='strict'):
global indent, started
if not input:
return (u'', 0)
content = input
if not started:
source = u'''
from collections import defaultdict
import sys
data_ptr = 0
memory = defaultdict(int)
'''.split(u'\n')
started = True
else:
source = []
def add(s):
source.append(u'\t' * indent + s)
for char in content:
if char == u'>':
add(u'data_ptr += 1')
if char == u'<':
add(u'data_ptr -= 1')
if char == u'+':
add(u'memory[data_ptr] += 1')
if char == u'-':
add(u'memory[data_ptr] -= 1')
if char == u'.':
#add(u'sys.stdout.write(memory[data_ptr])')
add(u'sys.stdout.write(chr(memory[data_ptr]))')
if char == u',':
add(u'memory[data_ptr] = ord(sys.stdin.read(1))')
if char == u'[':
add(u'while memory[data_ptr]:')
indent += 1
if char == u']':
indent -= 1
return (u'\n'.join(source) + u'\n', len(input))
class Codec(codecs.Codec):
def encode(self, input, errors='strict'):
return bf_encode(input, errors)
def decode(self, input, errors='strict'):
return bf_decode(input, errors)
class StreamWriter(Codec, codecs.StreamWriter):
pass
class StreamReader(Codec, codecs.StreamReader):
pass
def getregentry():
return (bf_encode, bf_decode, StreamReader, StreamWriter)
Le fichier source à exécuter :
# coding: bf
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
Et son execution :
$ python test.py
Hello World!
Rendons hommage à un autre fou furieux qui à eu la même idée, mais qui s'en est
servi pour remplacer l'indentation significative de python par un système à
base d'accolades, [http://timhatch.com/projects/pybraces/]. Je me suis
largement inspiré de son code pour écrire le mien.
Pour conclure, cela ne sert à rien, c'est marrant, et on doit pouvoir écrire
des préprocesseurs pour python avec ;)
Je me suis bien marré, j'espère que vous aussi ;)
# Rhhaa, de balises
Posté par Guillaum (site web personnel) . Évalué à 3.
[^] # Re: Rhhaa, de balises
Posté par CrEv (site web personnel) . Évalué à 4.
[^] # Re: Rhhaa, de balises
Posté par Guillaum (site web personnel) . Évalué à 2.
En fait c'est mon éditeur qui coupe les phrases et après pour linuxfr j'oublie de remettre le bon formatage.
En fait c'est tordu, parce que si l'on coche la case "ajouter des retours a la ligne", cela prend en compte mes retours a la ligne inutiles, et si l'on ne la coche pas, cela font le bronx.
Bref toutes mes excuses pour cela.
Sinon, simple remarque, mais sur un viewport de plus de 800 px de large, si tu laisse le texte couler normalement, cela ne fait pas des lignes de 400 caractères ? Personnellement mon cerveau décroche sur les lignes de plus de 80 caracteres (je crois que des études prouvent que la longueur moyenne de confort c'est 40em)
[^] # Re: Rhhaa, de balises
Posté par CrEv (site web personnel) . Évalué à 3.
C'est surtout que les navigateurs sont capables, en fonction de la css, de remplir correctement le texte et même de le justifier. Aussi si ma css me présente des lignes de 400 mots c'est que ma css est moisie. Mais si je la configure bien et que je la laisse faire, ben quelque soit mon écran l'affichage sera correct.
Si par contre je prend un texte en dur à 80 (qui en outre a un aspect dégeu sur le bord droit) sur un écran plus petit, ça devient franchement crade.
[^] # Re: Rhhaa, de balises
Posté par Psychofox (Mastodon) . Évalué à 2.
[^] # Re: Rhhaa, de balises
Posté par CrEv (site web personnel) . Évalué à 2.
# Fonctionnalité qui tue
Posté par Maclag . Évalué à 4.
Étant donné que Python est un langage facile et accessible, on peut supposer que la moitié des développeurs Python ne sait pas ce qu'est un encodage.
Par corollaire, on démontre que cette "fonctionnalité" est presque complètement inutile pour tous les autres langages. Un bon préprocesseur suffit largement.
Hein? Ouai, bon, avec toutes les civilisations qu'on a eu sur Terre, je vais bien trouver un calendrier sur lequel on est vendredi!!
-----------------> [ ]
[^] # Re: Fonctionnalité qui tue
Posté par Thomas J. (site web personnel) . Évalué à 3.
Vous connaissez tous Python_(langage) comme étant le meilleur langage du monde.
On va dire que c'est un prêté pour un rendu ;)
[^] # Re: Fonctionnalité qui tue
Posté par Tonton Th (Mastodon) . Évalué à 4.
Python_(langage)
Le lien wikipedia est faux. Il fallait lire http://python.org/ !
# nan mais vraiment
Posté par fearan . Évalué à 10.
Bon réflexion personnelles mise à part, c'est intéressant comme système; j'avais vu que des fichier perl pouvaient être encode en whitespace, le gars qui ouvrait un fichier ne vois que des espaces ou tabulation; donc rien.
C'est tout ce genre de trucs qui me font aimer l'info.
Il ne faut pas décorner les boeufs avant d'avoir semé le vent
# Faux espoir…
Posté par nicolas . Évalué à 10.
Tiens ?!
*scroll*
« Guillaume »
*soupir*
--
Les fautes de grammaire c’est le mal…
[^] # Re: Faux espoir…
Posté par Guillaum (site web personnel) . Évalué à -2.
Le COD c'est découverte, donc c'est avant, donc il faut accorder, or c'est féminin ?
Donc avec ce raisonnement (que j'ai eu en écrivant cet article, et j'étais tout fier de ne pas avoir, pour une fois, oublié d'accorder avec le COD), et bien l'accord est juste non ?
Bon, ok, après réflexion, le COD c'est pas "découverte", mais "m", toutes mes confuses !
N'empêche...
[^] # Re: Faux espoir…
Posté par Axel R. (site web personnel) . Évalué à 4.
Il n'empêche que dans tous les cas, "heureuse" est un adjectif qui s'accorde avec le nom... rien à voir avec le "participe passé".
On dira donc "la découverte qu'il a faite" alors qu'on dira "il a fait une découverte".
Axel
[^] # Re: Faux espoir…
Posté par nicolas . Évalué à 2.
[^] # Re: Faux espoir…
Posté par cosmocat . Évalué à 3.
PS : Je ne suis pas sûr qu'il soit de bon ton d'utiliser des acronymes qui ne soient pas dans le champ lexical du domaine traité par le site. J'ai mis trop longtemps à comprendre que COD voulait dire Complément d'Objet Direct et non pas autre chose (comme "CODe". Je me suis dis qu'ayant pour "habitude" de mettre un 'e' de trop, tu n'étais pas lojn d'enlever aussi :) )
[^] # Re: Faux espoir…
Posté par mansuetus (site web personnel) . Évalué à 1.
http://www.megaconnard.com/le-billet-reproduction-du-jour-co(...)
# chiffrage ?
Posté par Oook . Évalué à 4.
Si oui, python est le premier logiciel de script pour faire du code proprio...
[^] # Re: chiffrage ?
Posté par monde_de_merde . Évalué à 4.
# -*- coding: super_decrypteur_de_code_super_proprio -*-
Mais ton troll est trop gros pour que je te réponde sérieusement en rappelant que la faculté de lire un code n'est en rien lié à sa notre proprio/libre.
[^] # Re: chiffrage ?
Posté par monde_de_merde . Évalué à 2.
Mes confuses.
[^] # Re: chiffrage ?
Posté par Oook . Évalué à 1.
pour le troll, en fait, je pensais plus à un équivalent du pcode de matlab qui permet de livrer des fonctions de calcul sans donner l'algo...
[http://www.mathworks.com/help/techdoc/matlab_prog/f7-38053.h(...)]
[^] # Re: chiffrage ?
Posté par Guillaum (site web personnel) . Évalué à 2.
[^] # Re: chiffrage ?
Posté par Guillaum (site web personnel) . Évalué à 4.
Oui, cela doit être techniquement possible.
Cependant, j'avoue que je ne voie aucun moyen de ne pas exposer le code python déchiffré après (il est forcement en mémoire à un moment donné).
D'ailleurs j'en viens à me demander comment ils "sécurisent" ce type d'outil, les proprios ;)
Sinon, il faudra penser à désactiver la génération du bytecode .pyc, parce que celui-ci est en "clair".
Qu'entends tu par "de script"
[^] # Re: chiffrage ?
Posté par claudex . Évalué à 2.
Pour Javascript, il existe des obfuscateurs de code (à ne pas confondre avec les compresseurs).
« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
[^] # Re: chiffrage ?
Posté par Frank-N-Furter . Évalué à 10.
Depending on the time of day, the French go either way.
[^] # Re: chiffrage ?
Posté par zebra3 . Évalué à 3.
Article Quarante-Deux : Toute personne dépassant un kilomètre de haut doit quitter le Tribunal. -- Le Roi de Cœur
[^] # Re: chiffrage ?
Posté par claudex . Évalué à 3.
« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
[^] # Re: chiffrage ?
Posté par flagos . Évalué à 3.
[^] # Re: chiffrage ?
Posté par Frank-N-Furter . Évalué à 10.
Depending on the time of day, the French go either way.
[^] # Re: chiffrage ?
Posté par jigso . Évalué à 2.
Par ex Acme::EyeDrops, Acme::ǝmɔA, Acme::Palindrome, Acme::Greek,... (sur cpan.org)
# Le pouvoir du libre c'est aussi de rendre les gens heureux !
Posté par foutaises . Évalué à 3.
Car si python avait été propriétaire et fermé, jamais l'entreprise en charge du développement n'aurait proposé un codec rot13!
Et jamais une centaine de personnes n'auraient pu sortir de la lecture de ce journal avec le sourire aux lèvres, amusés et heureux de cette découverte.
Merci pour ce journal sympa comme tout.
[^] # Re: Le pouvoir du libre c'est aussi de rendre les gens heureux !
Posté par Victor STINNER (site web personnel) . Évalué à 2.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.