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

Fornikator -  
 Broum -
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   Statut Contributeur Dernière intervention   3 193
 
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   Statut Contributeur Dernière intervention   1 608
 
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   Statut Contributeur Dernière intervention   1 608
 
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   Statut Membre Dernière intervention   894
 
tu as le champ Primaire qui est autoincrementé, donc unique, pourquoi ne l'utilises tu pas comme ID ?
0
Fornikator
 
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   Statut Contributeur Dernière intervention   3 193
 
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   Statut Membre Dernière intervention   894
 
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   Statut Contributeur Dernière intervention   3 193
 
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   Statut Membre Dernière intervention   894
 
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   Statut Contributeur Dernière intervention   3 193
 
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   Statut Contributeur Dernière intervention   1 608
 
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   Statut Contributeur Dernière intervention   3 193
 
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   Statut Contributeur Dernière intervention   1 608
 
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   Statut Membre Dernière intervention   894
 
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   Statut Contributeur Dernière intervention   3 193
 
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
Fornikator
 
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   Statut Contributeur Dernière intervention   3 193
 
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
Fornikator
 
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   Statut Contributeur Dernière intervention   3 193
 
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
Fornikator
 
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   Statut Contributeur Dernière intervention   3 193
 
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   Statut Membre Dernière intervention   894
 
une base de données avec 60 millions d'enregistrements ??
0
Fornikator
 
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   Statut Contributeur Dernière intervention   3 193
 
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   Statut Contributeur Dernière intervention   3 193
 
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
Fornikator
 
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   Statut Contributeur Dernière intervention   3 193
 
le derniergénéré, c'est le plus élevé.. tu utilises donc un truc du genre
select max(id) from tartiflette;
0
Broum
 
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   Statut Contributeur Dernière intervention   3 193
 
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
Broum
 
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   Statut Contributeur Dernière intervention   3 193
 
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