À court d'id unique en php
Je veux créer un id unique mais uniqid()
est de donner quelque chose comme '492607b0ee414'
. Ce que je voudrais, c'est quelque chose de semblable à ce que tinyurl donne: '64k8ra'
. Plus c'est court, mieux c'est. La seule condition est qu'il ne devrait pas avoir un ordre apparent et qu'il devrait regarder de plus beau qu'un ordre apparemment aléatoire de la séquence de nombres. Les lettres sont privilégiées sur les nombres et, idéalement, il ne serait pas le cas mixte. Comme le nombre d'entrées ne seront pas que de nombreux (jusqu'à 10000 ou) le risque de collision n'est pas un facteur énorme.
Des suggestions apprécié.
- Prendre les 6 premiers caractères?
- Comme uniqid est basé sur l'horodatage les 6 premiers caractères sera la même chose pour un temps assez long 😉 Même si j'ai pris les x derniers caractères ou combiné cela d'une certaine façon, je pense qu'il est toujours plus propre approche. Quelque chose comme "x1f', ce serait bien.
- Avez-vous trouvé une solution? Si oui, de les partager ou de les prix une réponse.
- Ouais, je suis allé avec ce que lpfavreau suggéré, bien qu'un peu modifié. Comme la liste des éléments est assez petite, je peux faire un, en mémoire de vérifier les collisions
Vous devez vous connecter pour publier un commentaire.
Faire une petite fonction qui retourne des lettres aléatoires pour une longueur donnée:
Ensuite, vous aurez envie d'appeler jusqu'à ce que celui-ci est unique, en pseudo-code, selon l'endroit où vous vous souhaitez stocker de l'information:
Vous pourriez aussi vous voulez vous assurer que les lettres ne forment pas un mot dans un dictionnaire. Peut-il être l'ensemble de l'anglais dictionnaire ou juste un mauvais mot dictionnaire pour éviter de choses qu'un client pourrait trouver de mauvais goût.
EDIT: je tiens à ajouter ceci n'a de sens que si, comme vous avez l'intention de les utiliser, ce n'est pas pour un grand nombre d'éléments, car cela pourrait être assez lent le plus de collisions que vous obtenez (obtention d'un IDENTIFIANT déjà dans la table). Bien sûr, vous aurez envie d'un tableau indexé, et vous aurez envie de régler le nombre de lettres dans l'ID pour éviter la collision. Dans ce cas, avec 6 lettres, vous auriez 26^6 = 308915776 possible Identifiants uniques (moins de gros mots) qui devrait être suffisant pour votre besoin de 10000.
EDIT:
Si vous voulez une combinaison de lettres et de nombres, vous pouvez utiliser le code suivant:
ord('a')
etord('z')
à l'extérieur de la boucle, pour éviter l'appel de la fonction à chaque passage.@gen_uuid() par gord.
preg_replace eu une méchante utf-8 problèmes, ce qui provoque l'uid parfois contenir "" + " ou "/".
Pour contourner ce problème, vous devez explicitement de rendre le modèle de l'utf-8
M'a fallu un certain temps pour trouver que c'est peut-être sauve quelqu'un d'autre un mal de tête
Vous pouvez le faire avec moins de code:
Résultat (exemples):
function gen_uid($l=10){ $str = ""; for ($x=0;$x<$l;$x++) $str .= substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyz"), 0, 1); return $str; }
Il y a deux façons d'obtenir un fiable IDENTIFIANT unique: Faire en sorte de long et variable que les chances de collision sont spectaculairement petite (comme avec un GUID) ou de stocker toutes les Id générés dans une table de recherche (que ce soit dans la mémoire ou dans une base de données ou un fichier) pour vérifier l'unicité lors de la génération.
Si vous êtes vraiment vous demandant comment vous pouvez générer une telle courte de la clé et de garantir son unicité, sans une sorte de contrôle de doublon, la réponse est, vous ne pouvez pas.
Voici la routine que j'utilise pour aléatoire base62s de n'importe quelle longueur...
Appel
gen_uuid()
renvoie des chaînes commeWJX0u0jV, E9EMaZ3P
etc.Par défaut ceci renvoie à 8 chiffres, donc un espace de 64^8 soit environ 10^14,
c'est assez souvent de faire des collisions assez rare.
Pour une plus grande ou plus petite chaîne, de passer en $len comme souhaité. Pas de limite en longueur, comme je l'ai ajouter jusqu'à satisfaction [jusqu'à la limite de sécurité de 128 caractères, qui peut être retiré].
Note, utiliser un hasard sel à l'intérieur de le md5 [ou sha1 si vous préférez], de sorte qu'il ne peut pas facilement être de la rétro-ingénierie.
Je n'ai pas trouvé fiable base62 conversions sur le web, d'où cette approche pour le décapage de caractères à partir de la base64 résultat.
Utiliser librement sous la licence BSD,
profiter,
gord
Vraiment la solution la plus simple:
Faire l'ID unique avec:
Obtenir la valeur d'origine de nouveau:
Ne peux pas prendre le crédit pour ce que c'est à partir d'un autre dépassement de la pile de la page, mais j'ai pensé que la solution était si élégant et impressionnant que ça en valait la copie sur ce fil de discussion pour les gens qui font référence à ce.
Vous pouvez utiliser l'Identifiant et le juste de le convertir à la base de 36 nombre si vous voulez à convertir et de l'autre. Peut être utilisé pour n'importe quelle table avec un id de type entier.
Gens intelligents pouvez probablement comprendre avec suffisamment d'id d'exemples. Ne laissez pas cette obscurité remplacer sécurité.
Je suis venu avec ce que je pense est une super solution de le faire sans un contrôle d'unicité. J'ai pensé partager pour tous les futurs visiteurs.
Un compteur est vraiment un moyen facile de garantir l'unicité ou si vous utilisez une base de données d'une clé primaire aussi garantit l'unicité. Le problème est qu'il est mauvais et et pourraient être vulnérables. J'ai donc pris la séquence et mélangées avec un algorithme de chiffrement. Depuis le chiffrement peut être inversé, je sais que chaque id est unique, tout en apparaissant de façon aléatoire.
C'est python pas de php, mais j'ai téléchargé le code ici:
https://github.com/adecker89/Tiny-Unique-Identifiers
Lettres sont jolies, les chiffres sont moches.
Vous voulez des chaînes aléatoires, mais ne veulent pas "moche" des chaînes aléatoires?
Créer un nombre aléatoire et l'imprimer dans alpha-style (de base-26), à l'instar de la réserve "chiffres" que de compagnies aériennes.
Il n'y a pas d'usage général de la base de fonctions de conversion intégré dans PHP, autant que je sache, de sorte que vous aurez besoin de code qui peu vous-même.
Une autre alternative: utiliser
uniqid()
et de se débarrasser des chiffres.Ou de les remplacer par des lettres:
Vous pouvez aussi faire comme tihs:
Vous pouvez le faire sans impur/costy des trucs comme des boucles, des concaténations de Chaîne ou plusieurs appels à rand(), dans un endroit propre et facile à lire. Aussi, il est préférable d'utiliser
mt_rand()
:Si vous avez besoin de la Chaîne pour avoir la longueur exacte dans tous les cas, il suffit de compléter le nombre hexadécimal avec des zéros:
La "théorique backdraw" est, que vous êtes limité à PHPs capacités - mais c'est plus une question philosophique dans ce cas 😉 Let's go à travers elle de toute façon:
$length <= 8
au moins sur un système 32 bits, où PHPs limitation pour ce qui devrait être 4.294.967.295 .mt_rand()
au moins sur un système 32 bits, il devrait être 2.147.483.647Revenir au sujet - l'intuitif
do { (generate ID) } while { (id is not uniqe) } (insert id)
a un inconvénient et un possible défaut qui pourrait vous conduire directement à l'obscurité...Inconvénient: La validation est pessimiste. Le faire comme ceci toujours nécessite un chèque à la base de données. Avoir assez d'espace de clé (par exemple la longueur de 5 pour votre 10k entrées) aura très peu de chances de provoquer des collisions comme souvent, il pourrait être comparable moins coûteuse en termes de ressources à essayer juste pour stocker les données et recommencez seulement dans le cas d'une CLÉ UNIQUE d'erreur.
Défaut: Utilisateur Un récupère un ID qui obtient vérifié que pas encore pris. Puis le code d'essayer d'insérer les données. Mais en attendant, l'Utilisateur B saisi de la même boucle et, malheureusement, récupère le même nombre aléatoire, parce que Utilisateur Un n'est pas sauvegardé et cet ID est toujours libre. Maintenant, le système stocke l'Utilisateur B ou Utilisateur Un, et lorsque vous tentez de stocker le deuxième Utilisateur, il existe déjà de l'autre, dans l'intervalle, - ayant le même ID.
Vous auriez besoin pour gérer cette exception dans tous les cas et de la nécessité de re-tenter l'insertion avec un nouvel ID. L'ajout de cette tout en gardant le pessimiste vérification de la boucle (que vous auriez besoin de re-entrée) aura pour résultat assez moche et difficile à suivre code. Heureusement, la solution à ce problème est le même que celui de l'inconvénient: aller Juste pour elle, en premier lieu, et d'essayer de stocker les données. Dans le cas d'une CLÉ UNIQUE erreur viens de réessayer avec un nouvel ID.
Prendre un lookt à cet article
Il explique comment générer à court d'id uniques de votre bdd en id, comme youtube ne.
En fait, la fonction dans l'article est très liée à fonction php base_convert qui convertit un nombre à partir d'une base à l'autre (mais seulement jusqu'à 36).
Si vous désirez une version plus longue de l'Id unique d'utiliser ceci:
$uniqueid = sha1(md5(time()));
Mieux Encore De Réponse: Plus petit Unique "de Hachage Comme" Chaîne de caractères Donnée Unique ID de Base de données - PHP Solution, Aucun Tiers les Bibliothèques Nécessaires.
Voici le code: