-1

I'm new to android programming and i want to make a 4 Digit PIN generator without any repeats. How do I do it?? I don't know how to loop that very well yet. Thank you!!

I already tried Random but it gives me numbers that repeat.

int randomPIN = (int)(Math.random()*9000)+1000;

String pin = String.valueOf(randomPIN);
dummy.setText(pin);

I'm looking for an outcome of 1354, 4682, 3645 but the results are mostly 3344, 6577, 1988

Tamir Abutbul
  • 7,301
  • 7
  • 25
  • 53
  • 1
    Have you checked [this](https://stackoverflow.com/questions/4040001/creating-random-numbers-with-no-duplicates)? – Tamir Abutbul Sep 04 '19 at 15:36
  • As you are new to programming, this is a great problem for you to solve on your own, but here is a bit of a hint on how to proceed: start with getting the first random digit, then keep trying to get a second random digit that isn't the first; then keep trying to get a third random digit that isn't either of the first two, and so on. – dan.m was user2321368 Sep 04 '19 at 15:39
  • I will thank you!!! –  Sep 04 '19 at 15:42
  • I think i found a way thanks for your help guys!! –  Sep 04 '19 at 15:43
  • Are you looking for results that are persistent across runs of the application, or a mechanism to generate 9000 values sequentially without repeating any of them? If it's the former, you'll need to preserve state somehow between runs of the app. – pjs Sep 04 '19 at 20:37
  • This is a bad idea. You reduce the room of valid pins to from `10^4` to `10*9*8*7`. And because you don't want that the pin starts with 0, it is actually `9*9*8*7 = 4536`, less than half of the possible `10,000` combinations. – Johannes Kuhn Sep 04 '19 at 22:02
  • 1
    Why do you want to make your PINs deliberately less secure? By eliminating repeated digits, you reduce the code space by more than half, since only 4536 codes meet your criterion. – Lee Daniel Crocker Sep 04 '19 at 22:04

4 Answers4

1

Create a list of the digits, shuffle it, and return the first four digits. Here's one way of doing it as a static method:

/* No need for a new list each time */
private static final List<Integer> digits =
    new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));

/**
 * Returns a PIN string that contains four distinct digits.
 */
public static String nextPin() {
    Collections.shuffle(digits);
    final StringBuilder sb = new StringBuilder(4);
    for (Integer digit : digits.subList(0, 4)) {
        sb.append(digit);
    }
    return sb.toString();
}

Obviously, if you wanted the digits as an array of numbers instead of a string, you'd process the sublist differently than I've shown here.

If you just return the sublist itself, be aware that it will change each time you

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
0

//create list ArrayList numbers = new ArrayList(); Random randomGenerator=new Random();while (numbers.size() < 4) {int random = randomGenerator .nextInt(4); if (!numbers.contains(random)) { numbers.add(random);}}

  • ArrayList numbers=new ArrayList(); Random randomGenerator=new Random(); while (numbers.size() < 4) { int random = randomGenerator .nextInt(4); if (!numbers.contains(random)) { numbers.add(random); }} – Eltohamy Mohammed Sep 05 '19 at 07:19
0

Somewhat of an academic exercise - here's one requiring Java 8:

    // flag to control if you want number sequence to be the same each run
    boolean repeatable = true;

    // seed for randomness - for permutation of list (not the integers)
    Random rnd = new Random((repeatable ? 3 : System.currentTimeMillis()));

    // generate randomized sequence as a List
    List<Integer> myNums;
    Collections.shuffle((myNums = IntStream.rangeClosed(1000, 9999).boxed().collect(Collectors.toList())), rnd);

    // Work with list...
    for (Integer somePin : myNums) {
        Log.i("", "Next PIN: "+somePin);
    }
-2

You're gonna have to add the random ints step after step and check for duplicates.

Random random = new Random();
int rdmInt = random.nextInt(9);
String pin = "";
while (pin.length() < 4) {
    rdmInt = random.nextInt(9);
    String addition = String.valueOf(rdmInt);
    if (pin.contains(addition)) continue;
    pin += addition;
}