|
|
|
| /* Edition Française */ |
| « CustomErrors Pour Les Nuls | DBAs?! Pour quoi faire? » |
J.S Bangs nous envoie un bout de code qu’il a déniché au plus profond d’une application Java qu’il maintient. La fonction getRandomBits() retourne un tableau de 32 bits aléatoires pour des raisons de sécurité. Puisque Java offre une méthode Random, ceci devrait être assez facile. A vrai dire, une bonne implémentation peut être écrite en cinq lignes :
public static byte[] getRandomBits() {
byte[] random = new byte[32];
Random.nextBytes(random);
return random;
}
Bien sûr, le prédécesseur de JS.S trouva une façon beaucoup plus intéressante pour fournir ce tableau de bits : sa propre méthode getRandomBits
* Enumerate all of the System properties
* Create an MD4 hash of all of the property key/value pairs
* Do a bitwise-XOR of the various hashes
* Throw in an MD4 hash of the current system time so that the value isn't always the same
* Bitwise-XOR that in there as well
* Return the result
public static byte[] innerGetRandomBits() {
int pos = 0;
int iters = 0;
bits = new byte[(nbits + 7) / 8];
for (int i = 0; i < bits.length; i++)
bits[i] = (byte) 0;
Enumeration e = null;
try {
e = System.getProperties().propertyNames();
} catch (Exception ex) {
// no need to do anything
}
MD4 hash = new MD4();
int hash_count = 0;
int hash_bytes = 0;
long ms = System.currentTimeMillis();
byte[] bytes = new byte[12];
for (int i = 0; i < 8; i++) {
bytes[i] = (byte) (ms & 0xffL);
ms = ms >> 8;
}
int hn = System.identityHashCode(bytes);
for (int i = 0; i < 4; i++) {
bytes[i + 8] = (byte) (hn & 0xffL);
hn = hn >> 8;
}
if (e != null)
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
if (key != null) {
String val = System.getProperty(key);
if (val != null) {
String pair = key + val;
bytes = pair.getBytes();
hash.engineUpdate(bytes, 0, bytes.length);
hash_bytes += bytes.length;
// when the hash input size is large enough ...
if (hash_bytes >= 128) {
hash_count++;
hash_bytes = 0;
// ... produce a digest and ...
byte[] digest = hash.engineDigest();
for (int i = 0; i < digest.length; i++) {
// ...fold it into the bit buffer
bits[pos] = (byte) (bits[pos] ^ digest[i]);
pos++;
if (pos == bits.length) {
pos = 0;
iters++;
}
} // end for
} // end if hash_bytes
} // end if val non null
} // end if key non null
} // end while e.hasMoreElements
while (iters < 2) {
for (int j = 512 / 8; j > 0; j--) {
Thread.yield();
ms = System.currentTimeMillis();
for (int i = 0; i < 8; i++) {
bytes[i] = (byte) (ms & 0xffL);
ms = ms >> 8;
}
hash.engineUpdate(bytes, 0, 8);
hash_bytes += 8;
// when the hash input size is large enough ...
if (hash_bytes >= 128) {
hash_count++;
hash_bytes = 0;
// ... produce a digest and ...
byte[] digest = hash.engineDigest();
for (int i = 0; i < digest.length; i++) {
// ...fold it into the bit buffer
bits[pos] = (byte) (bits[pos] ^ digest[i]);
pos++;
if (pos == bits.length) {
pos = 0;
iters++;
}
} // end for
} // end if hash_bytes
} // end for
} // end while iters
return bits;
}| « CustomErrors Pour Les Nuls | DBAs?! Pour quoi faire? » |