The_magicien
Messages postés72Date d'inscriptionmardi 5 juillet 2005StatutMembreDernière intervention 8 février 2009 22 déc. 2007 à 13:24
Modifications effectuées ;)
neigedhiver
Messages postés2480Date d'inscriptionjeudi 30 novembre 2006StatutMembreDernière intervention14 janvier 201119 16 déc. 2007 à 15:43
@Kankrelune : Bravo pour le monologue, j'aurais pas fait mieux.
@The_Magicien : Ben si on poste en commentaire, c'est pour que tu puisses bénéficier des améliorations qu'on propose. Tu ne t'appropries pas notre travail, on te le donne. C'est pas pareil.
Et puis même si tu considères que ce n'est pas toi qui a écrit ce code, il l'a été en tout cas à ton initiative : il ne me serait pas venu à l'idée de me renseigner sur la manière dont vérifier un numéro de série d'un billet Euro, de même qu'il ne me serait pas venu à l'idée non plus d'écrire un code pour le vérifier.
Les commentaires avaient donc pour but de te montrer comment faire plus simple, plus efficace et plus élégant (en plus, là, t'as directement une fonction utilisable dans n'importe quelle application). Ils avaient aussi pour vocation de le montrer à tout le monde.
Tu peux donc sans scrupule l'utiliser. Si tu ne veux pas le mettre à la place de ton code, ce que je peux comprendre, tu peux le mettre à la suite ;)
Mais je t'en prie... On se fout de droits d'auteurs sur des commentaires sur une source ^^
The_magicien
Messages postés72Date d'inscriptionmardi 5 juillet 2005StatutMembreDernière intervention 8 février 2009 14 déc. 2007 à 22:19
@ Evangun : Ce code n'est pas difficile à générer singulièrement. Cependant, si on veut entrer dans l'optique d'un faussaire il veut faire beaucoup d'argent donc si on veut générer des milliers, des millions de numéros de série, ça prend beaucoup plus de temps et c'est plus simple de mettre des numéros complètement aléatoires.
@ Kankrelune et Neigedhiver : Je ne sais pas si je vais faire les modifications parce que sinon, ce ne sera plus le code que moi j'ai fait donc c'est également par respect pour ce que vous m'avez proposé, je ne voudrais pas m'approprier le travail des autres.
Merci pour ces commentaires.
kankrelune
Messages postés1293Date d'inscriptionmardi 9 novembre 2004StatutMembreDernière intervention21 mai 2015 14 déc. 2007 à 15:40
kankrelune
Messages postés1293Date d'inscriptionmardi 9 novembre 2004StatutMembreDernière intervention21 mai 2015 14 déc. 2007 à 12:48
Merde j'avais compris l'exception dans le sens inverse... j'ai rien dis... par contre y a quand même un truc qui cloche car tu exclu des caractère sans spécifier quel caractère peut apparaitre... mieux vaut peut être mettre...
([L-Z^OQW])
je rajouterais un $ à la fin pour bien délimiter la chaine que l'on attend... .. .
La première est un coup plus rapide, un coup plus lente...
kankrelune
Messages postés1293Date d'inscriptionmardi 9 novembre 2004StatutMembreDernière intervention21 mai 2015 14 déc. 2007 à 12:32
([^a-koqw])
>
([a-k^oqw])
sinon c'est marrant pour valider le code d'un billet de banque effectivement... mais ça s'arrête là un billet pouvant bien entendu être faux avec un code valide... .. .
@ tchaOo°
neigedhiver
Messages postés2480Date d'inscriptionjeudi 30 novembre 2006StatutMembreDernière intervention14 janvier 201119 14 déc. 2007 à 02:55
Salut,
Quelques petites améliorations sur les regex : plutôt que d'en faire je ne sais pas combien dans ton script, tu peux te contenter de n'en faire qu'une.
Je crois comprendre à la lecture de ton code qu'un numéro de série est composée d'une lettre entre L et Z inclus, à l'exception de O, Q et W, suivie de 11 chiffres. Une seule regex suffit pour vérifier la validité du numéro et récupérer la lettre et le numéro :
Si le numéro est syntaxiquement correct, $matches est alors un tableau de ce genre :
* [0]=>S15509500765
* [1]=>S
* [2]=>15509500765
$matches[0] est la chaine qui correspond au motif
$matches[1] la lettre, et $matches[2] la série de chiffres.
Déjà, tu économises des perfs (une seule pcre au lieu de 3) et tu gagnes en quantité de code (et donc en lisibilité) : tu n'as plus qu'un seul test qui débouche sur le message d'erreur numéro invalide.
Ensuite, pour la valeur des lettres... Switch n'est pas optimal, puisque le script parcourt toutes les possibilités jusqu'à tomber sur la bonne.
Puisqu'on a utilisé une regex très sévère en terme de filtrage, on sait que la lettre ne peut être qu'une lettre entre L et Z sauf O, Q et W et pas un autre caractère. On peut donc utiliser directement sa valeur ascii :
$pre = ord(strtoupper($matches[1])) - 64;
Ca, c'est fait : une ligne qui te fait économiser 49 lignes de ton switch($letter)
Ensuite, pour concaténer le tout et obtenir un nombre :
$num = (int) ($matches[1] . $matches[2]);
Maintenant, plus qu'à vérifier la validité du numéro :
if ( bcmod($num, "9") == 8)
Ca, c'est beurk. Mettre 9 entre guillemets change son type en chaine de caractères. bcmod, qui opère sur des nombres, va devoir le changer encore en nombre, alors qu'il était déjà dans le bon type.
if (bcmod($num, 9) == 8)
Voilà : 3 lignes au lieu de plusieurs dizaines. T'as gagné tellement de lignes et en lisibilité que tu peux même te permettre d'ajouter des commentaires ^^ Parce que ça manque, et c'est dommage, tu t'es donné la peine de faire un code XHTML 1.0 Transitionnal valide...
Et si tu veux faire encore plus propre, tu peux mettre tout le html à la fin du script, pour bien séparer le traitement de l'affichage.
Encore un dernier détail... Dans un soucis de factorisation (qui consiste à ne pas écrire 2 fois un code identique utilisé à 2 endroits différents) tu peux modifier l'affichage du message final vrai ou faux billet.
Par exemple :
$billet (bcmod($num, 9) 8) ? 'vrai' : 'faux';
Utilise une classe pour la mise en forme de ton texte (et pas un h2 qui sert à identifier un titre, et uniquement à cela, et pas à écrire plus gros);
Et là, tu auras un code php performant, élégant, documenté (si tu mets des commentaires ;) ) et séparé du code html.
Quant au html, en plus d'être valide, il sera aussi sémantiquement correct.
Evangun
Messages postés1980Date d'inscriptiondimanche 20 février 2005StatutMembreDernière intervention24 septembre 20124 14 déc. 2007 à 00:24
Hello,
Je ne connaissais pas ce truc, c'est marrant ! Ceci dit, si j'étais faussaire, je le connaîtrais, et du coup je ferais des numéros corrects :)
22 déc. 2007 à 13:24
16 déc. 2007 à 15:43
@The_Magicien : Ben si on poste en commentaire, c'est pour que tu puisses bénéficier des améliorations qu'on propose. Tu ne t'appropries pas notre travail, on te le donne. C'est pas pareil.
Et puis même si tu considères que ce n'est pas toi qui a écrit ce code, il l'a été en tout cas à ton initiative : il ne me serait pas venu à l'idée de me renseigner sur la manière dont vérifier un numéro de série d'un billet Euro, de même qu'il ne me serait pas venu à l'idée non plus d'écrire un code pour le vérifier.
Les commentaires avaient donc pour but de te montrer comment faire plus simple, plus efficace et plus élégant (en plus, là, t'as directement une fonction utilisable dans n'importe quelle application). Ils avaient aussi pour vocation de le montrer à tout le monde.
Tu peux donc sans scrupule l'utiliser. Si tu ne veux pas le mettre à la place de ton code, ce que je peux comprendre, tu peux le mettre à la suite ;)
Mais je t'en prie... On se fout de droits d'auteurs sur des commentaires sur une source ^^
14 déc. 2007 à 22:19
@ Kankrelune et Neigedhiver : Je ne sais pas si je vais faire les modifications parce que sinon, ce ne sera plus le code que moi j'ai fait donc c'est également par respect pour ce que vous m'avez proposé, je ne voudrais pas m'approprier le travail des autres.
Merci pour ces commentaires.
14 déc. 2007 à 15:40
function validateSerial($num)
{
if(!empty($num) && preg_match('`^([l-npr-vx-z])([0-9]{11})$`i', $num, $matches))
{
return (bcmod(
str_replace(
$matches[1],
ord(strtoupper($matches[1])) - 64,
$matches[0]), '9') === '8');
}
return false;
}
@ tchaOo°
14 déc. 2007 à 15:39
function validateSerial($num)
{
if(!empty($num)|| preg_match('`^([l-npr-vx-z])([0-9]{11})$`i', $num, $matches))
{
return (bcmod(
str_replace(
$matches[1],
ord(strtoupper($matches[1])) - 64,
$matches[0]), '9') === '8');
}
return false;
}
@ tchaOo°
14 déc. 2007 à 13:01
`^([l-npr-vx-z])([0-9]{11})$`i
les deux autre laissent passer des codes invalides... .. .
@ tchaOo°
14 déc. 2007 à 12:52
@ tchaOo°
14 déc. 2007 à 12:51
@ tchaOo°
14 déc. 2007 à 12:51
Et effectivement, mieux vaut spécifier quels caractères afficher, plutôt que ceux à exclure...
Est-ce que l'excuse de l'heure est valable... ?
14 déc. 2007 à 12:48
Voici : http://www.orphyx.net/shortlink.php?l=1
14 déc. 2007 à 12:48
([L-Z^OQW])
je rajouterais un $ à la fin pour bien délimiter la chaine que l'on attend... .. .
function validate($num)
{
if(!empty($num))
{
if(preg_match('~^([L-Z^OQW])([0-9]{11})$~i', $num, $matches))
{
return (bcmod(
(int)str_replace(
$matches[1],
ord(strtoupper($matches[1])) - 64,
$matches[0]), 9) === 8)
}
}
return false;
}
A tester j'ai codé ça en vrac... .. .
@ tchaOo°
14 déc. 2007 à 12:43
([l-z^oqw])
Les deux regex sont à peu près équivalentes :
http://www.lumadis.be/regex/test_regex.php?lang=fr&pat1=%60^([^a-koqw])([0-9]{11})%60i&pat1typ=preg_match&pat2=%60^([^a-koqw])([0-9]{11})%60i&pat2typ=preg_match&txt=S15509500765&result=Ti
La première est un coup plus rapide, un coup plus lente...
14 déc. 2007 à 12:32
>
([a-k^oqw])
sinon c'est marrant pour valider le code d'un billet de banque effectivement... mais ça s'arrête là un billet pouvant bien entendu être faux avec un code valide... .. .
@ tchaOo°
14 déc. 2007 à 02:55
Quelques petites améliorations sur les regex : plutôt que d'en faire je ne sais pas combien dans ton script, tu peux te contenter de n'en faire qu'une.
Je crois comprendre à la lecture de ton code qu'un numéro de série est composée d'une lettre entre L et Z inclus, à l'exception de O, Q et W, suivie de 11 chiffres. Une seule regex suffit pour vérifier la validité du numéro et récupérer la lettre et le numéro :
if (preg_match('`^([^a-koqw])([0-9]{11})`i', $_POST['num'], $matches)) {
// Numéro syntaxiquement valide
}
else {
// Numéro invalide !
}
Si le numéro est syntaxiquement correct, $matches est alors un tableau de ce genre :
* [0]=>S15509500765
* [1]=>S
* [2]=>15509500765
$matches[0] est la chaine qui correspond au motif
$matches[1] la lettre, et $matches[2] la série de chiffres.
Déjà, tu économises des perfs (une seule pcre au lieu de 3) et tu gagnes en quantité de code (et donc en lisibilité) : tu n'as plus qu'un seul test qui débouche sur le message d'erreur numéro invalide.
Ensuite, pour la valeur des lettres... Switch n'est pas optimal, puisque le script parcourt toutes les possibilités jusqu'à tomber sur la bonne.
Puisqu'on a utilisé une regex très sévère en terme de filtrage, on sait que la lettre ne peut être qu'une lettre entre L et Z sauf O, Q et W et pas un autre caractère. On peut donc utiliser directement sa valeur ascii :
$pre = ord(strtoupper($matches[1])) - 64;
Ca, c'est fait : une ligne qui te fait économiser 49 lignes de ton switch($letter)
Ensuite, pour concaténer le tout et obtenir un nombre :
$num = (int) ($matches[1] . $matches[2]);
Maintenant, plus qu'à vérifier la validité du numéro :
if ( bcmod($num, "9") == 8)
Ca, c'est beurk. Mettre 9 entre guillemets change son type en chaine de caractères. bcmod, qui opère sur des nombres, va devoir le changer encore en nombre, alors qu'il était déjà dans le bon type.
if (bcmod($num, 9) == 8)
Voilà : 3 lignes au lieu de plusieurs dizaines. T'as gagné tellement de lignes et en lisibilité que tu peux même te permettre d'ajouter des commentaires ^^ Parce que ça manque, et c'est dommage, tu t'es donné la peine de faire un code XHTML 1.0 Transitionnal valide...
Et si tu veux faire encore plus propre, tu peux mettre tout le html à la fin du script, pour bien séparer le traitement de l'affichage.
Encore un dernier détail... Dans un soucis de factorisation (qui consiste à ne pas écrire 2 fois un code identique utilisé à 2 endroits différents) tu peux modifier l'affichage du message final vrai ou faux billet.
Par exemple :
$billet (bcmod($num, 9) 8) ? 'vrai' : 'faux';
Utilise une classe pour la mise en forme de ton texte (et pas un h2 qui sert à identifier un titre, et uniquement à cela, et pas à écrire plus gros);
echo 'Votre billet est ' . $billet . ' !
';
Dans ton css :
p#resultat {
font-weight: bold;
background-color: transparent;
}
p.vrai {
color: green;
}
p.faux {
color: red;
}
Et là, tu auras un code php performant, élégant, documenté (si tu mets des commentaires ;) ) et séparé du code html.
Quant au html, en plus d'être valide, il sera aussi sémantiquement correct.
14 déc. 2007 à 00:24
Je ne connaissais pas ce truc, c'est marrant ! Ceci dit, si j'étais faussaire, je le connaîtrais, et du coup je ferais des numéros corrects :)