1931 votes

Comment générer une chaîne alphanumérique aléatoire ?

J'ai cherché un simple Algorithme Java permettant de générer une chaîne alphanumérique pseudo-aléatoire. Dans mon cas, cette chaîne serait utilisée comme identifiant unique de la session/clé, qui serait "probablement" unique sur plus d'un million d'ordinateurs. 500K+ (mes besoins ne nécessitent pas vraiment quelque chose de plus sophistiqué).

Idéalement, je pourrais spécifier une longueur en fonction de mes besoins d'unicité. Par exemple, une chaîne générée d'une longueur de 12 pourrait ressembler à ceci "AEYGF7K0DM1X" .

162 votes

Méfiez-vous de le paradoxe de l'anniversaire .

62 votes

Même en tenant compte du paradoxe de l'anniversaire, si vous utilisez 12 caractères alphanumériques (62 au total), il vous faudrait encore bien plus de 34 milliards de chaînes de caractères pour atteindre le paradoxe. Et le paradoxe d'anniversaire ne garantit pas une collision de toute façon, il dit juste qu'il y a plus de 50% de chances.

6 votes

@NullUserException 50 % de chance de succès (par essai) est sacrément élevé : même avec 10 essais, le taux de succès est de 0,999. En gardant cela à l'esprit et le fait que vous pouvez essayer BEAUCOUP sur une période de 24 heures, vous n'avez pas besoin de 34 milliards de chaînes de caractères pour être pratiquement sûr de deviner au moins l'une d'entre elles. C'est la raison pour laquelle certains jetons de session doivent être très, très longs.

0voto

Riley Jones Points 33
public static String RandomAlphanum(int length)
{
    String charstring = "abcdefghijklmnopqrstuvwxyz0123456789";
    String randalphanum = "";
    double randroll;
    String randchar;
    for (double i = 0; i < length; i++)
    {
        randroll = Math.random();
        randchar = "";
        for (int j = 1; j <= 35; j++)
        {
            if (randroll <= (1.0 / 36.0 * j))
            {
                randchar = Character.toString(charstring.charAt(j - 1));
                break;
            }
        }
        randalphanum += randchar;
    }
    return randalphanum;
}

J'ai utilisé un algorithme très primitif en utilisant Math.random(). Pour augmenter le caractère aléatoire, vous pouvez implémenter directement la fonction util.Date classe. Néanmoins, cela fonctionne.

-1voto

Mayank Points 19

J'utilise une solution très simple avec Java 8. Il suffit de la personnaliser en fonction de vos besoins.

...
import java.security.SecureRandom;
...

//Generate a random String of length between 10 to 20.
//Length is also randomly generated here.
SecureRandom random = new SecureRandom();

String sampleSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";

int stringLength = random.ints(1, 10, 21).mapToObj(x -> x).reduce((a, b) -> a).get();

String randomString = random.ints(stringLength, 0, sampleSet.length() - 1)
        .mapToObj(x -> sampleSet.charAt(x))
        .collect(Collector
            .of(StringBuilder::new, StringBuilder::append,
                StringBuilder::append, StringBuilder::toString));

Nous pouvons l'utiliser pour générer une chaîne alphanumérique aléatoire comme ceci (la chaîne renvoyée comportera obligatoirement des caractères non numériques ainsi que des caractères numériques) :

public String generateRandomString() {

    String sampleSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_";
    String sampleSetNumeric = "0123456789";

    String randomString = getRandomString(sampleSet, 10, 21);
    String randomStringNumeric = getRandomString(sampleSetNumeric, 10, 21);

    randomString = randomString + randomStringNumeric;

    //Convert String to List<Character>
    List<Character> list = randomString.chars()
            .mapToObj(x -> (char)x)
            .collect(Collectors.toList());

    Collections.shuffle(list);

    //This is needed to force a non-numeric character as the first String
    //Skip this for() if you don't need this logic

    for(;;) {
        if(Character.isDigit(list.get(0))) Collections.shuffle(list);
        else break;
    }

    //Convert List<Character> to String
    randomString = list.stream()
            .map(String::valueOf)
            .collect(Collectors.joining());

    return randomString;

}

//Generate a random number between the lower bound (inclusive) and upper bound (exclusive)
private int getRandomLength(int min, int max) {
    SecureRandom random = new SecureRandom();
    return random.ints(1, min, max).mapToObj(x -> x).reduce((a, b) -> a).get();
}

//Generate a random String from the given sample string, having a random length between the lower bound (inclusive) and upper bound (exclusive)
private String getRandomString(String sampleSet, int min, int max) {
    SecureRandom random = new SecureRandom();
    return random.ints(getRandomLength(min, max), 0, sampleSet.length() - 1)
    .mapToObj(x -> sampleSet.charAt(x))
    .collect(Collector
        .of(StringBuilder::new, StringBuilder::append,
            StringBuilder::append, StringBuilder::toString));
}

-1voto

Albert Points 11

Chaîne de 10 lettres aléatoires entre majuscules et minuscules

StringBuilder randomString = new StringBuilder();   
Random random = new Random();
boolean alphaType = true;
int j;

for(int i = 0; i <= 9; ++i)
{
    j = (random.nextInt(25) + (alphaType == true ? 65 : 97));
    randomString.append((char)j);
    alphaType = !alphaType;
}
return randomString.toString();

-1voto

Steven L Points 3892

Encore une autre solution...

public static String generatePassword(int passwordLength) {
    int asciiFirst = 33;
    int asciiLast = 126;
    Integer[] exceptions = { 34, 39, 96 };

    List<Integer> exceptionsList = Arrays.asList(exceptions);
    SecureRandom random = new SecureRandom();
    StringBuilder builder = new StringBuilder();
    for (int i=0; i<passwordLength; i++) {
        int charIndex;

        do {
            charIndex = random.nextInt(asciiLast - asciiFirst + 1) + asciiFirst;
        }
        while (exceptionsList.contains(charIndex));

        builder.append((char) charIndex);
    }
    return builder.toString();
}

-1voto

kyxap Points 174

Vous pouvez également générer n'importe quelle lettre minuscule ou majuscule ou même des caractères spéciaux à partir des données de la table ASCII. Par exemple, générez des lettres majuscules de A (DEC 65) à Z (DEC 90) :

String generateRandomStr(int min, int max, int size) {
    String result = "";
    for (int i = 0; i < size; i++) {
        result += String.valueOf((char)(new Random().nextInt((max - min) + 1) + min));
    }
    return result;
}

Sortie générée pour generateRandomStr(65, 90, 100)); :

TVLPFQJCYFXQDCQSLKUKKILKKHAUFYEXLUQFHDWNMRBIRRRWNXNNZQTINZPCTKLHGHVYWRKEOYNSOFPZBGEECFMCOKWHLHCEWLDZ

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X