Zend Framework : validateur algorithme Luhn

Logo Zend Framework

L'algorithme de Luhn est utilisé comme somme de contrôle dans de nombreux identifiants comme le numéro SIREN ou les numéros de carte de crédits. Il permet de vérifier la validité d'un numéro et donc de détecter d'éventuelles erreurs de saisie.

Voici une implémentation en PHP dérivée de Zend_Validate_Abstract.

Pour vérifier un numéro de carte de crédit, il est préférable d'utiliser Zend_Validate_Ccnum.

<?php
/**
 * @see Zend_Validate_Abstract
 */
require_once 'Zend/Validate/Abstract.php';

class 
Wiip_Validate_Luhn extends Zend_Validate_Abstract
{
    
/**
     * Validation failure message key for when the value fails the mod-10 checksum
     */
    
const CHECKSUM 'luhnChecksum';

    
/**
     * Digits filter for input
     *
     * @var Zend_Filter_Digits
     */
    
protected static $_filter null;

    
/**
     * Validation failure message template definitions
     *
     * @var array
     */
    
protected $_messageTemplates = array(
        
self::CHECKSUM => "Luhn algorithm (mod-10 checksum) failed on '%value%'"
    
);

    
/**
     * Defined by Zend_Validate_Interface
     *
     * Returns true if and only if $value follows the Luhn algorithm (mod-10 checksum)
     *
     * @param string $value
     * @return boolean
     */
    
public function isValid($value)
    {
        
$this->_setValue($value);

        if (
null === self::$_filter) {
            
/**
             * @see Zend_Filter_Digits
             */
            
require_once 'Zend/Filter/Digits.php';
            
self::$_filter = new Zend_Filter_Digits();
        }

        
$valueFiltered self::$_filter->filter($value);

        
$length strlen($valueFiltered);

        
$sum 0;

        for (
$i $length 1$i >= 0$i--) {
            
$digit = (int) $valueFiltered[$i];
            if ((
$i 2) == 1) {
                
// Rang pair, on multiplie par 2
                
$digit *= 2;
        if (
$digit 9)    $digit -= 9;
            }
            
$sum += $digit;
        }

        if ((
$sum 10) != 0) {
            
$this->_error(self::CHECKSUM$valueFiltered);
            return 
false;
        }

        return 
true;
    }
}
?>

Exemple d'utilisation pour valider un numéro SIREN dans un formulaire dérivé de Zend_Form:

<?php
$this
->addElement(
    
'text',
    
'siren',
    array(
        
'description' => '9 chiffres',
        
'label' => 'SIREN :',
        
'maxlength' => 9,
        
'size' => 9,
        
'validators' => array(
            array(
'StringLength'true9),
            array(
'Luhn'true)
        )
    )
);
?>

Commentaires

Il est à noté que ce test ne fonctionne pas pour tous les sirens. En effet dans certains cas, la banque de france utilise des numéros siren fictifs commençant par 20 et ne validant pas l'algorithme de Luhn.

Ajouter un commentaire