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).

Author: Laurent Grégoire, 2015-06-15

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.

 0
Author: Laurent Grégoire, 2015-06-16 13:58:11