Besoin d'une alternative plus petite pour GUID pour DB ID, mais toujours uniques et aléatoires pour les URL
J'ai regardé tous de la place pour cela et je n'arrive pas à obtenir une réponse complète pour cette. Donc, si la réponse existe déjà sur stackoverflow alors je m'excuse à l'avance.
Je veux un unique et ID aléatoire, de sorte que les utilisateurs de mon site web ne peut pas deviner le prochain numéro et juste hop à quelqu'un d'autre information. J'ai l'intention de s'en tenir à une incrémentation de l'ID de la clé primaire, mais aussi de stocker un hasard et de l'IDENTIFIANT unique (sorte de hachage) pour cette ligne dans la base de données et de mettre un index sur elle.
De mes recherches je me rends compte que je tiens à éviter les collisions et j'ai lu quelques mentions de SHA1.
Mes exigences de base sont
- Quelque chose de plus petit qu'un GUID. (Semble horrible dans l'URL)
- Doit être unique
- Éviter les collisions
- Pas une longue liste de personnages étranges qui sont illisibles.
Un exemple de ce que je recherche serait www.somesite.com/page.aspx?id=AF78FEB
Je ne suis pas sûr si je dois être la mise en œuvre de la présente dans la base de données (je suis à l'aide de SQL Server 2005) ou dans le code (je suis à l'aide de C# ASP.Net)
EDIT:
De tous à la lecture, je l'ai fait je me rends compte que c'est la sécurité par l'obscurité. Je compte bien avoir l'autorisation appropriée et d'authentification pour l'accès aux pages. Je vais utiliser .Net de l'Authentification et de l'autorisation-cadre. Mais une fois une légitime utilisateur a ouvert une session et accéder à un legimate (mais créé dynamiquement la page) rempli avec des liens à des objets qui lui appartiennent. Par exemple, un lien peut être www.site.com/page.aspx?item_id=123. Qu'est-ce que l'arrêt lui en cliquant sur ce lien, puis modifier l'URL ci-dessus pour aller www.site.com/page.aspx?item_id=456 ce qui ne lui appartient PAS? Je sais que certaines technologies Java comme Struts (je me tiens à être corrigé) tout stocker dans la session et en quelque sorte de travailler à partir de ça, mais je n'ai aucune idée de comment c'est fait.
Vous devez vous connecter pour publier un commentaire.
[En réponse à l'edit]
Vous devriez envisager de chaînes de requête comme "le mal de l'entrée". Vous avez besoin de programmation pour vérifier que l'utilisateur authentifié est autorisé à voir l'élément demandé.
Raymond Chen a un bon article sur pourquoi vous ne devriez pas utiliser "la moitié d'un guid", et offre une solution adaptée à la production de vos propres "pas tout à fait guid mais assez bon" type de valeur ici:
Sa stratégie (sans implementiation) a été basée sur:
Mise à JOUR (4 Février 2017):
Walter Stabosz découvert un bogue dans le code original. Après enquête il y a d'autres bugs découvert, cependant, de nombreux tests et à retravailler le code par moi-même, l'auteur original (CraigTP) a maintenant résolu tous ces problèmes. J'ai mis à jour le code ici avec la bonne version de travail, et vous pouvez également télécharger Visual Studio 2015 solution ici qui contient le "shortcode" la génération de code et de manière assez complète de la suite de tests pour prouver l'exactitude.
Un mécanisme intéressant que j'ai utilisé dans le passé, c'est en interne, il suffit d'utiliser une incrémentation entier/long, mais à la "carte" qui entier à une alphanumérique "code".
Exemple
Code
Le code suivant montre une classe simple qui va changer une longue d'un "code" (et encore!):
}
C'est essentiellement votre propre baseX système de numérotation (où X est le nombre de caractères dans le shortCode_Keyspace constante.
Pour rendre les choses unpredicable, démarrez votre interne de l'incrémentation de la numérotation à partir d'autre chose que 1 ou 0 (j'.e commencer à 184723) et aussi changer l'ordre des caractères dans le shortCode_Keyspace constante (c'est à dire utiliser les lettres A-Z et les chiffres de 0 à 9, mais scamble leur ordre au sein de la chaîne constante. Cela vous aidera à faire de chaque code quelque peu imprévisible.
Si vous utilisez ce pour "protéger" quoi que ce soit, c'est toujours la sécurité par l'obscurité, et si un utilisateur donné peut observer assez de ces codes générés, ils peuvent prédire le code pertinent pour une longue. La "sécurité" (si on peut appeler ça comme ça) c'est que le shortCode_Keyspace constante est brouillé, et reste secret.
EDIT:
Si vous voulez juste pour générer un GUID, et de le transformer en quelque chose qui est toujours unique, mais contient un peu moins de personnages, cette petite fonction fera l'affaire:
Example
l'article que j'ai ajouté à votre réponse.Si vous ne voulez pas que d'autres utilisateurs de voir des gens de l'information, pourquoi ne pas avoir sécurisé la page que vous êtes en utilisant l'id?
Si vous le faites, alors il n'a pas d'importance si vous utilisez une incrémentation Id.
Vous pourriez générer aléatoirement un nombre. Vérifier que ce numéro n'est pas déjà dans la base de données et l'utiliser. Si vous souhaitez qu'il apparaisse comme une chaîne de caractères aléatoires, vous pourriez convertir en hexadécimal, de sorte que vous obtenez Un F-là, tout comme dans votre exemple.
Un GUID est de 128 bits. Si vous prenez ces morceaux et ne pas utiliser un jeu de caractères avec seulement 16 caractères pour les représenter (16=2^4 et 128/4 = 32 chacters), mais un jeu de caractères avec, disons, de 64 caractères (comme en Base 64), vous vous retrouvez à seulement 22 caractères (64=2^6 et 128/6 = 21.333, donc 22 caractères).
Prendre votre auto-incrément ID, et HMAC-SHA1 avec un secret connu seulement de vous. Cela va générer un hasard-à la recherche de 160 bits qui cachent les vrais ID incrémentielle. Ensuite, prendre un préfixe de longueur qui rend les collisions suffisamment rare pour votre application---dire 64-bits, ce qui peut encoder en 8 caractères. Utiliser ce que votre chaîne.
HMAC permettra de garantir que personne ne peut la carte de bits indiqué retour de la sous-nombre. Par malaxage d'un auto-incrément ID, vous pouvez être sûr qu'il sera unique. Si votre risque de collisions vient de la probabilité d'un 64 bits partielle de collision en SHA1. Avec cette méthode, vous pouvez prédéterminer si vous avez des collisions en pré-production de toutes les chaînes aléatoires que cette méthode qui génèrent (par exemple le nombre de lignes que vous attendez) et de contrôle.
Bien sûr, si vous êtes prêt à spécifier une condition unique sur votre colonne de base de données, puis il suffit de générer de façon totalement aléatoire fonctionnera tout aussi bien. Vous avez juste à être prudent sur la source de l'aléatoire.
Ce que vous pourriez faire est quelque chose que je fais quand je veux exactement ce que vous voulez.
Créer votre GUID.
Obtenir de supprimer les tirets, et d'obtenir un
sous-chaîne de combien de temps vous voulez que votre
ID
Vérifier la base de données pour que l'ID, si elle
existe passez à l'étape 1.
Insérer un enregistrement.
C'est le moyen le plus simple pour s'assurer qu'il est obscurci et unique.
J'ai juste eu une idée et je vois Greg également souligné cela. J'ai de l'utilisateur stocké dans la session avec un nom d'utilisateur. Quand j'ai créer ma requête, je vais rejoindre sur la table des Utilisateurs avec cet ID d'Utilisateur, si l'ensemble est vide, alors nous savons qu'il a été le piratage de l'adresse URL et je peux rediriger vers une page d'erreur.
Un GUID est juste un nombre
La dernière génération de Guid (version 4) est fondamentalement un grand nombre aléatoire*
Parce que c'est un grand de nombre aléatoire les chances de collision sont VRAIMENT petits.
Le plus grand nombre que vous pouvez faire avec un GUID est sur:
Donc si vous générez deux Guid l'occasion de la deuxième GUID est le même que le premier est:
Si vous générez 100 MILLIARDS de Guid.
La chance de votre 100 milliardième GUID entre en collision avec l'autre 99,999,999,999 Guid est:
Pourquoi 128 bits?
L'une des raisons est que les ordinateurs aime travailler avec des multiples de 8 bits.
8, 16, 32, 64, 128, etc
L'autre raison est que le gars qui est venu avec le GUID senti 64 n'était pas assez, et 256 a été de trop.
Avez-vous besoin de 128 bits?
Non, combien de bits dont vous avez besoin dépend du nombre de numéros que vous attendez pour générer et comment sûr que vous voulez être qu'ils n'entrent pas en collision.
64 bits exemple
Puis la chance que votre deuxième numéro d'entrer en collision avec le premier serait:
Au lieu de:
Ce sujet de la 100 milliardième nombre?
La chance de vos 100 milliardième nombre entre en collision avec l'autre 99,999,999,999 serait:
Au lieu de:
Donc, si vous utilisez 64 bits?
Dépend êtes-vous générer 100 milliards de chiffres? Même si vous étiez alors que 180 000 000 de vous faire mal à l'aise?
Un peu plus de détails sur les Guid
Je parle spécifiquement de la version 4.
La Version 4 ne fait pas les utiliser tous les 128 bits pour le nombre aléatoire partie, il utilise 122 bits. Les 6 autres bits sont utilisés pour indiquer qui est la version 4 de le GUID standard.
Les nombres dans cette réponse sont basés sur 122 bits.
Et oui puisque c'est juste un numéro au hasard, vous pouvez simplement prendre le nombre de bits que vous voulez à partir d'elle. (Assurez-vous de ne pas prendre l'une des 6 gestion des versions bits qui ne changent jamais - voir ci-dessus).
Au lieu de prendre des bits à partir de la GUID bien que vous pourriez utiliser à la place la le même générateur de nombres aléatoires le GUID eu de bits à partir de.
Il probablement utilisé le générateur de nombre aléatoire qui est livré avec le système d'exploitation.
Combien de temps est trop long? Vous pouvez convertir le GUID à Base 64, qui finit par rendre tout à fait un peu plus courte.