Task

Find, through brute force, the five-letter passwords corresponding with the following SHA-256 hashes:

1. 1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad
2. 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b
3. 74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f

Your program should naively iterate through all possible passwords consisting only of five lower-case ASCII English letters. It should use concurrent or parallel processing, if your language supports that feature. You may calculate SHA-256 hashes by calling a library or through a custom implementation. Print each matching password, along with its SHA-256 hash.

Related task: SHA-256

include builtins\sha256.e
include builtins\VM\pThreadN.e -- (shd not be rqd on 0.8.1+)
 
function asHex(string s)
string res = ""
    for i=1 to length(s) do
        res &= sprintf("%02X",s[i])
    end for
    return res
end function
 
sequence starts
constant start_cs = init_cs(),      -- critical section
         hashes = {x"1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad",
                   x"3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
                   x"74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f"}
 
procedure find_passwords()
    sequence thrashes = {}  -- thread-safe copy of hashes
    enter_cs(start_cs)
    for i=1 to length(hashes) do
        thrashes = append(thrashes,thread_safe_string(hashes[i]))
    end for
    leave_cs(start_cs)
    while true do
        string pwd
        enter_cs(start_cs)
        if length(starts)=0 then
            leave_cs(start_cs)
            exit
        end if
        pwd = starts[$]&repeat('a',4)
        starts = starts[1..$-1]
        leave_cs(start_cs)
        while length(pwd) do
            string hash = sha256(pwd)
            if find(hash,thrashes) then ?{pwd,asHex(hash)} end if
            for i=5 to 2 by -1 do
                if pwd[i]!='z' then
                    pwd[i] += 1
                    exit
                end if
                pwd[i] = 'a'
                if i=2 then pwd = "" exit end if
            end for
        end while
    end while
    exit_thread(0)
end procedure
 
for nthreads=4 to 4 do
    atom t0 = time()
    starts = tagset('a','z',-1)
    sequence threads = {}
    for i=1 to nthreads do
        threads = append(threads,create_thread(routine_id("find_passwords"),{}))
    end for
    wait_thread(threads)
    string e = elapsed(time()-t0)
    printf(1,"completed with %d threads in %s\n",{nthreads,e})
end for
