Bonjour
Je cherche une librairie existante qui permet de générer des GUID. C'est-à-dire un générateirs d'identifiants uniques.
J'ai regardé du coté de jakartans commons mais j'ai rien toruvé
Merci
Pierre
Version imprimable
Bonjour
Je cherche une librairie existante qui permet de générer des GUID. C'est-à-dire un générateirs d'identifiants uniques.
J'ai regardé du coté de jakartans commons mais j'ai rien toruvé
Merci
Pierre
En cherchant sur le net tu devrais trouver des algos en pseudo code pour écrire la fonction qui n'est pas très compliquée.
Le principe est en général le suivant (mais cela peut varier, il existe plusieurs solutions) : ton GUID doit comprendre:
1 - l'adresse IP ou MAC de la machine sous forme numérique
2 - un timestamp
3 - le code de hashage du thread appelant
4 - un nombre aléatoire
1) permet que le GUID dépende de la machine, ainsi dans une architecture distribuée tu peux avoir 2 appels simultanés à la méthode sur 2 machines distinctes
2) variation temporelle du GUID pour que 2 appels successifs mais avec un timestamp différent soient distincts
3) dans un système multi-threadé on peut avoir des appels très rapprochés. Ce champ permet de traiter le cas (très improbable) de 2 appels ayant le même timestamp
4) et pour paufiner le tout un nombre aléatoire. Il présente son utilité pratiquement que dans le cas où l'on arrive par à récupérer le champ 1 (ça m'est arrivé de toujours récupérer l'IP 127.0.0.1 8O )
Voilà il ne reste plus qu'à coder. Par contre cela génrère des ID de taille respectable :lol:
Jacques Desmazières
Et le java.util.UUID ? :mouarf:
Merci Jacques pour la réponse, je savais un peu l'algo a suivre pour générer le GUID mais ton explication est excellente!
Par contre, je cherche vraiment une librairie existante qui ferait le travail a ma place :)
Pour ce qui est de UUID.. je suis en java 1.4 donc ce n'est pas une solution :(
Apparemment cela existe dans les librairies apache mais peut être pas en tant que librairie utilitaire en dehors d'un projet:
http://mail-archives.apache.org/mod_...@collab.net%3E
Sinon dans la sandbox Jakarta
http://jakarta.apache.org/commons/sandbox/id/
Jacques Desmazières
ok merci
sinon est-ce que tu as un bout de code à me donner pour générer le GUID?
Merci encore
Voilà, j'utilise dans mes applis la méthode getGUID, mais j'ai laissé le code pour getUUID, mais je ne l'ai pas testée à fond.
(ceci n'est qu'un extrait d'une classe plus complexe, il peut donc manquer des imports ou d'autres petites choses)
Jacques DesmazièresCode:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129 import java.net.InetAddress; import java.rmi.server.UID; import java.security.SecureRandom; /** * Cette classe gère la génération de GUID (Global Unique IDentifier) * <BR> * Cette classe traite deux problèmes de la génération d'identifiants uniques * <LU> * <LI> la génération de GUID * <LI> la performance * </LU> * <HR> * Cette classe propose deux implémentations du générateur (méthodes statiques) * <LU> * <LI> getUUID : génère un identifiant sur 36 caractères basé sur l'objet java.rmi.server.UID * <LI> getGUID : génère un identifiant sur 36 caractères basé sur la publication * "UUID and GUID Internet standards draft for the Network Working Group by Paul J. Leach, Microsoft, and Rich Salz, Certco" * </LU> * Les performances de ces deux méthodes sont très proches (getUUID étant très légèrement plus rapide) * Par contre, il n'est pas certain que getUUID soit conforme à J2EE * Donc utiliser de préférence getGUID * <HR> * * @author Jacques * Creation date: (28/03/2001) */ public abstract class GuidGenerator { private static String hexInetAddress = "10203040"; private static String formatedInetAddress = "-1020-3040"; private static byte[] bytes = { 16, 32, 48, 64 }; private static SecureRandom seeder = new SecureRandom(); static { try { seeder.nextLong(); bytes = InetAddress.getLocalHost().getAddress(); StringBuffer tmpBuffer = new StringBuffer(); for (int pos = 0; pos < bytes.length; pos++) { String tmp = Long.toHexString(seeder.nextLong()) + Long.toHexString(bytes[pos]); tmpBuffer.append(tmp.substring(tmp.length() - 2)); } hexInetAddress = tmpBuffer.toString(); tmpBuffer = new StringBuffer(); tmpBuffer.append("-"); tmpBuffer.append(hexInetAddress.substring(0, 4)); tmpBuffer.append("-"); tmpBuffer.append(hexInetAddress.substring(4)); formatedInetAddress = tmpBuffer.toString(); } catch (Exception uhe) { throw new RuntimeException(uhe); } } /** * getGUID retourne un identifiant unique sous forme d'une chaine de 36 caractères. * <BR> * format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx * (1-8 hex characters) time uniqueness (system clock) * (9-16 hex characters) spatial uniqueness (IP address) * (17-24 hex characters) object uniqueness (replace singleton) * (25-36 hex characters) random uniqueness * <BR> * <HR> * Creation time: (3/28/01 11:32:46 AM) * @author jacques * @return String */ public static String getGUID() { StringBuffer tmpBuffer = new StringBuffer(); // 1-8 hex characters String time = Long.toHexString(System.currentTimeMillis() & 0xFFFFFFFF); tmpBuffer.append(time.substring(time.length() - 8)); // 9-16 hex characters tmpBuffer.append(formatedInetAddress); // 17-24 hex characters tmpBuffer.append("-"); String tmp = "0000" + Long.toHexString(tmpBuffer.hashCode()); tmpBuffer.append(tmp.substring(tmp.length() - 4)); // 25-36 hex characters tmpBuffer.append("-"); tmp = "000000000000" + Long.toHexString(seeder.nextLong()); tmpBuffer.append(tmp.substring(tmp.length() - 12)); return tmpBuffer.toString(); } /** * getGUID retourne un identifiant unique sous forme d'une chaine de 36 caractères. * <BR> * Cette méthode est basée sur la génération d'identifiant par java.rmi.server.UID * format: xxxxxxxx-xxxx:xxxxxxxxxx:xxxxxxxxxxx * <BR> * <HR> * Creation time: (3/28/01 11:32:46 AM) * @author jacques * @return String * @exception */ public static String getUUID() { StringBuffer tmpBuffer = new StringBuffer(); String tmp = null; tmpBuffer.append(hexInetAddress); tmpBuffer.append("-"); tmp = "00000000" + (new UID()).toString(); tmpBuffer.append(tmp.substring(tmp.length() - 21)); long node = seeder.nextLong(); tmp = "000000" + Long.toHexString(node); tmpBuffer.append(tmp.substring(tmp.length() - 6)); return tmpBuffer.toString(); } }
J'utilise dans une application (qui etait basée initialement sur du 1.4) une classe trouvée sur le web:
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211 package xxxxxxxxxxxxxxxx; /* * RandomGUID * @version 1.2 01/29/02 * @author Marc A. Mnich * com.brightobject.util.guidgenerator.util; * * From www.JavaExchange.com, Open Software licensing * * 01/29/02 -- Bug fix: Improper seeding of nonsecure Random object * caused duplicate GUIDs to be produced. Random object * is now only created once per JVM. * 01/19/02 -- Modified random seeding and added new constructor * to allow secure random feature. * 01/14/02 -- Added random function seeding with JVM run time * */ import java.net.*; import java.security.*; import java.util.*; /* * In the multitude of java GUID generators, I found none that * guaranteed randomness. GUIDs are guaranteed to be globally unique * by using ethernet MACs, IP addresses, time elements, and sequential * numbers. GUIDs are not expected to be random and most often are * easy/possible to guess given a sample from a given generator. * SQL Server, for example generates GUID that are unique but * sequencial within a given instance. * * GUIDs can be used as security devices to hide things such as * files within a filesystem where listings are unavailable (e.g. files * that are served up from a Web server with indexing turned off). * This may be desireable in cases where standard authentication is not * appropriate. In this scenario, the RandomGUIDs are used as directories. * Another example is the use of GUIDs for primary keys in a database * where you want to ensure that the keys are secret. Random GUIDs can * then be used in a URL to prevent hackers (or users) from accessing * records by guessing or simply by incrementing sequential numbers. * * There are many other possiblities of using GUIDs in the realm of * security and encryption where the element of randomness is important. * This class was written for these purposes but can also be used as a * general purpose GUID generator as well. * * RandomGUID generates truly random GUIDs by using the system's * IP address (name/IP), system time in milliseconds (as an integer), * and a very large random number joined together in a single String * that is passed through an MD5 hash. The IP address and system time * make the MD5 seed globally unique and the random number guarantees * that the generated GUIDs will have no discernable pattern and * cannot be guessed given any number of previously generated GUIDs. * It is generally not possible to access the seed information (IP, time, * random number) from the resulting GUIDs as the MD5 hash algorithm * provides one way encryption. * * ----> Security of RandomGUID: <----- * RandomGUID can be called one of two ways -- with the basic java Random * number generator or a cryptographically strong random generator * (SecureRandom). The choice is offered because the secure random * generator takes about 3.5 times longer to generate its random numbers * and this performance hit may not be worth the added security * especially considering the basic generator is seeded with a * cryptographically strong random seed. * * Seeding the basic generator in this way effectively decouples * the random numbers from the time component making it virtually impossible * to predict the random number component even if one had absolute knowledge * of the System time. Thanks to Ashutosh Narhari for the suggestion * of using the static method to prime the basic random generator. * * Using the secure random option, this class compies with the statistical * random number generator tests specified in FIPS 140-2, Security * Requirements for Cryptographic Modules, secition 4.9.1. * * I converted all the pieces of the seed to a String before handing * it over to the MD5 hash so that you could print it out to make * sure it contains the data you expect to see and to give a nice * warm fuzzy. If you need better performance, you may want to stick * to byte[] arrays. * * I believe that it is important that the algorithm for * generating random GUIDs be open for inspection and modification. * This class is free for all uses. * * * - Marc */ public class RandomGUID extends Object { private static Random myRand; private static SecureRandom mySecureRand; /* * Static block to take care of one time secureRandom seed. * It takes a few seconds to initialize SecureRandom. You might * want to consider removing this static block or replacing * it with a "time since first loaded" seed to reduce this time. * This block will run only once per JVM instance. */ static { mySecureRand = new SecureRandom(); long secureInitializer = mySecureRand.nextLong(); myRand = new Random(secureInitializer); } public String valueBeforeMD5 = ""; public String valueAfterMD5 = ""; /* * Default constructor. With no specification of security option, * this constructor defaults to lower security, high performance. */ public RandomGUID() { getRandomGUID(false); } /* * Constructor with security option. Setting secure true * enables each random number generated to be cryptographically * strong. Secure false defaults to the standard Random function seeded * with a single cryptographically strong random number. */ public RandomGUID(boolean secure) { getRandomGUID(secure); } /* * Method to generate the random GUID */ private void getRandomGUID(boolean secure) { MessageDigest md5 = null; StringBuffer sbValueBeforeMD5 = new StringBuffer(); try { md5 = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { System.out.println("Error: " + e); } try { InetAddress id = InetAddress.getLocalHost(); long time = System.currentTimeMillis(); long rand = 0; if (secure) { rand = mySecureRand.nextLong(); } else { rand = myRand.nextLong(); } // This StringBuffer can be a long as you need; the MD5 // hash will always return 128 bits. You can change // the seed to include anything you want here. // You could even stream a file through the MD5 making // the odds of guessing it at least as great as that // of guessing the contents of the file! sbValueBeforeMD5.append(id.toString()); sbValueBeforeMD5.append(":"); sbValueBeforeMD5.append(Long.toString(time)); sbValueBeforeMD5.append(":"); sbValueBeforeMD5.append(Long.toString(rand)); valueBeforeMD5 = sbValueBeforeMD5.toString(); md5.update(valueBeforeMD5.getBytes()); byte[] array = md5.digest(); StringBuffer sb = new StringBuffer(); for (int j = 0; j < array.length; ++j) { int b = array[j] & 0xFF; if (b < 0x10) { sb.append('0'); } sb.append(Integer.toHexString(b)); } valueAfterMD5 = sb.toString(); } catch (UnknownHostException e) { System.out.println("Error:" + e); } } /* * Convert to the standard format for GUID * (Useful for SQL Server UniqueIdentifiers, etc.) * Example: C2FEEEAC-CFCD-11D1-8B05-00600806D9B6 */ public String toString() { String raw = valueAfterMD5.toUpperCase(); StringBuffer sb = new StringBuffer(); sb.append(raw.substring(0, 8)); sb.append("-"); sb.append(raw.substring(8, 12)); sb.append("-"); sb.append(raw.substring(12, 16)); sb.append("-"); sb.append(raw.substring(16, 20)); sb.append("-"); sb.append(raw.substring(20)); return sb.toString(); } }