classe antispam en php

ViPHP
ViPHP | 3607 Messages

23 janv. 2007, 17:55

Bonjour à tous,
Suite à ce problème, et à l'idée de Hubert
Je me suis mis en tête de faire une classe d'antispam php...
Elle est fonctionnelle en l'état, mais il reste tout de même de nombreuses améliorations à faire...
Je compte donc sur vos critiques pour faire évoluer le bazard...
Voici la classe:
<?php
/**
 * Classe anti-spam
 * Permet d'utiliser le traditionnel mailto
 * Sans les désagréments des spammeurs...
 *
 * Attention, la fonction mailto() est à utilisée
 * avant tout envoi de contenu/entêtes au navigateur
 * Car elle en envoie elle-même
 * 
 * Exemple d'utilisation :
 * <code><?php
 * if(empty($_SERVER['QUERY_STRING']))
 * {
 *     $spam = new antiSpam('[email protected]', 'vigenere', 'un titre','un petit texte de contenu');
 *     $spam->writeLink();
 * }
 * else
 * {
 *     $spam = new antiSpam($_SERVER['QUERY_STRING'],'vigenere');
 *     $spam->mailto();
 * }
 * ?></code>
 * 
 * @author Joris Mulliez
 * @package Mail
 */
class antiSpam
{
    /**
     *  Borne infèrieure pour la génération de la clé aléatoire
     */
    const BORNE_RAND_INF=1;

    /**
     *  Borne supèrieure pour la génération de la clé aléatoire
     */
    const BORNE_RAND_SUP=255;

    /**
     *
     */
    const RANDOM=0;

    /**
     *
     */
    const DEFAULT_URL='php_self';

    /**
     * Texte affiché par defaut entre <a...> et </a> s'il n'est pas précisé
     */
    const DEFAULT_TXT='click';

    /**
     * Title par defaut du lien
     */
    const DEFAULT_TITLE='E-mail';

    /**
     * Variable contenant l'email à cacher des spammeurs
     */
    private $email=null;

    /**
     * Variable contenant la clé de cryptage
     */
    private $crypt_methode=null;

    /**
     * Variable contenant un éventuel sujet du mail
     */
    private $subject=null;

    /**
     * Variable contenant un éventuel contenu du mail
     */
    private $body=null;

    /**
     * Variable contenant l'url vers laquelle renvoi le lien
     */
    private $url=null;

    /**
     * Variable contenant le texte entre les balises <a...> et </a>
     */
    private $txt=null;

    /**
     * Variable contenant un éventuel title du lien
     */
    private $title=null;
    
    /**
     * tableau des correspondances fonctions méthodes de cryptage
     */
    private $crypt_functions=array('vigenere'=>array('vig_crypt','vig_decrypt'),'cesar'=>array('cesar_crypt','cesar_decrypt'));
    

    /**
     * Constructeur
     *
     * @param String $email
     * @param Int    $key
     * @param String $subject
     * @param String $body
     * @param String $url
     * @param String $txt
     * @param String $title
     */
    public function __construct($email,$crypt_methode=RANDOM,$subject=null,$body=null,$url='php_self',$txt=null,$title=null)
    {
        $this->email = $email;
        $this->crypt_methode = $crypt_methode;
        $this->subject = $subject;
        $this->body = $body;
        $this->url = $url==self::DEFAULT_URL ? $_SERVER['PHP_SELF'] : $url;
        $this->txt = $txt==null ? self::DEFAULT_TXT : $txt;
        $this->title = $title==null ? self::DEFAULT_TITLE : $title;
    }

    /**
     * Fonction writeLink
     * permet d'écrire le lien à cliquer pour effectuer le mailto
     */
    public function writeLink()
    {
        $tmp[] = (!empty($this->subject)) ? 'subject='.$this->subject : false;
        $tmp[] = (!empty($this->body)) ? 'body='.$this->body : false;
        $tmp=implode('&',$tmp);
        $mailto = $this->email.(!empty($tmp) ? '?'.$tmp : '');
        $mailto = $this->encoder($mailto);
        echo '<a title="'.$this->title.'" href="'.$this->url.'?' . urlencode($mailto) . '">'.(!empty($this->txt) ? $this->txt : 'click').'</a>';

    }

    /**
     * Fonction mailto
     * permet de décoder l'email et ses paramètres et de l'enovoyer en entête afin de lancer le logiciel de messagerie
     */
    public function mailto()
    {
        header('Refresh: 0;url="mailto:'.$this->decoder(urldecode($this->email)));
        exit();
    }

    /**
     * Fonction encoder
     * @param  String $str  la chaine à encoder
     * @return String       la chaine encodée
     */
    private function encoder($str)
    {
        return $this->{$this->crypt_functions[$this->crypt_methode][0]}($str);
    }

    /**
     * Fonction decoder
     * @param  String $str  la chaine à decoder
     * @return              la chaine decodée
     */
    private function decoder($str)
    {
        return $this->{$this->crypt_functions[$this->crypt_methode][1]}($str);
    }
    
    /**
     * Fonction cesar_crypt
     * @param  String $str  la chaine à encoder
     * @return              la chaine encodée
     */
    private function cesar_crypt($str)
    {
        $key=rand(1,255);
        $temp='';
        for($i=0;$i<strlen($str);$i++){
            $temp.=chr(ord($str{$i})+$key);
        }
        return chr($key).$temp;
    }
    
    /**
     * Fonction cesar_decrypt
     * @param  String $str  la chaine à decoder
     * @return              la chaine decodée
     */
    private function cesar_decrypt($str)
    {
        $key=ord($str[0]);
        $temp='';
        for($i=1;$i<strlen($str);$i++){
            $temp.=chr(ord($str{$i})-$key);
        }
        return $temp;
    }
    
    /**
     * Fonction vig_crypt
     * @param  String $str  la chaine à encoder
     * @return              la chaine encodée
     */
    private function vig_crypt($texteaCrypter,$longueurcle=0)
    {
        for($i=0;$i<=255;$i++){
            $carreVigenere[$i]=array();
            $x=$i;
            for($j=0;$j<=255;$j++){
                $carreVigenere[$i][]=chr($x);
                $x=(($x<255) ? $x+1 : 0);
            }
        }
        $Cle='';
        if($longueurcle==0) $longueurcle=rand(5,30);
        for($i=0;$i<$longueurcle;$i++)
            $Cle.=chr(rand(0,255));
        $texteCrypter=='';
        $j=0;
        for($i=0;$i<strlen($texteaCrypter);$i++){
            
            //on "descend" à la ligne correspondant à la lettre de la cle et ça nous donne la lettre cryptée
            $texteCrypter.=$carreVigenere[ord($Cle{$j})][ord($texteaCrypter{$i})];
            
            //gestion de la rotation de la clé
            $j=(($j<($longueurcle-1)) ? $j+1 : 0);
        }
        return chr($longueurcle).$Cle.$texteCrypter;
    }

    /**
     * Fonction vig_decrypt
     * @param  String $str  la chaine à decoder
     * @return              la chaine decodée
     */
    private function vig_decrypt($texteaDecrypter)
    {
        for($i=0;$i<=255;$i++){
            $carreVigenere[$i]=array();
            $x=$i;
            for($j=0;$j<=255;$j++){
                $carreVigenere[$i][]=chr($x);
                $x=(($x<255) ? $x+1 : 0);
            }
        }
        $longueurcle=ord($texteaDecrypter{0});
        $Cle='';
        for($i=1;$i<=$longueurcle;$i++)
            $Cle.=$texteaDecrypter{$i};
        $texteDecrypter='';
        $j=0;
        for($i=$longueurcle+1;$i<strlen($texteaDecrypter);$i++){
            
            //on cherche la position de la lettre du texte crypté dans la ligne correspondant à la lettre de la clé
            $key=array_keys($carreVigenere[ord($Cle{$j})],$texteaDecrypter{$i});
            
            // on "remonte" à la première ligne et ça nous donne la lettre décryptée
            $texteDecrypter.=$carreVigenere[0][$key[0]];
            
            //rotation de la clé
            $j=(($j<($longueurcle-1)) ? $j+1 : 0);
        }
        return $texteDecrypter;
    }
}
?>
et un exemple d'utilisation:
<?php
if(empty($_SERVER['QUERY_STRING'])){
    $spam = new antiSpam('[email protected]','cesar','un titre','un petit texte de contenu');
    $spam->writeLink();
} else {
    $spam = new antiSpam($_SERVER['QUERY_STRING'],'cesar');
    $spam->mailto();
}
?>
voilà j'attend vos remarques ;-)
Modifié en dernier par jojolapine le 26 janv. 2007, 13:45, modifié 1 fois.

Mammouth du PHP | 19672 Messages

23 janv. 2007, 19:01

Proposition d'amélioration en vitesse : soigne la manière de faire les commentaires de façons à générer une documentation complète avec phpDocumentor :
<?php
/**
 * Classe anti-spam
 * Permet d'utiliser le traditionnel mailto
 * Sans les désagréments des spammeurs...
 *
 * Attention, la fonction mailto() est à utilisée
 * avant tout envoi de contenu/entêtes au navigateur
 * Car elle en envoie elle-même
 * 
 * Exemple d'utilisation :
 * <code><?php
 * if(empty($_SERVER['QUERY_STRING']))
 * {
 *     $spam = new antiSpam('[email protected]', RANDOM, 'un titre','un petit texte de contenu');
 *     $spam->writeLink();
 * }
 * else
 * {
 *     $spam = new antiSpam($_SERVER['QUERY_STRING']);
 *     $spam->mailto();
 * }
 * ?></code>
 * 
 * @author ....
 * @package Mail
 */
class antiSpam
{
    /**
     *  Borne infèrieure pour la génération de la clé aléatoire
     */
    const BORNE_RAND_INF=1;

    /**
     *  Borne supèrieure pour la génération de la clé aléatoire
     */
    const BORNE_RAND_SUP=255;

    /**
     *
     */
    const RANDOM=0;

    /**
     *
     */
    const DEFAULT_URL='php_self';

    /**
     * Texte affiché par defaut entre <a...> et </a> s'il n'est pas précisé
     */
    const DEFAULT_TXT='click';

    /**
     * Title par defaut du lien
     */
    const DEFAULT_TITLE='E-mail';

    /**
     * Variable contenant l'email à cacher des spammeurs
     */
    private $email=null;

    /**
     * Variable contenant la clé de cryptage
     */
    private $key=null;

    /**
     * Variable contenant un éventuel sujet du mail
     */
    private $subject=null;

    /**
     * Variable contenant un éventuel contenu du mail
     */
    private $body=null;

    /**
     * Variable contenant l'url vers laquelle renvoi le lien
     */
    private $url=null;

    /**
     * Variable contenant le texte entre les balises <a...> et </a>
     */
    private $txt=null;

    /**
     * Variable contenant un éventuel title du lien
     */
    private $title=null;


    /**
     * Constructeur
     *
     * @param String $email
     * @param Int    $key
     * @param String $subject
     * @param String $body
     * @param String $url
     * @param String $txt
     * @param String $title
     */
    public function __construct($email,$key=RANDOM,$subject=null,$body=null,$url='php_self',$txt=null,$title=null)
    {
        $this->email = $email;
        $this->key = $key==self::RANDOM ? rand(self::BORNE_RAND_INF,self::BORNE_RAND_SUP) : $key;
        $this->subject = $subject;
        $this->body = $body;
        $this->url = $url==self::DEFAULT_URL ? $_SERVER['PHP_SELF'] : $url;
        $this->txt = $txt==null ? self::DEFAULT_TXT : $txt;
        $this->title = $title==null ? self::DEFAULT_TITLE : $title;
    }

    /**
     * Fonction writeLink
     * permet d'écrire le lien à cliquer pour effectuer le mailto
     */
    public function writeLink()
    {
        $tmp[] = (!empty($this->subject)) ? 'subject='.$this->subject : false;
        $tmp[] = (!empty($this->body)) ? 'body='.$this->body : false;
        $tmp=implode('&',$tmp);
        $mailto = $this->email.(!empty($tmp) ? '?'.$tmp : '');
        $mailto = $this->encoder($mailto);
        echo '<a title="'.$this->title.'" href="'.$this->url.'?' . urlencode($mailto) . '">'.(!empty($this->txt) ? $this->txt : 'click').'</a>';

    }

    /**
     * Fonction mailto
     * permet de décoder l'email et ses paramètres et de l'enovoyer en entête afin de lancer le logiciel de messagerie
     */
    public function mailto()
    {
        header('Refresh: 0;url="mailto:'.$this->decoder(urldecode($this->email)));
        exit();
    }

    /**
     * Fonction encoder
     * @param  String $str  la chaine à encoder
     * @return String       la chaine encodées
     */
    private function encoder($str)
    {
        $key=$this->key;
        $temp='';
        for($i=0;$i<strlen($str);$i++){
            $temp.=chr(ord($str{$i})+$key);
        }
        return chr($key).$temp;
    }

    /**
     * Fonction decoder
     * @param  String $str  la chaine à decoder
     * @return              la chaine decodée
     */
    private function decoder($str)
    {
        $key=ord($str[0]);
        $temp='';
        for($i=1;$i<strlen($str);$i++){
            $temp.=chr(ord($str{$i})-$key);
        }
        return $temp;
    }
}
?>
;)
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

ViPHP
AB
ViPHP | 5818 Messages

23 janv. 2007, 21:45

Bonjour,

J'arrive pas à tester. En localhost ou sur le serveur distant ça m'affiche

Code : Tout sélectionner

Parse error: parse error, expecting `T_OLD_FUNCTION' or `T_FUNCTION' or `T_VAR' or `'}'' in d:\program files\easyphp1-8\www\alainbweb\untitled-13.php on line 33

ViPHP
ViPHP | 3607 Messages

23 janv. 2007, 22:40

à quoi correspond la ligne 33 ? quelle version de php ?
Sinon comme ça au pif, c'est peut-être parceque j'ai une fonction qui s'appelle mailto ? (comme celle de php)
Surement à changer :-k

ViPHP
AB
ViPHP | 5818 Messages

23 janv. 2007, 22:54

Re bonsoir

La ligne 33 c'est : const BORNE_RAND_INF=1;

Serveur distant PHP Version 4.4.4

Localhost PHP Version 4.3.10

ViPHP
ViPHP | 3607 Messages

23 janv. 2007, 23:00

oups :oops: j'ai oublié de dire, c'est une classe php5
je la referai peut-être pour php4, ais pas tout de suite, j'attend de "finaliser" celle-ci

ViPHP
ViPHP | 3607 Messages

24 janv. 2007, 00:03

je viens d'essayer PhpDocumentor avec ma version de classe et la tienne, et ben c'est le jour et la nuit :langue:
merci pour ce petit conseil ;-)
Bon j'essaye petit à petit d'améliorer...
J'ai une question, par rapport à mon encodage/décodage
Je me suis dit tout à l'heure "mince et si jamais le caractère plus le nombre aléatoire fait plus de 255 (en code ascii) ça va plus rimer à rien et tout faire *****!"
Et bien je me demande pourquoi, j'ai mis une clé de 2000, et ben tout marche au poil... :shock:
existe-il une table ascii étendue qui va jusqu'a 100000000000.....000000 de caractères ? :roll:
je comprend pas trop :?

ViPHP
ViPHP | 3607 Messages

26 janv. 2007, 13:50

Hopla!
j'ai éditer mon premier post pour une nouvelle version de la classe...
qui permet de gérer plus facilement diverses méthodes de cryptage, il suffit en effet de rajouter les fonctions de cryptage/decryptage, et de mettre à jour le tableau $crypt_functions...
Les seules contraintes étant que la clé doit être passée dans l'url, à l'intèrieur du message codé!
(comme ça pas de sessions...)
Il reste bien sur moultes choses à faire, car j'ai livré la version à chaud! :wink:

ViPHP
ViPHP | 4674 Messages

01 févr. 2007, 18:43

Bonjour,

On va continuer la discussion pour faire un peu de pub à ta classe ;-)

Alors, le système est bien pensé, à une chose prêt (et je vais chercher de ce pas) : on ne rentre pas l'adresse email en tant que texte entre la balise <a>.
Car dans : <a href="mailto:address1">address2</a>, le robot va lire la 1 et et la 2. Donc on enlève le mailto, bien il reste donc la numéro 2. Alors on va remplacer par un texte.
Well, pas de problème Sergent, but est-ce que vous aimeriez aller sur un site où il n'y a pas l'adresse email d'indiquer, mais un texte alternatif ?
Souvent, je vais sur un site pour retrouver un adresse, ou alors savoir qu'elle existe, je ne vais pas forcément cliquer sur le lien.
C'est mal dit, mais le fond de ma pensée est : je pense qu'il faut tout de même indiquer l'adresse.

Dans ce cas, ne faudrait-il pas prendre l'alternative : address_AT_domain_DOT_tld, qui serait alors le texte du lien, et on fait un header location sur mailto comme actuellement ? (est-ce les robots comprennent ça ?)

Je vais regarder les normes accessibilités concernant les emails, mais je voulais déjà poser ces questions ^^

Merci
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

ViPHP
ViPHP | 3607 Messages

01 févr. 2007, 19:08

Bonjour et merci de t'intéresser à ma classe ;)
concernant le fait que tu souhaites voir l'adresse afficher entre les <a>...</a>, c'est dors et déja possible, en renseignant le paramètre $txt, on peut donc faire comme ceci:
$antispam= new antiSpam($email,RANDOM,$sujet_du_mail,$contenu_du_mail,$url_redirection,$email,$untitre);
en sachant qu'il n'y a pas de remplacement du @ et du .
(mais c'est tout à fait envisageable de le faire ;-) )
Maintenant, le principal défaut de la méthode (jusqu'a ce que je trouve la parade), c'est que lorsque l'on clique... on arrive sur une page blanche, et là j'arrive pas à rediriger ailleur... :cry:
mais bon je cherche (cf http://www.phpfrance.com/forums/voir_sujet-26766.php)
Après je sais pas si c'est utile de garder de multiples fonctions de cryptages... d'içi à ce que les robots trouve la clé et la méthode de cryptage, on est tranquille je pense ;-)

ViPHP
ViPHP | 4674 Messages

01 févr. 2007, 19:13

Alors, après recherche sur le service de BrailleNet, à savoir AccessiWeb, je n'ai trouvé aucune recommandation concernant les adresses emails.

J'ai trouvé une alternative plutôt intéressante, mais je ne connais pas suffisament le comportement des robots pour savoir si elle est juste, à vous de me dire.

Bien, alors, comme tout le monde devrait le savoir, le texte d'un lien hypertexte ne doit pas être seulement : "ici", "cliquez-ici", "suivant", "lire", "commenter" etc. Mais "Lire l'article n°7", "Voir l'article suivant : Comment ne pas se faire spammer", ou encore "Commenter l'article n°7" (attention, un lien ne doit pas dépasser 80 caractères ; cf AccessiWeb, le but n'étant pas ici ne parler de ça).
Donc, le robot va voir un lien, il va alors regarder le texte de ce lien, et il va lire : "Me contacter à l'adresse : [email protected]".
Aussi, le fait de mettre une phrase dans le lien améliore le référencement.

Je pars du principe que le robot regarde _tous_ les liens (même ceux qui ne comporte pas de mailto:).

L'adresse est cachée dans le texte du lien, et de cette façon, on améliore l'accessibilité, et le référencement.
Après il faut savoir si le robot analyse précisement le texte, c'est à dire, est-ce qu'il cherche le motif d'une adresse email dans un texte de lien si l'adresse email n'est pas immédiate ? Ou est-ce que si l'adresse email n'est pas immédiate (c'est à dire cachée) il passe son chemin de suite ?

Que de questions :D


Petit résumé :
  • Soit le robot scanne tous les liens
    • l'adresse est immédiate, par exemple : <a href="[...]" title="Me contacter">[email protected]</a> ;
      l'adresse n'est pas immédiate, par exemple : <a href="[...]" title="Me contacter">Me contacter à l'adresse [email protected]</a> ;
    Soit le robot scanne que les liens mailto:
    • même raisonnement, en ajoutant <a href="mailto:*" ...> ;
Je vous laisse sur cette réflexion.[/list]


EDIT :
tu m'avais dis que le robot regardait le texte du lien, et le lien lui même (j'avais pris comme exemple un href="mailto: ...). Donc on ne peut pas laisser l'adresse en tant que texte, le problème saurait toujours là. sauf si le robot ne scanne pas les liens "non-mailto" ...
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

ViPHP
ViPHP | 3607 Messages

01 févr. 2007, 19:19

Je pense que c'est à peu près comme l'a dit Hubert, c'est à dire que toute adresse email contenu dans une page (qu'elle soit derrière un mailto ou non) sera récupérée, donc afficher en clair l'adresse, même hors mailto, je suis pas sur qu'on soit à l'abris...

ViPHP
ViPHP | 4674 Messages

01 févr. 2007, 19:23

Ok, donc le robot scanne tous les liens.
Est-ce qu'il va aller chercher un motif de lien, ou alors le camouflage est parfait ? :D
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

ViPHP
ViPHP | 3607 Messages

01 févr. 2007, 19:27

Est-ce qu'il va aller chercher un motif de lien, ou alors le camouflage est parfait ? :D
Le robot scanne TOUT!!!
c'est à dire que si tu as ça dans ta page:
<p>ozef ef ozef nfez [email protected] rogregn </p>
il va récupérer l'adresse... (après c'est que des suppositions ;-) )

et au cas ou tu ne le saurais pas... ton adresse est actuellement dans un mailto sur cette page ;-)

ViPHP
ViPHP | 4674 Messages

01 févr. 2007, 21:44

lol, bon on a pas fini de galérer :P

Je vais encore y réfléchir :)
Je vous tiens au jus.
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).