2017-02-27 2 views
2

En this code golf answer, aross donne une solution qui utilise probablement le codage IBM-850 en tant que valeurs de paramètres en PHP »Comment l'encodage IBM-850 fonctionne-t-il avec les paramètres de la fonction PHP?

echo preg_filter("/^(.*?[aeiouy]+)/i","$1 $1 $0",$argn); 
echo preg_filter(~ðíÎÐı└ñ×ÜûÉèåóÈÍðû,~█╬▀█╬▀█¤,$argn);  # Encoded 

Comment ça marche? Pourquoi les paramètres ne sont pas cotés? Comment se fait que les paramètres sont codés et non le reste du code?

Répondre

3

Il n'a pas tant à voir avec IBM-850, qui est juste un codepage remplissant le 8 peu au-delà ASCII pour donner une représentation aux octets que vous finirez avec.

La clé ici s la bitwise not operator ~ qui retourne tous les bits - 0 devient 1 et 1 devient 0. Si vous videz ~"/^(.*?[aeiouy]+)/i" dans un fichier et l'ouvrir comme 850 ça va ressembler:

ðíÎÐı└ñ×ÜûÉèåóÈÍðû 

Et ~"$1 $1 $0" aussi ressemble à:

█╬▀█╬▀█¤ 

Alors vous voyez où cela va.

En PHP, une constante indéfinie est supposée avoir une valeur de chaîne correspondant à son nom. Par exemple:

var_dump(foo); 

Sorties string(3) "foo" (ainsi que l'avis « L'utilisation de foo constante indéfinie - supposée« foo », si les avis sont allumés.)

Lorsque l'une des deux chaînes charabia ci-dessus sont mis dans un script PHP sans guillemets, ils sont pris comme des constantes non définies avec leurs noms supposés pour leurs valeurs.

Maintenant PREPEND chacun ~ pour retourner en arrière leurs morceaux et vous avez les regex d'origine et cordes remplacement:

preg_filter("/^(.*?[aeiouy]+)/i","$1 $1 $0",$argn) 

Seuls les paramètres ont leurs bits basculés parce qu'ils sont la seule chaîne littéraux, qui est ce que cette astuce s'applique à. Pour chaque chaîne, il s'agit d'une paire de guillemets en échange d'un seul tilde.

Le retournement de bit a dû être effectué car l'une des chaînes d'origine seules sans guillemets aurait posé des erreurs d'analyse.

Façon astucieuse de créer deux octets.