7
votes

Générer des caractères alphanumériques alphanumériques uniques de 7 caractères de long

Il n'est pas nécessaire de ne pas être des mots significatifs - plus comme une génération de mots de passe aléatoire, mais la capture est - elles devraient être uniques. Je vais utiliser ceci pour une sorte de package / code de produit. Quelle est la meilleure méthode disponible? :)


9 commentaires

Pourquoi vos mots de passe doivent-ils être uniques?


Il / elle a dit "comme des mots de passe", pas des "mots de passe". Pour autant que je sache, c'est un code de produit et ceux qui doivent certainement être uniques.


Sidenote mineur: Si vous donnez ces codes aux utilisateurs, soyez conscient que vous allez finalement donner un code qui lit «F * ckyou»


@nickf: bon point. J'ai eu une fonction qui a généré des consonnes et des voyelles alternativement, je l'utilisais pour alimenter des cordes CAPTCHA 5 ... Pendant les tests, j'en ai eu un qui a dit Merda (traduction = SH t ) et un client aîné a un peu en colère parce qu'il en a eu un qui a dit celui qui a déclaré FODER (traduction = à f ck ) ...


Echo Base_Convert ('34486853790', 10, 36);


@Alix Ce que j'ai fait dans le passé quand j'avais besoin d'un générateur de mot de passe est comme la réponse de Jon avec la chaîne $ autorisée_chars , mais supprimé toutes les voyelles, ainsi que des caractères pouvant être mal interprétés comme d'autres caractères: < Code> 1, l, 0


@NICKF: Le truc est que les voyelles sont cruciales si vous souhaitez générer des mots de passe mnémoniques, il est plus facile de rappeler generatino que gnrtnpcgkf par exemple. J'ai fini par vérifier si la chaîne générée contenait des mots "sale" ( en.wikipedia.org/wiki/seven_dirty_words ).


@Alix, eh bien oui, je suppose que cela dépend de la quantité que vous souhaitez éviter d'insulter vos utilisateurs. Même avec une profanité Filtrer des variations mineures et ainsi de suite. Si vous vouliez faire un mot prononcable, aucune des méthodes ne s'appliquerait de toute façon.


Supprimer les voyelles est une bonne idée d'empêcher de générer un mot significatif


15 Réponses :


0
votes

Étant donné que vous mentionnez des mots de passe ici, je suppose que vous avez besoin d'une méthode sécurisée (c'est-à-dire: une personne ne devrait pas être capable de deviner le mot de passe de quelqu'un d'autre en connaissant un autre mot de passe). Vous pouvez utiliser ce qui suit:

  1. Décidez d'un mot de passe principal, par exemple "MasterPassword"
  2. Pour chaque mot de passe généré, appendez-le à celui d'une ou séquentielle nonce , par exemple "MasterPassword1", "MasterPassword2".
  3. Effectuez un hachage cryptographique sur celui (SHA, MD5, etc.) et secouez le hachage à une représentation hexadécimale, par exemple "CE7F181A44A4A5B7E43FE2B9A0B1F0C1".
  4. tronquez-le à autant de caractères que vous en avez besoin - peut-être sept comme vous avez indiqué: "CE7F181".
  5. Vérifiez si cela a été attribué avant. Sinon, renvoyez cela comme mot de passe. Sinon, répétez de 2.

    Si la sécurité n'est pas un problème, les étapes 1 et 2 seront en elles-mêmes suffisantes. Si la sécurité est un problème, il est essentiel que personne ne connaisse vous-même la valeur de «MasterPassword».


6 commentaires

Je ne suis pas grand dans Crypto, je ne peux donc pas mettre des mots à mon inconfort avec cette idée ... mais cela me met mal à l'aise. Vous avez réduit les possibilités en allant avec base16 au lieu de, par exemple, base-26 + 26 + 10; De plus (devinez ici) Vous compromettez l'intégrité d'un hachage lorsque vous le tronquez. J'admets, cependant, l'exigence d'un mot de passe unique est un peu étrange, aussi ...


Convenu sur tous les points. Je concéderai volontiers le point concernant l'hexagone, vous avez raison que les plus potentiels personnages sont meilleurs. Également convenu sur la troncature, mais nécessitant des mots de passe de 32 caractères (ou pire), il est inévitable. En outre, le hachage est plus utilisé comme moyen de générer un mot de passe hautement unique, étant donné une base similaire à d'autres mots de passe que comme une mesure de sécurité. Vraiment, un hachage non-crypto ou peut-être un CRC pourrait également être utilisé, sauf que cela rend le mot de passe principal plus vulnérable.


Les hachages cryptographiques ne sont pas uniques. Ils sont définitivement pas uniques si vous les tronquez. Cette méthode n'a vraiment aucun avantage pour générer simplement des chaînes aléatoires et vérifier ces pour voir s'ils ont été attribués.


P.s. Et je suis [un peu] gros dans la crypto, je peux donc mettre en mots mon inconfort avec cette idée. ;)


Ok, j'ai mal formulé ma réponse ci-dessus. Je n'ai jamais voulu impliquer que le hash serait unique, simplement qu'il était très susceptible d'être unique. Si la sécurité est requise, cette méthode présente les avantages de cette méthode par rapport à un générateur de chaîne aléatoire non cryptographique - il est (de manière provoquément) plus difficile pour un attaquant d'ingénierie inverse un mot de passe de l'autre utilisateur particulier des mots de passe générés. Vous auriez le regarder essentiellement comme une génération de caractère à l'aide d'un PRNG cryptographique (le hash), auquel cas il y a une petite différence entre cette réponse et d'autres.


vraiment mal formulé ce commentaire, maintenant que je l'ai relu ...;)



6
votes

Il n'est généralement pas possible de générer des séquences avec des éléments uniques et aléatoires: évidemment être unique, l'algorithme doit prendre en compte les éléments générés précédemment dans la séquence, les suivants ne seront donc pas vraiment aléatoires.

Par conséquent, votre meilleur pari serait de détecter les collisions et de réessayer simplement (ce qui pourrait être très coûteux dans votre cas particulier).

Si vous êtes contraint de seulement 7 caractères, il n'y a pas grand chose que vous puissiez faire ci-dessus: xxx

Cela devrait éventuellement vous donner un nouveau mot de passe.

Cependant, dans des cas similaires, j'ai rencontré, je choisis habituellement une taille de mot de passe plus grande qui arrive également à être le Taille de la représentation hexagonale d'une fonction de hachage populaire (par exemple, MD5 ). Ensuite, vous pouvez le rendre plus facile sur vous-même et moins d'erreur sujette: xxx

Ceci a également l'avantage supplémentaire que l'espace de séquence est plus grand, il y aura donc moins de collisions. Vous pouvez choisir la taille de la fonction de hachage en fonction des numéros attendus de mots de passe que vous générerez à l'avenir pour "garantir" une probabilité de collision faible et donc moins d'appels vers la fonction éventuellement chère déjà_exists .


1 commentaires

'Alphanumérique' implique que vous aurez besoin de 0 ... 9 dans votre variable $ autorisée_chars :)



0
votes

Voici comment je résous ce problème:

Considérez que les 7 caractères peuvent être l'une des 26 lettres (ABC..Z) ou 10 numéros (01 ... 9). Cela fait 36 ​​caractères possibles.

Chaque fois que votre application génère un nouveau code, demandez-lui une variable globale. Vous pouvez transformer ce numéro unique en une chaîne unique à l'aide d'un convertisseur «hexatridecimal» et en ajoutant des caractères de remplissage pour constituer le reste de la chaîne.

Regardez ce lien. Je pense que ce gars avait le même problème que vous: http://www.codemaxima.com/2010/04/Le -Hexatridecimal-numéroting-system /


0 commentaires

0
votes
$random = substr(hash('md5',openssl_random_pseudo_bytes(32)),0,7);

0 commentaires

1
votes

Voici une façon de le faire sans hachage ou boucles: xxx

Comme quelques autres personnes ont mentionné, garantissant l'unicité est plus compliquée et devrait être inutile. La manière la plus simple que vous puissiez le faire serait d'ajouter des caractères supplémentaires à la fin, d'incrémenter avec chaque mot de passe généré.


0 commentaires

1
votes

Voici quelque chose qui semble aléatoire et doit être unique et avoir 7 caractères pour les temps à venir:

xxx

ou pour un peu plus aléatoire et moins unicité (entre 1000 et 10000 par seconde) : xxx

ou (unicité entre 100 et 10000 par seconde) - C'est probablement la meilleure option: xxx

ou (unicité entre 10 et 10000 par seconde): xxx

Vous avez l'idée.


1 commentaires

prudent de débordement entier ici. Intval (Microtime (True) * 10000) == -65867797 - Cela vous donne une sortie de 6 caractères.




-1
votes

Heres un moyen très simple xxx

Vous devrez mettre en œuvre votre propre fonction check_unique. Cette partie devrait être facile.


0 commentaires

0
votes

+1 au commentaire de @Michael Haren. Si les mots de passe sur votre site ne doivent pas avoir de contrainte pour être uniques.

Si j'essaie d'utiliser un mot de passe donné et que je reçois une erreur que je ne peux pas l'utiliser car elle est déjà utilisée, je sais que certains utilisateurs du système ont ce mot de passe. S'il y a 1000 utilisateurs, je n'ai besoin que d'essayer un max de 1000 autres comptes avant de trouver celui qui a ce mot de passe.

Ne répondez pas vraiment à votre question, mais plus qu'un commentaire. Donc, je marquais ce cw.


2 commentaires

Je crois que le terme "génération de mot de passe" était un exemple, je pense qu'il souhaite générer des codes de produit.


@Alix: Merci, je n'ai pas lu la question assez près. Ma faute! Je vais laisser mon CW réponse ici afin que les lecteurs qui envisagent de forcer les mots de passe à être uniques puissent voir le contre-argument.



1
votes

Un alphanumérique aléatoire aléatoire (base 36 = 0..9 + a..z code>) La valeur qui contient 7 caractères doit avoir une représentation de base 10 entre 2176782336 code > et 78364164095 code> strong>, l'extrait suivant le prouve: xxx pré>

afin que celui-ci soit unique, nous devons compter sur un facteur non répété, Le choix évident est temps () code>: p> xxx pré>

Si nous voulions seulement assurer un facteur d'unicité minimal de 1 code unique par seconde que nous pourrions faire: p> xxx pré>

Vous remarquerez que ces codes ne sont pas aléatoires, vous remarquerez également que temps () code> ( 1273508728 code>) est inférieur à 2176782336 code> (la base minimale de la base 10 d'un code de caractère 7), c'est pourquoi je fais heure () * 2 p> P> P> P> P> P> P> P> P> P> P> P> P> P> > Permet maintenant de faire quelques mathématiques afin d'ajouter au hasard et d'augmenter le facteur d'unicité tout en respectant les limitations entier des anciennes versions de PHP ( ?): P>

base_convert(mt_rand(122, 782) . substr(number_format(microtime(true), 1, '', ''), 3), 10, 36);


4 commentaires

Pourquoi commencez-vous par 1000000 et non 0000000 ?


@sawa: Avez-vous lu la question et le premier paragraphe de ma réponse?


Ma question a été adressée à votre premier paragraphe. Vous le prouvez, avec 1000000 Intérieur var_dump (base_convert ('1000000', 36, 10)); au lieu de 0000000. Je demande pourquoi? La question est de demander une chaîne. Pourquoi une chaîne ne peut-elle pas commencer par "0"?


@sawa: Eh bien, vous pourriez, mais vous devriez alors le rendre avec 0. Je suppose que je n'ai pas mentionné que parce que l'horodatage n'aura jamais ce genre de faible valeur.



0
votes
md5( microtime() );

0 commentaires

0
votes

La réponse de Galen n'autorise qu'une seule utilisation de chaque caractère du mot de passe. Pas beaucoup d'informations dans cette chaîne. Un changement simple si: xxx


0 commentaires

1
votes

C'est ma façon préférée de le faire. XXX

Uniqid utilise l'heure actuelle pour générer une chaîne aléatoire très unique. Les résultats ressemblent à "3f456yg".


0 commentaires

0
votes
substr(str_shuffle(md5(microtime())),rand(0,21),7);

0 commentaires

0
votes

Essayez ceci xxx

il donnera une chaîne de longueur 5.


0 commentaires