Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Remember those brute-force programs to crack password that show every combination they are trying? More precisely, at one point, the n first characters are fixed (they have been guessed successfully), and every possible character for the remaining ones is being tested. You've probably seen some in movies, or in some software written by people that like fancy interfaces.
Sorry to disappoint, but we won't write a program to crack password, only one to reproduce the nice output.

Challenge

Given a string containing printable ascii characters but no newlines (ascii code 32 to 126 or matching the regex ^[ -~]{2,}$), print an output following this rules:

  • At time t=n seconds, the n first characters printed are the n first characters of the input string.
  • After the n fixed characters, you should append a string formed random character (chosen uniformly pseudo-randomly from the unicode range   to ~ (code 32 to 126)) to form a string of the length of the initial one.
  • You should output at least (more on that later) 20 lines every second: every one of them will have the same n first characters, but a different random end.

It's probably not very clear yet what you are supposed to do, so lets go through an example:

Example

I'll print only 5 different lines for every seconds instead of the 20 minimum just to make it more readable.

Consider the input abcde.
During the first second, a valid output can be something like (completely random):

dGuT4
S!jkN
"gQ>[
TU3! 
*fAjV

Then, t=1, the first character of every following string will be a (the first character of the input):

a);jD
aHv^p
aqw5*
a|.?:
a{gbK

Now, t=2, the first two characters will be ab:

abTJ"
ab\ e
ab3T#
abYWS
ab"#<

Now, t=3, the first three characters will be abc :

abcvW
abc3G
abc(g
abc{@
abc@4

Now, t=4, the first four characters will be abcd :

abcdD
abcdv
abcdj
abcd$
abcd6

Finally, t=5, we print the input (only once):

abcde

A few precisions

  • You shouldn't bother too much with your language precision toward the seconds (ie. If your algorithm is correct but your system/language lacks precision then it's fine).
  • The first second can be shorter than one second (That is, if you launch you program during a second, the first second can be just the remaining time until the end of the current second). Or put differently, you don't have to wait for the start of a new second to start printing the outputs.
  • At least 20 lines per second: The more natural way would be an infinite loop with a special behaviour one every second (or a timeout, or whatever), so that will result in probably a few thousand lines per second (and that's perfectly fine!). But if you have another idea, feel free to use it as long as you print at least 20 lines per second.
  • The input will always be more than 2 characters long.
  • You can consider that the input won't be more that 30 characters long if it helps. (But if it works for longer ones, it's for the best)
  • The input format should be the most natural representation of a string in your language.

Code example

If you still don't understand exactly what you have to do, you can run the following code in a linux terminal to see:

perl -F -aplE 'while(@F){$t=time;while($t==time){print$s,map{chr(32+rand 94)}@F}$s.=shift@F}' <<< "Craking in progress!"

Winning criterion

This is , so shortest code in byte wins!

A slightly modified version of the code, just for the eyes : (to run in your terminal as well)

Note that this version adds \r before each line, but your program shouldn't do that: lines should be separated with newlines.

perl -F -aplE '$\="";while(@F){$t=time;while($t==time){print"\r$s",map{chr(32+rand 94)}@F}$s.=shift@F}print"\r"' <<< "1354778852012936"


Thanks to Laikoni and Flp.Tkc for their suggestions and improvement in the sandbox.

share|improve this question
2  
Like this scene from the movie War Games? – JHM 19 hours ago
1  
Is it mandatory to separate the lines of output with \r (making them all replace each other onscreen like in the animation), or is \n acceptable? – ais523 19 hours ago
1  
@ais523 \n is perfectly acceptable. The version with \r is just here because it looks better, but you don't need those \r. – Dada 19 hours ago
    
If the random generation happens to crack the password earlier is it alright to stop at that point? – Jonathan Allan 19 hours ago
1  
Shouldn't you include in the rules that the random characters should not be the actual character in that place ? Otherwise random strings can match the password given, but the search goes on, which movie buffs would rate as a glitch. – Tom 8 hours ago

17 Answers 17

Node, 145 142 bytes

for(s=process.argv[2],d=new Date;s[a=(new Date-d)/1e3|0]+console.log(s.replace(/./g,(c,i)=>i<a?c:String.fromCharCode(32+Math.random()*95))););

This seems a little long, and there's probably a little room for golfing. Note that the semicolon at the end is required; without it the program throws a syntax error because the for statement has no body.

Outputs way more than 20 lines per second; a little birdie told me that it's roughly 12 thousand. Here's how it looks in the ConEmu terminal emulator on my computer (recorded at 30 fps):

enter image description here

share|improve this answer

HTML/JavaScript, 170 bytes

setInterval(_=>o.textContent=i.value.replace(/./g,(c,i)=>Date.now()-d>++i*1e3?c:String.fromCharCode(Math.random()*95+32)),d=50)
<input id=i oninput=d=Date.now()><pre id=o>

share|improve this answer
    
You can use new Date in place of Date.now(), saving you 2 bytes in the JS part. – ETHproductions 3 hours ago

BASH, 99 93 92 91 88 bytes

with tr + head + urandom

while ((${#1}-n));do
echo "${1::n=SECONDS}`tr -dc \ -~</dev/ur*|head -c$[${#1}-n]`"
done

(thx. to @manatwork )

share|improve this answer
4  
[ "$n" = ${#1} ]((n==${#1})); ${1:0:$n}${1::n} – manatwork 7 hours ago
    
@manatwork: whoa! – Ipor Sircer 7 hours ago
1  
1 more: the space in front of input redirection < is not needed. – manatwork 6 hours ago
1  
@manatwork ((n==${#1})) --> ((${#1}-n)) – Ipor Sircer 6 hours ago
1  
Either because you reversed the logic or because I banged my previous test, but ${1::n=SECONDS} seems to work now. – manatwork 6 hours ago

Bash, 247 245 212 207 bytes

R()(echo $SECONDS);w=`R`;until [ "$a" = "$1" ];do for i in `seq 1 $[${#1}-${#a}]`;{ a+=`printf "\x$(printf %x $[$RANDOM%127+32])"`;};echo -e "$a\r";a=${1:0:q};((`R`-w>0))&&{ w=`R`;((q++));}||:;done;echo "$a"

Thanks a lot Bash for being so whitespace sensitive...

Anyways, output is given in real time on separate lines. Save as a .sh script and invoke with:

bash <File Name>.sh <Input>

For example, bash Cracking_In_Progress.sh okayerty results in the following output, recorded at 30 frames per second:

Example Output

share|improve this answer

Pyth - 27 24 bytes

This actually looks pretty cool :D

WJ-lQKs.d1+<QKsmOr;\~J;Q

Try it online here (obviously not in real time, but if you scroll it down with a steady hand).

share|improve this answer

WinDbg, 400 391 bytes

.for(r$t1=@$t0;by(@$t1);r$t1=@$t1+1){};m@$t0 L@$t1-@$t0+1 @$t1+1;r$t4=2*@$t1+2-@$t0;r$t8=@$t4+f;r$t3=0;.for(r$t2=0;@$t2<@$t1-@$t0;da@$t0){.for(r$t7=@$t0+@$t2;by(@$t7);r$t7=@$t7+1;r$t8=@$t8+1){eb@$t7 by(@$t8)%5e+20};r$t9=0;.foreach(p {.echotime}){.if7==@$t9{ea@$t4"p";.if1>@$t3{r$t3=by(@$t4+7)}};r$t9=@$t9+1};j@$t3!=by(@$t4+7)'m@$t0+@$t4-@$t1+@$t2-1 L1 @$t0+@$t2;r$t2=@$t2+1;r$t3=by(@$t4+7)'}

-9 bytes by simplifying some math

This definitely does not seem to be the kind of thing WinDbg is intended to do. ;)

Input is taken by entering an ascii string at a memory location and setting that address to the pseudo-register $t0. Eg:

r$t0 = 2000000
eza @$t0 "abcde"

The prng I'm using is whatever the contents in memory, some bytes past the input string. Chrome.exe appears to fill the memory space after 0x2000000 with random-looking-enough bytes so I used a dump of chrome.exe. Unknown if this is uniform, but looks random-enough to me.

How it works:

.for(r$t1=@$t0; by(@$t1); r$t1=@$t1+1){};         * From $t0, increment $t1 until the byte
                                                  * at $t1 is 0 to find length of input
m@$t0 L@$t1-@$t0+1 @$t1+1;                        * Duplicate input (memory 
                                                  * becomes: "input\0input\0")

r$t4=2*@$t1+2-@$t0;                               * Set $4 to the byte after \0 of the 
                                                  * duplicated input
r$t8=@$t4+f;                                      * Set $t8 to $t4+15, this is the prng
r$t3=0;                                           * Init $t3=0, this will hold the time

.for(r$t2=0; @$t2<@$t1-@$t0; da@$t0){             * For $t2=0, loop until it's input length,
                                                  * printing the string at $t0 after each
                                                  * loop. $t0 is where the password crack
                                                  * progress is written.
    .for(r$t7=@$t0+@$t2; by(@$t7); r$t7=@$t7+1;   * Loop over each uncracked char
                                   r$t8=@$t8+1){  * also incrementing prng ($t8)
        eb@$t7 by(@$t8)%5e+20                     * Write a visible ascii char onto the
                                                  * uncracked char position based on the 
                                                  * current byte of prng%0x5e+0x20 (prng%126+32)
    };

    r$t9=0;                                       * Set $t9=0 for updating current time
    .foreach(p {.echotime}){                      * For each (string) word in a statement
                                                  * like "Debugger (not debuggee) time: Mon 
                                                  * Nov 21 18:23:08.433 2016 (UTC - 8:00)"
        .if7==@$t9{                               * If the 7th word, ie- the current time
            ea@$t4"p";                            * Write the time at $t4
            .if1>@$t3{                            * If $t3 has not been set yet
                r$t3=by(@$t4+7)                   * ...save the current second in $t3
            }
        };
        r$t9=@$t9+1                               * Increment $t9 until it's 7
    };

    j@$t3!=by(@$t4+7)'                            * If the current second has changed
        m@$t0+@$t4-@$t1+@$t2-1 L1 @$t0+@$t2;      * Copy the cracked char from dupe input
        r$t2=@$t2+1;                              * Increment $t2 (loop ends when this is input length)
        r$t3=by(@$t4+7)                           * Save the new current second
    '
}                                                 * Final crack is printed by for loop

Note: Some bytes could be golfed by using j instead of the .if's, but that causes it to run too slowly on my machine so it doesn't output at least 20 lines per second, so not saving those bytes.

Sample Output: http://pastebin.com/H4H74sAx

share|improve this answer

MATL, 26 bytes

`GZ`:)' ~'olGn4Mk-I$YrhD7M

Try it online!

Below is the real-time output from the offline compiler. Note that the animated GIF was recorded at 20 fps to keep its size small, but the actual speed is much greater.

enter image description here

share|improve this answer

C, 182 176 128 bytes

Golfed:

i;s;n;x=0;g(char*c){s=time(0);while(c[++x]);do{n=time(0)-s;for(i=0;i<x;i++)putchar(i<n?c[i]:32+rand()%95);puts("");}while(n<x);}

Ungolfed:

#include "stdio.h"
#include "stdlib.h"
#include "time.h"
int i,s,n,x=0;
void g(char* c) {
  s = time(0); //Get the initial time
  while(c[++x]); // x = strlen(c) (happy about this one)
  do {
    n = time(0) - s; //seconds since beginning
    for(i = 0; i < x; i++)
      //after each second, print another char of the password
      putchar(i < n ? c[i] : 32 + rand() % 95);
    puts("");
  } while(n < x); //while we haven't printed the whole word
}

I've heard that it's possible to drop some standard #includes, but I couldn't get it to work on the MingW GCC compiler I just downloaded. Also couldn't figure out how to #define b #include without using more space than it was worth. I'm just an idiot, it works fine without them.

share|improve this answer
    
X=0 is not required instead declare it with others like this a,b,c,d; cuz all global variables declared like that are int and init by 0 also since you are returning nothing you should write it in main () – Mukul Kumar 10 mins ago

05AB1E, 30 bytes

gFžcUNV[¹Y£žQ.r¹gY-£J,XžcÊ#}¹,

Uses the CP-1252 encoding. Try it online!

Please help me golf this down.

share|improve this answer

R, 138 bytes

z=Sys.time;n=nchar(x<-scan(,""));s=z();t=0;while(t<=n){t=t+z()-s;cat(substr(x,1,f<-floor(t)),intToUtf8(sample(32:126,n-f,T)),"\n",sep="")}

Reads input from stdin.

Counted approximately 61 lines on my machine between each additional letter in the "password".

share|improve this answer

Python 3, 167 166 bytes

import time,random
t=time.time
p,s=input(),t()
while t()-s<len(p):print(p[:int(t()-s)]+''.join(chr(random.randint(32,126))for _ in range(len(p)-int(t()-s))))
print(p)

Reads input from stdin. A 171-byte version runs under Python 2 (replaced input with raw_input):

import time,random
t=time.time
p,s=raw_input(),t()
while t()-s<len(p):print(p[:int(t()-s)]+''.join(chr(random.randint(32,126))for _ in range(len(p)-int(t()-s))))
print(p)

Ungolfed:

import random
import time

p = input()
start = time.time()
while time.time() - start < len(p): 
    print(
        p[:int(time.time() - start)] + 
        ''.join(chr(random.randint(32, 126)) for _ in range(len(p) - int(time.time()-start)))
    )
print(p)
share|improve this answer

Java 7, 271 265 bytes

void c(String s)throws Exception{String x="",r;for(char c=32;c<'~';x+=c++);for(int i=0,j,l=s.length();i<=l*20;i++){r="";Thread.sleep(45);for(j=0;j<i/20;r+=s.charAt(j++));for(;j++<l;r+=x.charAt((int)(Math.random()*94)));System.out.println(r);if(s.equals(r))return;}}

Ungolfed:

void c(String s) throws Exception{
  String x = "",
         r;
  for(char c = 32; c < '~'; x += c++);
  for(int i = 0, j, l = s.length(); i <= l*20; i++){
    r = "";
    Thread.sleep(45);
    for(j = 0; j < i/20; r += s.charAt(j++));
    for( ; j++ < l; r += x.charAt((int)(Math.random()*94)));
    System.out.println(r);
    if(s.equals(r)){
      return;
    }
  }
}

Input: abcde
Output:

enter image description here

share|improve this answer
    
I'm not sure if you designed it purposefully to only print 20 lines per second, but if it helps your golfing, you only have to print at least 20 lines per second. I don't know if changing the "20 lines per second" math to "change every second" math would help or not. – nmjcman101 2 hours ago

C#, 203 197 195 bytes

Golfed:

void F(string s){int l=s.Length,t=0;var w=new Stopwatch();w.Start();do{if(w.Elapsed.Seconds>t)t++;Console.WriteLine($"{s.Substring(0,t)}{Path.GetRandomFileName().Substring(0,l-t)}");}while(t<l);}

Ungolfed:

    void F(string s)
    {
        int l = s.Length, t = 0;
        var w = new Stopwatch();

        w.Start();

        do
        {
            if (w.Elapsed.Seconds > t)
                t++;

            Console.WriteLine($"{s.Substring(0, t)}{Path.GetRandomFileName().Substring(0, l - t)}");
        } while (t < l);
    }

l stores input length.

StopWatch and Path.GetRandomFileName() are parts of .NET framework.

EDIT1: Implicit type of Stopwatch declaration.

EDIT2: l initialization moved to declaration.

share|improve this answer
    
You can use the static method Stopwatch.StartNew() to save newing up the stopwatch, and explicitly starting it – Chris 2 hours ago

05AB1E, 26 bytes

I post this as a different answer with respect to the other 05AB1E answer since the approach is different

.põ¸ì¨vT·FyžQ.r¹gyg-£«}}¹»

.p                         Generate ordered prefix of input (e.g., ["a", "ab", "abc", "abcd", "abcde"] for "abcde")
  õ¸ì                      Prepend an empty string (e.g., result is ["", "a", "ab", ...])
     ¨                     Strip the last element (the same string as the input)
      v                    For each string in the array
       T·F                 For N in range(20)
          y                Push the current string
           žQ.r            Push all printable characters, shuffled
               ¹gyg-       Take the difference between the length of the input and the length of the current string -> x
                    £      Take the x first characters from the shuffled printable characters
                     «     Yield currentString + shuffledCharacters
                      }    End inner for
                       }   End outer for
                        ¹  Push input (last iteration)
                         » Join everything with newlines and implicitly display

Try it online!

share|improve this answer

ForceLang, 322 bytes

Noncompeting, requires language features that postdate the question.

def s set
s g goto
s W io.writeln
s k io.readln()
s T timer.new()
def a T.poll()
label 1
s P math.floor a.mult 1e-6
if P=k.len
g 6
s j 0
s t ""
if P=0
g 4
label 3
s v k.charAt j
s t t+v
s j 1+j
if j-P
g 3
label 4
if j=k.len
g 5
s r 94.mult random.rand()
s v string.char 32+r
s t t+v
s j 1+j
g 4
label 5
W t
g 1
label 6
W k
share|improve this answer

Python3, 149 141 139 bytes

import time,random
i,x=input(),0;l=len(i)
while x<l:x=int(time.clock());print(i[:x]+"".join(chr(random.randint(32,126))for _ in"a"*(l-x)))

Input from stdin.

Eyes version (157 bytes):

import time,random
p,i,x=print,input(),0;l=len(i)
while x<l:x=int(time.clock());p(i[:x]+"".join(chr(random.randint(32,126))for _ in"a"*(l-x)),end="\r")
p(i)
share|improve this answer
    
I think you can save a few bytes by not "renaming" things that you only do once. For instance you have t=time.clock, but you only use t once in the code. Replacing it with just time.clock will save 3 bytes. Same thing for print. – nmjcman101 2 hours ago
    
@nmjcman101 Oops, carry over from prev ver. Thanks! – matsjoyce 2 hours ago
    
Also your for _ in range(l-x) can be for _ in"a"*(l-x) for 2 bytes. – nmjcman101 1 hour ago
    
@nmjcman101 Nice! I must remember that one... – matsjoyce 1 hour ago

Haskell (GHC), 202 bytes

import System.Random
import Control.Concurrent
f s|l<-length s=mapM_(\n->putStr('\r':take n s)>>mapM(\_->toEnum<$>randomRIO(32,126))[1..l-n]>>=putStr>>threadDelay 50000)$[n|n<-[0..l-1],f<-[1..20]]++[l]

-5 bytes without fancy carriage return action

enter image description here

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.