DEV Community

Florian Rohrer
Florian Rohrer

Posted on

Write a simple but impactful script

Basic challenge (simple): Write a script that produces all possible 4-digit numbers (0000...9999), then put them into a random order and save the output into a text file. Make sure you include leading zeroes where necessary and make also sure that each number is on a separate line in the text file.

Bonus challenge (for daring programmers only): Do the basic challenge and then do the following: Call the generated file leaked_pins.txt, and email it to one of your co-workers. In the description of the email, say that all the PIN numbers have been leaked, and they should be cautious and check, whether their PIN is contained in the file or not.

Share your code below. If any of you tries the bonus challenge, I am happy to hear any stories :)

Latest comments (47)

Collapse
 
jacaetevha profile image
Jason Rogers †

Just coming across this. I like finding and using old gems. For this, jot does just great.

jot -w %04d 9999 | shuf > /path/to/pins.txt

Or for those on a Mac using GNU coreutils (probably from brew), you'd use gshuf instead of shuf:

jot -w %04d 9999 | gshuf > /path/to/pins.txt

Of course, Ruby is just as elegant:

ruby -e 'puts ("0000"..."9999").to_a.shuffle' > /path/to/pins.txt

... but on my machine the Ruby solution is about 95% slower than the jot version: 148ms vs. 8ms, respectively.

Collapse
 
moopet profile image
Ben Sinclair

Vim/Bash:

9998O<esc>:%s/^/\=printf('%04d',line('.'))/<cr>:%!shuf<cr>:w leaked-pins.txt
Collapse
 
lchvdlch profile image
lchvdlch

AWK:



awk 'BEGIN{for(i=0;i<10000;i++){N[i]=sprintf("%04d",i)};while(i){j=int(10000*rand());if(N[j]){print N[j];delete N[j];i--}}}' > leaked_pins.txt
Collapse
 
quainor profile image
Quainor

Love the bonus challenge!
Sent such a list to a friend working for a bank years ago.
This made it to the board of directors within minutes.
Still laughing and gasping - almost can't believe this impact :-D.

Collapse
 
littlefox profile image
Mara Sophie Grosch (LittleFox)

Hacky Perl/sh oneliner

perl -e '@v=("0000".."9999"); %x; print map { do { $i=int(rand(@v)); } while($x{$i}); $x{$i}=1; $v[$i] . "\n"} @v;' > hacked_pins.txt

Generates a list of pins (@v) and then selects a random entry for every entry in the list (hacky use of map). %x is used to mark which entries already have been returned.

Collapse
 
vguarnaccia profile image
Vincent Guarnaccia • Edited
seq --equal-width 0 1 9999 | sort --random-sort > result.txt
Collapse
 
vguarnaccia profile image
Vincent Guarnaccia • Edited

Easier to read and works with embedded Linux systems (BusyBox):

seq -w 0 1 9999 | shuf > result.txt
Collapse
 
rpalo profile image
Ryan Palo

I didn't know this for a long time, but you can use strings to build ranges in Ruby as well, avoiding the need for any fancy padding with zeros!

pins = ("0000".."9999").to_a.shuffle.join("\n")
File.open("pins.txt", "w") { |f| f << pins }
Collapse
 
philippeback profile image
Philippe Back • Edited

Pharo

(file :='leaked_pins.txt' asFileReference) writeStreamDo: [ :s |
(0 to: 9999) shuffled do: [ :n | s << (n printPaddedWith: $0 to: 4); cr ]].

SMTPClient 
deliverMailFrom: 'donotreply@somewhere.com' 
to: { 'poorcolleague@target.org' }
text: ('All the PIN numbers have been leaked, and you should be cautious and check, whether your PIN is contained in the file. ', file contents)
usingServer: 'somereplay.world.net'
Collapse
 
ganderzz profile image
Dylan Paulus • Edited

Clojure?

 (spit "./hacks.txt" 
       (clojure.string/join "\n" 
            (shuffle 
                (map 
                   #(format "%04d" %) 
                    (range 0 10000)))))
Collapse
 
rafd123 profile image
Rafael Dowling Goodman • Edited

F#

do
    let rnd = System.Random()
    use file = System.IO.File.CreateText("leaked_pins.txt")

    [0..9999]
    |> Seq.sortBy (fun _ -> rnd.Next())
    |> Seq.iter (fprintfn file "%04d")

Some comments may only be visible to logged-in visitors. Sign in to view all comments.