[PHP] Générer un ID unique pas trop long

Fermé
Fornikator - 4 août 2010 à 02:41
 Broum - 15 nov. 2010 à 18:05
Bonjour,

Je crée un script pour minimiser les URL, et donc dans ma table j'ai la table :

Primaire - ID - URL

Primaire : Elle sert pas à gros chose à part rendre fonctionnelle la table (elle est auto-incrémentiel)
ID : C'est l'ID du lien (www.site.com/?u=XXXXXXXXXXXXX) j'utilise un uniqid() en php, il crée 13 caractères mais c''est trop long.
URL : On stock l'URL.

Donc l'ID unique de l'URL est généré par la fonction uniqid() en php, mais elle génère un ID beaucoup trop long pour un minimiseur d'URL.

Comment généré un ID unique mais pas trop long (4-5 caractères) ?

PS : Il est très important que l'ID sois unique sinon il y aura 2 URL avec le même ID et donc le dernier lien minimisé prendra la place de l'ancien.

Merci d'avance.
A voir également:

12 réponses

Nabla's Messages postés 18203 Date d'inscription mercredi 4 juin 2008 Statut Contributeur Dernière intervention 28 avril 2014 3 193
4 août 2010 à 12:06
premier ID:
00001
2° ID
00002 ..
ensuite tu passes a 0000A => 0000Z
et tu recommence à 00010 ....
ca te fait compter en base 36, ca devrait suffir ?
avec 5 caractères, t'as 60 millions de possibiilités
8
HostOfSeraphim Messages postés 6750 Date d'inscription jeudi 2 février 2006 Statut Contributeur Dernière intervention 31 juillet 2016 1 608
Modifié par HostOfSeraphim le 5/08/2010 à 14:33
Une solution :

- Ajouter une colonne "horodatage" qui contient le timestamp du moment de l'enregistrement

- Utiliser cette fonction sur le timestamp :

https://www.php.net/manual/fr/function.uniqid.php#96898

Exemple pour un timestamp à 1281011079 :

<? echo rand_uniqid("1281011079"); ?> // b5ZGyb

Pour retrouver le timestamp depuis le code :

<? echo rand_uniqid("b5ZGyb ", true); ?> // 1281011079

Ca te permet donc d'avoir une chaîne courte, et un horodatage pour trier les entrées de la plus récente à la plus ancienne.


Configuration : Fedora 13 virtualisé sur machine hôte CentOS 5.5 (via VirtualBox)
5
HostOfSeraphim Messages postés 6750 Date d'inscription jeudi 2 février 2006 Statut Contributeur Dernière intervention 31 juillet 2016 1 608
5 août 2010 à 14:37
Du coup la table peut se résumer à deux champs :

- URL (clé primaire)
- Timestamp

Si on essaye de faire un lien pour une URL déjà existante, on ressort le code en utilisant le timestamp enregistré.
0
Alain_42 Messages postés 5361 Date d'inscription dimanche 3 février 2008 Statut Membre Dernière intervention 13 février 2017 894
4 août 2010 à 10:11
tu as le champ Primaire qui est autoincrementé, donc unique, pourquoi ne l'utilises tu pas comme ID ?
0
Alain_42 : Non je préfère pas utiliser ID puisque ça fait 1, 2, 3, 4..... et donc si on a 10 000 liens ça commence à faire vraiment très long, j'aimerais qu'il y ait des lettres.

Nabla's : Oui voila, mais comment faire pour faire comme tu propose ?

J'aimerais que ça génère un code comme pour ce minimiseur : https://tinyurl.com/

Merci
0
Nabla's Messages postés 18203 Date d'inscription mercredi 4 juin 2008 Statut Contributeur Dernière intervention 28 avril 2014 3 193
5 août 2010 à 09:22
comment faire, comment faire... il y a surement plusieurs possibilités. J'ai pas le temps de me pencher dessus, mais a mon avis ca mange pas trop de code.

le truc marant dans la programmation c'est justement la recherche du comment on fait...
pour l'instant, j'ai rien a te livrer de tout pret. Mais la logique est simple, c'est comme compter, sauf que t'utilises des chiffres de 0 à Z au lieu de 0 à 9 !
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Alain_42 Messages postés 5361 Date d'inscription dimanche 3 février 2008 Statut Membre Dernière intervention 13 février 2017 894
5 août 2010 à 13:32
regardes du coté de la fonction php base_convert ça doit répondre à ce que tu recherches

https://www.php.net/manual/fr/function.base-convert.php
0
Nabla's Messages postés 18203 Date d'inscription mercredi 4 juin 2008 Statut Contributeur Dernière intervention 28 avril 2014 3 193
5 août 2010 à 13:36
et ben voila une fonction qui fait exactement ce que je lui proposait ;)
comme quoi j'ai bien fait de pas essayer de la coder ;)
0
Alain_42 Messages postés 5361 Date d'inscription dimanche 3 février 2008 Statut Membre Dernière intervention 13 février 2017 894
5 août 2010 à 13:39
oui par contre il faut qu'il convertisse le champ ID dans une autre base pour avoir des chiffres et des lettres de a à z
0
Nabla's Messages postés 18203 Date d'inscription mercredi 4 juin 2008 Statut Contributeur Dernière intervention 28 avril 2014 3 193
5 août 2010 à 13:58
il peut très bien le convertir en chaine de caractère, et mettre cette chaine en clef primaire. Pas besoin d'ID ...
0
HostOfSeraphim Messages postés 6750 Date d'inscription jeudi 2 février 2006 Statut Contributeur Dernière intervention 31 juillet 2016 1 608
5 août 2010 à 14:01
J'allais le dire. Si la chaîne doit être unique, pas besoin d'un ID supplémentaire qui ne sert à rien.
0
Nabla's Messages postés 18203 Date d'inscription mercredi 4 juin 2008 Statut Contributeur Dernière intervention 28 avril 2014 3 193
5 août 2010 à 14:03
suffit juste de garder un jeton sur la dernière valeur ....
Je sais pas si en SQL on peut retrouver la dernière valeur. En progress, il y a la fonction "find last", mais pour SQL je sais pas ...
0
HostOfSeraphim Messages postés 6750 Date d'inscription jeudi 2 février 2006 Statut Contributeur Dernière intervention 31 juillet 2016 1 608
Modifié par HostOfSeraphim le 5/08/2010 à 14:16
Si il y a un ID, oui :

SELECT * FROM table ORDER BY id DESC LIMIT 1;


Sinon, si c'est une chaîne, il faudrait rajouter un champ d'horodatage et trier sur celui-ci.
0
Alain_42 Messages postés 5361 Date d'inscription dimanche 3 février 2008 Statut Membre Dernière intervention 13 février 2017 894
5 août 2010 à 14:34
début du topic:
Je crée un script pour minimiser les URL, et donc dans ma table j'ai la table :

Primaire - ID - URL

Primaire : Elle sert pas à gros chose à part rendre fonctionnelle la table (elle est auto-incrémentiel)
ID : C'est l'ID du lien ...


donc Primaire existe déja c'est l'identifiant unique autoincrémenté, il suffit de remplir le champ ID avec base_convert( ) du dernier Primaire+1

et le dernier Primaire on peut l'avoir facilement en mysql avec mysql_insert_id()
0
Nabla's Messages postés 18203 Date d'inscription mercredi 4 juin 2008 Statut Contributeur Dernière intervention 28 avril 2014 3 193
5 août 2010 à 15:19
en meme temps, en prenant juste l'ID, tu fais bien tout, pas besoin d'enregistrer le truc converti en base 35, car de toute facon, avec la fonction qu'ono t'a donné, tu pourras toujours retrouver ton bonheur. Pas la peine de charger ta base avec autre chose...
0
Merci pour vos réponses.

J'aime bien la solution de HostOfSeraphim avec le rand_uniqid();.

Mais est ce que le code sera toujours unique, il se répètera jamais ?

Et avec le time(), si deux personne minimise une URL à la même seconde, comment cela ce passe ?
0
Nabla's Messages postés 18203 Date d'inscription mercredi 4 juin 2008 Statut Contributeur Dernière intervention 28 avril 2014 3 193
5 août 2010 à 16:20
le problème avec les solutions dont tu parle, est que vu le nombrede chiffres en jeu, tu aura vite des superpositions... en partant de zero et en incrémentant, tu n'en aura jamais !
0
Oui mais avec l'auto incrémentation c'est trop long après 999999 liens.

1, 2, 3, 4, 5, 6........
0
Nabla's Messages postés 18203 Date d'inscription mercredi 4 juin 2008 Statut Contributeur Dernière intervention 28 avril 2014 3 193
5 août 2010 à 17:10
avec 5 caractères, je t'ai dis que t'avais 60 milliosn de possibilités.. avec ton truc, t'as pareil, sauf que forcement au bout d'un moment, tu vas avoir des entrées non renseignées, et des entrées en double, au bout d'un moment.

Bon, après tu fais ce que tu veux, c'est pas mes liens qui partiront en vrille ;)
0
OK je vais prendre ta technique mais après 60 millions on fait comment ?
Pour ta technique il faut utilisé base_convert() ?
0
Nabla's Messages postés 18203 Date d'inscription mercredi 4 juin 2008 Statut Contributeur Dernière intervention 28 avril 2014 3 193
5 août 2010 à 17:48
oui, la fonction qu'un autre membre a donné plus haut, je croi que c'était ca.

apres 60 millions, tu dois passer a 6 chiffres, mais de toutes facons, l'autre technique n'aurait pas fait mieu que les 60 milions ...

pour trouver 60 millions, j'ai fait:

(10 chiffres + 26 lettres) ^ 5 charactères

ca fait 36 ^ 5 => 60 000 000 environ
0
Alain_42 Messages postés 5361 Date d'inscription dimanche 3 février 2008 Statut Membre Dernière intervention 13 février 2017 894
5 août 2010 à 18:55
une base de données avec 60 millions d'enregistrements ??
0
Oui 60 millions dans une même table, avec des recherche avec WHERE.

Tu peux me montré comment faire en PHP pour ta technique Nabla's, je vois pas trop comment faire même avec base_convert(). Dans l'exemple PHP il y a des 10001011010.....
0
Nabla's Messages postés 18203 Date d'inscription mercredi 4 juin 2008 Statut Contributeur Dernière intervention 28 avril 2014 3 193
6 août 2010 à 09:30
la tout de suite, 'jai pas de serveur web sous la main pour tester.. peut etre ce week end...
0
Nabla's Messages postés 18203 Date d'inscription mercredi 4 juin 2008 Statut Contributeur Dernière intervention 28 avril 2014 3 193
6 août 2010 à 11:31
l'exemple du site, c'est
base_convert($hexadecimal, 16, 2);
pour toi, on passe de base 10 à base 36 ... ca fait:
base_convert($le_nombre, 10, 36);

j'ai pas testé, dis moi si ca marche
0
Oui cela fonctionne ! :

1 => 1
2 => 2
10 => a
11 => b
36 => 10
...

<?php
$hexadecimal = 1;
echo base_convert($hexadecimal, 10, 36);
?>

Cependant on doit faire + 1 ?

Donc, dans le variable hexadecimal, il doit y avoir le nombre auto incrémenté de la dernière entré Primaire de la base de donné ? Mais moi j'enregistre pas de date, donc je ne peux pas avoir le dernier.

En tous cas merci beaucoup !
0
Nabla's Messages postés 18203 Date d'inscription mercredi 4 juin 2008 Statut Contributeur Dernière intervention 28 avril 2014 3 193
8 août 2010 à 12:35
le derniergénéré, c'est le plus élevé.. tu utilises donc un truc du genre
select max(id) from tartiflette;
0
Est-il possible de faire ça avec les lettres majuscules en plus des lettres minuscules ?
0
Nabla's Messages postés 18203 Date d'inscription mercredi 4 juin 2008 Statut Contributeur Dernière intervention 28 avril 2014 3 193
14 nov. 2010 à 14:26
en peut envisager de le faire en base (10+26+26 => 62), mais je sais pas si la fonction va passer ou pas.. on peu encore le faire à la main ..
0
Effectivement la fonction ne prend pas en charge.

Voici l'erreur : Warning: base_convert() [function.base-convert]: Invalid 'to base' (62) in C:\wamp\www\base_convert.php on line 3

Etant novice en PHP, pouvez-vous me communiqué la méthode pour y arrivé ?

Merci d'avance.
0
Nabla's Messages postés 18203 Date d'inscription mercredi 4 juin 2008 Statut Contributeur Dernière intervention 28 avril 2014 3 193
14 nov. 2010 à 22:23
regardes en début de sujet, j'ai donné un peu la démarche..

tu comptes de 0 à 9 puis a à a puis A à Z ....
et ensuite, tu passes à 10 jusqu'à 19 puis 1a jusqueà 1z puis 1A jusqu'à 1Z ....

il faut que tu fasses l'algorythme. J'ai pas le temps dee le faire pour toi s je n'ai pas marqué au dessus... proposes quelques chose, et je t'aiderai à debugger ..
0