Je travaille avec une API qui veut que je produise des "identifiants de référence" opaques pour les transactions avec leur API, c'est-à-dire des références uniques que les utilisateurs ne peuvent ni supposer ni déduire de quelque manière que ce soit. (Est-ce que «Infer 'est bon anglais?)
C'est ce que j'ai piraté ensemble: p> Malheureusement, ma base de données ne semble pas manquer des transactions pour le moment. J'ai réalisé que ma méthode n'est pas particulièrement sûre en sécurité (disons que je suis en train d'exécuter le même code Django sur plusieurs threads Apache mod_wsgi, ils pourraient tous générer le même RandomRef!) P> a-t-il eu un Trick plus agréable pour générer des clés primaires aléatoires pour moi? p> p>
6 Réponses :
Pourquoi ne pas simplement chiffrer les identifiants séquentiels normaux à la place? À quelqu'un qui ne connaît pas la clé de cryptage, les identifiants sembleront aussi aléatoires. Vous pouvez écrire une enveloppe qui déchiffre automatiquement l'identifiant sur le chemin de la DB et la crypte sur le chemin de la DB. P>
C'est une bonne idée, merci. J'ai envisagé de haquer une combinaison de transaction userid et standard.Id, mais ce n'est pas garanti d'être unique non plus. Pouvez-vous suggérer une bonne fonction Python pour chiffrer? J'ai installé M2Crypto comme condition préalable à un autre paquet, mais pas encore vraiment l'utiliser.
Désolé @Alexbliskovsky, je suis un crypto n00b. Existe-t-il un moyen de spécifier la sortie cryptée à un petit entier? Est-il possible de conceptuellement (pour qu'il n'y ait aucune collision à moins que nous assurons que le domaine du texte brut est inférieur au domaine du texte crypté)?
Stackoverflow.com/questions/4028998/...
Vous devriez être capable de définir la colonne TransACACeRef dans votre base de données pour être unique. De cette façon, la base de données n'autorisera pas les transactions à ajouter avec la même valeur transacalref. Une possibilité est de générer de manière aléatoire UUIDS - la probabilité d'uuides aléatoires en collision est extrêmement petit. p>
Les entiers aléatoires ne sont pas uniques et les clés primaires doivent être uniques. Faites le champ clé un char (32) et essayez cela à la place: Uuids sont très bons à la fourniture d'unicité. P> p>
Deux Uuids générés par UUID4 ne sont pas garantis d'être uniques, il n'y a qu'une chance extrêmement faible (mais non nulle) d'une collision.
Merci, je n'ai jamais entendu parler d'Uuids avant, ils semblent beaucoup plus agréables que mon actuel Randint. Devrais-je toujours exécuter des choses à travers une boucle pour vous assurer que l'UUID n'est pas utilisée?
Votre couche de base de données organisera une exception si vous essayez d'insérer une clé non unique. Vous pouvez attraper cette exception et faire une autre uuid. Bien que quand je l'ai posté, je pensais que c'était une bonne réponse, Alex Martelli et Ambre ont donné de meilleures suggestions si vous pouvez les mettre en œuvre.
L'utilisation d'un champ de charret pour une clé primaire ne ressemble pas à une bonne idée.
J'ai créé un gist basé sur cette question: https://gist.github.com/735861
Suivre les conseils d'Amber, les clés privées sont cryptées et déchiffrées à l'aide de DES. La clé cryptée est représentée dans la base 36, mais toute autre représentation basée sur le caractère fonctionnera tant que la représentation est unique. P>
Tout modèle qui aurait besoin de ce type de représentation de clé privée cryptée dont il suffit d'hériter de Le modèle et le gestionnaire présenté dans le code. p>
Voici la viande du code: p> pour une transaction code> objet code> Il convient de noter que ce code n'assume que des clés privées que peut être représenté correctement comme des valeurs longues. p> p> transaction code>,
transaction.rypted_pk code> retournerait une représentation cryptée de la clé privée.
transaction.objects.get (chiffrété_pk = one_value) code> rechercherait des objets en fonction de la représentation de la clé privée cryptée. p>
jbrendel a créé une classe que vous pouvez simplement hériter pour obtenir un identifiant personnalisé. p>
Il ne semble pas fonctionner avec Django Admin. Cela ne me laissera pas économiser un nouvel enregistrement avec un identifiant vierge car c'est un champ obligatoire; Si je définis un identifiant, le aléatoire n'est pas généré. Cela n'a peut-être pas seulement travaillé dans une précédente version Django?
@sherbang pour le faire fonctionner avec admin, il suffit de modifier si auto.Id: code> partie. Si vous regardez de près les commentaires, il est dit "# Apparemment, nous connaissons notre identifiant déjà, donc nous n'avons pas à # faire quelque chose de spécial ici."