Générer n octets aléatoires basés sur une graine de m octets en Java
J'aimerais générer n octets aléatoires à partir d'une donnée m octets de semences. La séquence produite doit être reproductible; pour la même graines de la même séquence doit être généré. n peut être soit plus ou inférieure que m.
Les deux approches triviales suivantes qui me viennent à l'esprit sont biaisées:
- Hachez les m octets pour créer une longue graine pour alimenter un nouveau
java.util.Random
générateur. Problème: Je rejette l'entropie si n - Hachez les m octets pour générer des données "aléatoires". Problème: ce plafond n à une certaine valeur (20 pour SHA1 par exemple).
Existe-t-il une façon standard de le faire? Je n'ai vu aucune classe pertinente dans java.security
, mais je suppose que c'est un besoin fondamental pour la cryptographie?
Note: je n'ai pas besoin de "crypto-niveau extra-secure" au hasard, juste aléatoire qui passe les tests de base de hasard statistique. Aussi, je préférerais compter sur le code standard au lieu d'avoir à tout coder par moi-même.
Modifier: java.security.SecureRandom(byte[] seed)
ne correspond pas à la facture, la séquence générée est purement aléatoire et ne dépend pas seulement de la graine (au moins sur ma JVM, mais j'aimerais avoir un résultat prévisible).
1 answers
Pour mémoire , une solution (plutôt lente) comme discuté ci-dessus:
public byte[] rand(byte[] seed, int n) {
try {
byte[] data = null;
ByteArrayOutputStream ret = new ByteArrayOutputStream(n);
while (ret.size() < n) {
MessageDigest md = MessageDigest.getInstance("SHA1");
md.update(seed);
if (data != null)
md.update(data);
data = md.digest();
ret.write(data, 0, Math.min(n - ret.size(), data.length));
}
return ret.toByteArray();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
Cela génère 1M d'octets "aléatoires" en ~500ms, et passe des tests de randomité statistique très basiques. Peut-être que choisir un hachage plus rapide que SHA1 accélérerait la chose, n'a pas étudié cela.