0

I am writing a bash script for a c program, where the program asks for a 4 numerical pin inputs. However, when I wrote the script, the output seems to run in a loop, but it doesn't break where it gets identified as the correct number the program will accept.

#!/bin/bash

RANGE=9000
count=${RANDOM:0:4}

while [[ "$count" -le $RANGE ]]
do
    number=$RANDOM
    (( "number %= $RANGE" ))
    echo $number
    if [[ "$count" == "$RANGE" ]]; then
        break
    fi
done

When I run it, I can see some numbers in the output that returned as 2 or 3 digits, instead of 4. So in theory, what I want to do is find a random number that is 4 digits that the program will take, but I don't know what is the random number, so essentially it is a brute force, or just me manually guessing the pin number.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Antonette
  • 1
  • 1
  • Why are you putting your arithmetic expression in quotes? It's just `(( number %= RANGE ))`; no need for `$`s _or_ quotes. – Charles Duffy Sep 06 '20 at 00:40
  • Anyhow, if you get a 3 digit number that just means the first digit was 0; if you get a 2-digit number, the _first two_ digits are 0. – Charles Duffy Sep 06 '20 at 00:41
  • ...btw, it's not clear what you mean by "for a C program" in this context. – Charles Duffy Sep 06 '20 at 00:42
  • This is a c program that I am given that asks for a numerical input. I did not write the c program myself. Also, when I typed the arithmetic expression in quotes, I'm still a newbie at bash, but I will take that in consideration for future scripts. – Antonette Sep 06 '20 at 00:50

1 Answers1

0

If all you need is a random 4-digit number, you can do that with:

printf -v number "%04d" $((RANDOM % 10000))

The $RANDOM gives you a random number 0..32767, the % 10000 translates that to the range 0..9999 (not perfectly distributed, but should be good enough for most purposes), and the printf ensures leading zeros are attached to it (so you'll see 0042 rather than 42, for example).


You can test it with the following script:

(( total = 0 ))
(( bad = 0 ))
for i in {1..10000} ; do
    printf -v x "%04d" $((RANDOM % 10000))
    (( total += 1 ))
    [[ "${x}" =~ ^[0-9]{4}$ ]] || { echo Bad ${x}; (( bad += 1 )); }
done
(( good = total - bad ))
echo "Tested: ${total}, bad ${bad}, good ${good}"

which should give you:

Tested: 10000, bad 0, good 10000
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • 1
    Insofar as the OP is trying to make guesses at a number, it probably wouldn't do to not be able to guess combinations where the first digit is 0. – Charles Duffy Sep 06 '20 at 00:43
  • 1
    BTW, consider `printf -v x '%04d' "$x"` instead of the command substitution; makes the code bash-specific, but much faster (and it's already bash-specific anyhow). – Charles Duffy Sep 06 '20 at 00:58
  • Good points, @Charles, I've bought them on-board with another slight improvement that combines the random generation with the `printf`. I don't think being bash-specific is an issue since the question is *tagged* `bash`. – paxdiablo Sep 06 '20 at 01:08
  • Thank you for help, that cleared up some confusion about the scripting. I should've known that was the case with the numbers showing as 2 digits, when I was pretty sure I only asked for a certain range of numbers. – Antonette Sep 06 '20 at 01:23