11
votes

Une bonne pratique pour la création d'une pièce d'identité unique non séquentielle non séquentielle

J'ai besoin de créer un identifiant unique pour nos utilisateurs. Je ne veux pas utiliser un identifiant auto_incrimentation, car je ne veux pas que les utilisateurs puissent deviner combien d'utilisateurs nous avons, ou quel est le taux de croissance.

Un UUID n'est pas vraiment une option non plus, car les utilisateurs devront repasser l'ID sur un smartphone.

Donc, j'espère que je peux réduire la base de données de «brute-forcer» autant que possible de trouver des identifiants inutilisés. Quelle serait une façon intelligente d'y aller?

Merci!


3 commentaires

Cet article pourrait vous aider à plus que je pense. Stackoverflow.com/questions/307486/short-unique-id-in-php


«La typabilité humaine» se développera si vous utilisez le motif ([Consontant] [vocal]) * et uniquement de petites lettres.


Pourquoi ne laissez-vous pas l'utilisateur choisir son propre nom d'utilisateur, qui est votre identifiant, ce que vous recherchez? Votre utilisateur peut avoir également d'autres applications sur smartphone, vous le dérangeriez de vous souvenir d'un autre identifiant / mot de passe. Un UUID pourrait être utilisé pour des demandes de repos, car vous ne voudriez pas utiliser l'ID principal de toute communication au client utilisateur ou aux partenaires.


4 Réponses :


4
votes

Vous pouvez créer votre enregistrement et mettre à jour le champ après avec une uide aléatoire sur une fonction. La fonction vérifiera la vérification de l'unicité: xxx

pour les éléments existants, vous pouvez exécuter ceci: xxx

et dans l'instruction insertion que vous avez peut taper ceci: xxx


5 commentaires

Réponse très complète. "Déterministe" est incorrect dans ce cas cependant :)


C'est aussi une approche de force brute .. Mise en œuvre dans SQL PAS PHP, cependant.


Mais il semble également que cette méthode fera réellement brute une solution jusqu'à ce qu'elle trouve un nombre. Cela ne serait pas très bien évolué; Je pense donc que je préférerais une table de semences comme suggérée par @mchl.


Si l'UID de la colonne a un index, la base de données ne fait pas une "force brute", mais une recherche binaire et une échelle beaucoup mieux. Si l'UID de la colonne a une «contrainte unique», vous n'avez qu'à récupérer l'erreur et essayez avec le numéro aléatoire suivant.


aussi la possibilité que l'extérieur tandis que la boucle fonctionne une seconde fois est très très faible



7
votes

Créer une liste de numéros uniqe aléatoires (vous pouvez utiliser la plage PHP () CODE> et shuffle () code> fonctions) et l'avoir stocké dans la base de données ou même dans une TXT déposer. Assurez-vous que la liste est suffisamment longue de manière à durer quelque temps. Ensuite, chaque fois que vous avez besoin d'une nouvelle carte d'identité, affichez simplement la première valeur de la liste.

$list = range(0,999999); //list now contains numbers from 0 to 999999 
// if you ever need to add more ID's to your list, start at 1000000.
shuffle($list); //now it's randomly ordered


5 commentaires

Une extension à ce cas consisterait à mapper l'identifiant généré à l'aide du dictionnaire S / clé pour le rendre vraiment facile à taper (32 bits signifierait 3 mots courts) FAQS.ORG/RFCS/RFC1760.HTML a le dictionnaire.


Solution fraîche et simple, mais la table ne sera pas chevauchée. Qu'est-ce qui se passe sur deux ou plusieurs demandes d'insertion en même temps?


Si vous vous inquiétez de cela, les transactions sont là pour vous.


transactions en combinaison avec des contraintes.


Cela tourne difficile si vous avez près d'un milliard d'identifiants. Par exemple, le fichier pondérera GB.



2
votes

Si je vous comprends correctement, vous essayez de laisser les utilisateurs choisir leur propre identifiant unique d'une table dans laquelle il n'y a pas déjà d'utilisateur enregistré. Si tel est le cas, je disposerais de ma table d'utilisateurs avec des colonnes ID utilisateurId et Nom d'utilisateur. Puis renvoyez les identifiants où l'utilisateur est toujours null.

$query = "SELECT userID, userName FROM User WHERE userName='' AND userID=$userID";
$result=mysql_query($query);

if ($result) {
echo "number is available";
$insert = "UPDATE User
SET userName=$userName
WHERE userID=$userID";

$inserted=mysql_query($insert);
if ($inserted) {
echo "you have been inserted as: ";
echo $userID;
echo $userName;;
}


}


0 commentaires

21
votes

OK, je vais le donner un autre essai. Vos objectifs sont:

  • obfusez le taux d'incrément de votre identifiant - pas séquentiel, pas devinable, pas calculable li>
  • Demandez-le encore "utilisable" pour les utilisateurs de smartphones, ainsi que des utuids longs ou des hachages SHA1 sont hors de portée li>
  • éviter la nécessité de suppositions aléatoires / appels de bruteforce à la base de données li>
  • ont toujours de bonnes performances de base de données avec vos clés étrangères li> ul>

    Pour toujours avoir de bonnes performances dans votre base de données, vous devez conserver un entier standard auto_incrimentation pour votre PK. Notez que Innodb commande les lignes basées sur la PK (voir " InnoDB Index clustered "), donc si vous utilisez une sorte de hachage magique en tant que PK, vous vous retrouverez avec beaucoup de réorganisation de votre indice en cluster, donnant de mauvaises performances d'écriture. P>

    Je suggère d'utiliser un algorithme de chiffrement (cryptage, pas de hachage) pour crypter et décrypter l'ID que vous voulez masquer. De plus, pour la meilleure obfuscation, vous souhaitez utiliser une longueur minimale pour la chaîne résultante. La chaîne résultante doit être toujours utilisable. Vous devez donc utiliser quelque chose comme base64 pour le présenter à l'utilisateur informatique lisible. P>

    Essayez cet exemple de cryptage: P>

    10000 -> 1RXK468NYes -> 10000
    10001 -> QdEov5mjMPA -> 10001
    10002 -> 2gsgzWJgD+8 -> 10002
    10003 -> 2zwPwhqr9HI -> 10003
    10004 -> Xq+kDh1UFuM -> 10004
    10005 -> wfwv6TrW9xY -> 10005
    10006 -> 1Lck1L0HJ/U -> 10006
    10007 -> v+3YY2zfL1A -> 10007
    10008 -> 5AmGlqD8byM -> 10008
    10009 -> pZBIpPnKXHU -> 10009
    10010 -> CAeWdKGkk8c -> 10010
    10011 -> fYddnLOSK6U -> 10011
    10012 -> na8Ry0erHv8 -> 10012
    10013 -> zxNj+ZJVMBY -> 10013
    10014 -> gWJWC9VulZc -> 10014
    10015 -> 5pR9B79eM/E -> 10015
    10016 -> MQtpBhpzHRA -> 10016
    10017 -> dW+3nejBEIg -> 10017
    10018 -> znB/feM6104 -> 10018
    10019 -> RtdRwwRyEcs -> 10019
    10020 -> 4cW/OWT140E -> 10020
    10021 -> dIvK9VjOevg -> 10021
    10022 -> QxLdfrucc/Y -> 10022
    10023 -> M0KN3sX10Gs -> 10023
    10024 -> 827yFJyDCG4 -> 10024
    10025 -> JF/VRj92qL8 -> 10025
    10026 -> IXTvn/SCzek -> 10026
    10027 -> L4nFwvhgwX8 -> 10027
    10028 -> z0lve9nhgDA -> 10028
    10029 -> m/UBgZzfIXo -> 10029
    10030 -> IfWcrLKTHXk -> 10030
    10031 -> n/jPFwKR/9A -> 10031
    10032 -> j1mm2kbeWl0 -> 10032
    10033 -> cm7mOQMVa6k -> 10033
    10034 -> jCUuweEyRME -> 10034
    10035 -> LDaMcOWKxjg -> 10035
    10036 -> Zcrd5XzhhIk -> 10036
    10037 -> j0Yg/fCjyAA -> 10037
    10038 -> /LmlvRHmmmg -> 10038
    10039 -> t0juuzGSKs4 -> 10039
    10040 -> 9CoRCVXaak4 -> 10040
    10041 -> tFmImR4j0JM -> 10041
    10042 -> nI3Thy51hLg -> 10042
    10043 -> mTCJh0/h2mE -> 10043
    10044 -> S196xdyb3Os -> 10044
    10045 -> ItOyUp+J4Q4 -> 10045
    10046 -> DL87SidiOLM -> 10046
    10047 -> d+Nw3xBqV44 -> 10047
    10048 -> 3YzVelaC4uI -> 10048
    10049 -> fAUJVOl6PaU -> 10049
    


5 commentaires

J'aime cette solution, mais la simplicité d'une table de semences m'appelle. Je n'ai pas vraiment besoin de décryptage, car je vais simplement stocker la valeur dans un champ.


@Evert, je voulais juste démontrer une approche évolutive. La simplicité de la table de semences m'appelle aussi. Mais je n'aime pas la nécessité de "re-graine" lorsque la limite supérieure est atteinte. La solution de cryptage est une obfuscation complète 100% et cache également la gamme d'identifiants.


Oui, mais pour ce que ça vaut la peine. Je vous ai fait upvote :) C'est une solution très intelligente.


+ pour une belle fonction de cryptage :)


FWIW: Peut-être qu'il serait préférable d'utiliser la base32 au lieu de la base64. Cela élimine les problèmes de manipulation des humains: pas de sensibilité de cas, aucun caractère ambigieux (0 vs o, 1 vs L), pas de caractères spéciaux, ... mais cela rendra la corde beaucoup plus longue.