Parallel brute force: Difference between revisions

added elixir solution
(added elixir solution)
 
(40 intermediate revisions by 15 users not shown)
Line 15:
=={{header|Ada}}==
{{libheader|CryptAda}}
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO;
 
with CryptAda.Digests.Message_Digests.SHA_256;
Line 86:
Work := new Worker (First => C);
end loop;
end Brute_Force;</langsyntaxhighlight>
 
=={{header|BaCon}}==
<langsyntaxhighlight lang="qbasic">PRAGMA INCLUDE <openssl/sha.h>
PRAGMA LDFLAGS -lcrypto
 
Line 96:
LOCAL buffer[32], passwd[5] TYPE unsigned char
LOCAL result TYPE unsigned char*
LOCAL a,b,c,d,e TYPE intNUMBER
 
DATA "a13bbac91141bb5cfc6f1dc723256243775aeb3517671b350ce3f4c607d693c73a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b", "ea125efa275b675155f4f1a00ae8b6e361ea2ed486db1a55b805e4fc5f47441a74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f", "1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad"
 
WHILE TRUE
Line 134:
NEXT
NEXT
WEND</langsyntaxhighlight>
{{out}}
<pre>
Line 144:
=={{header|C}}==
{{trans|C#}}
<langsyntaxhighlight lang="c">// $ gcc -o parabrutfor parabrutfor.c -fopenmp -lssl -lcrypto
// $ export OMP_NUM_THREADS=4
// $ ./parabrutfor
Line 214:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>apple => 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b
Line 222:
=={{header|C sharp|C#}}==
 
<langsyntaxhighlight lang="csharp">using System;
using System.Linq;
using System.Text;
Line 262:
return true;
}
}</langsyntaxhighlight>
 
{{out}}
Line 271:
=={{header|C++}}==
{{libheader|OpenSSL}}
<langsyntaxhighlight lang="cpp">#include <atomic>
#include <cstdio>
#include <cstring>
Line 279:
#include <string>
#include <vector>
 
#include <openssl/sha.h>
 
Line 287 ⟶ 288:
}
bool parse(const std::string& hash) {
if (hash.length() != 2 * SHA256_DIGEST_LENGTH) {
std::cerr << "Invalid SHA-256 hash\n";
return false;
Line 325 ⟶ 326:
password_finder(int);
void find_passwords(const std::vector<std::string>&);
 
private:
int length;
Line 345 ⟶ 347:
--count;
std::ostringstream out;
out << "password: " << passwd << ", hash: " << hashes[m] << '\n';
<< '\n';
std::cout << out.str();
break;
Line 367 ⟶ 370:
for (int i = 0; i < n; ++i) {
char c = 'a' + i;
futures.push_back(std::async(std::launch::async,
std::async(std::launch::async, [&this, c]() { find_passwords(c); }));
}
}
Line 380 ⟶ 383:
pf.find_passwords(hashes);
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 392 ⟶ 395:
=={{header|Clojure}}==
{{libheader|clojure.math.combinatorics}}
<langsyntaxhighlight Clojurelang="clojure">(ns rosetta.brute-force
(:require [clojure.math.combinatorics :refer [selections]]) ;; https://github.com/clojure/math.combinatorics
(:import [java.util Arrays]
Line 472 ⟶ 475:
(some (partial check-candidate target-bytes sha256)
(selections space 5)))))))
</syntaxhighlight>
</lang>
{{out}}
<pre>Answer found for: 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b => apple
Line 481 ⟶ 484:
{{libheader|lparallel}}
{{libheader|ironclad}}
<langsyntaxhighlight lang="lisp">(defpackage #:parallel-brute-force
(:use #:cl
#:lparallel))
Line 526 ⟶ 529:
(end-kernel))))
(dolist (r results)
(format t "~A: ~A~%" (first r) (second r)))))</langsyntaxhighlight>
{{out}}
<pre>apple: 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b
mmmmm: 74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f
zyzzx: 1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad</pre>
 
=={{header|Erlang}}==
There are a total of 8 tasks, each handling a different set of prefixes (abc, def, ghi, jkl, mno, pqr, stuv, wxyz)
<lang Erlang>
#! /usr/bin/escript
-mode(compile).
-export([cracker/4, supervisor/3]).
 
hexdigit(N) when (N >= 0) and (N =< 9) -> N + $0;
hexdigit(N) when (N >= 10) and (N < 16) -> N - 10 + $a.
 
hexbyte(N) -> [hexdigit(N bsr 4), hexdigit(N band 15)].
 
match(Key, Hash) ->
B = crypto:hash(sha256, Key),
Hash == lists:append([hexbyte(X) || <<X:8/integer>> <= B]).
 
cracker(Prefixes, Rest, Hashes, Boss) ->
Results = [[[P|Q], Hash]
|| P <- Prefixes, Q <- Rest, Hash <- Hashes, match([P|Q], Hash)],
Boss ! {done, Results}.
 
supervisor(0, Results, Caller) -> Caller ! {done, Results};
supervisor(Tasks, Results, Caller) ->
receive
{done, Cracked} -> supervisor(Tasks - 1, Cracked ++ Results, Caller)
end.
 
main(_) ->
Tasks = ["abc", "def", "ghi", "jkl", "mno", "pqr", "stuv", "wxyz"],
Letter = lists:seq($a, $z),
Rest = [[B, C, D, E] || B <- Letter, C <- Letter, D <- Letter, E <- Letter],
Hashes = [
"1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad",
"3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
"74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f"
],
Boss = spawn(?MODULE, supervisor, [length(Tasks), [], self()]),
[spawn(?MODULE, cracker, [Prefixes, Rest, Hashes, Boss])
|| Prefixes <- Tasks],
 
receive
{done, Results} -> Results
end,
 
[io:format("~s: ~s~n", Result) || Result <- Results].
</lang>
{{Out}}
<pre>
$ ./par-brute.erl
zyzzx: 1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad
mmmmm: 74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f
apple: 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b
</pre>
 
=={{header|D}}==
There is at least one more method not shown for doing the task in parallel, which uses the std.concurrency module instead.
<langsyntaxhighlight Dlang="d">import std.digest.sha;
import std.parallelism;
import std.range;
Line 641 ⟶ 590:
 
return true;
}</langsyntaxhighlight>
 
{{out}}
Line 649 ⟶ 598:
mmmmm <=> 74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f
zyzzx <=> 1115dd80feaacefdf481f1f9070374a2a81e27880f187396db67958b27cbad</pre>
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{libheader| System.Threading}}
{{libheader| DCPsha256}}[[https://github.com/StephenGenusa/DCPCrypt]]
<syntaxhighlight lang="delphi">
program Parallel_Brute_Force;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils,
System.Threading,
DCPsha256;
 
function Sha256(W: string): string;
var
HashDigest: array[0..31] of byte;
d, i: Byte;
begin
Result := '';
with TDCP_sha256.Create(nil) do
begin
Init;
UpdateStr(W);
final(HashDigest[0]);
for i := 0 to High(HashDigest) do
Result := Result + lowercase(HashDigest[i].ToHexString(2));
end;
end;
 
procedure Force(a: int64);
var
password: string;
hash: string;
i, j, k, l: integer;
w: string;
const
Words: TArray<string> = ['1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad',
'3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b',
'74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f'];
begin
password := ' ';
password[1] := chr(97 + a);
 
for i := 97 to 122 do
begin
password[2] := chr(i);
for j := 97 to 122 do
begin
password[3] := chr(j);
for k := 97 to 122 do
begin
password[4] := chr(k);
for l := 97 to 122 do
begin
password[5] := chr(l);
hash := Sha256(password);
 
for w in Words do
begin
if SameText(hash, w) then
begin
Writeln('>>', password, ' => ', hash);
end;
end;
end;
end;
end;
end;
end;
 
var
s: string;
begin
 
TParallel.&For(0, 25, Force);
 
Writeln('Enter to exit');
readln;
end.</syntaxhighlight>
 
=={{header|Elixir}}==
<syntaxhighlight lang="elixir">
defmodule RosettacodeBruteForce do
require Logger
 
@spec start() :: :ok
def start() do
children = [
{Task.Supervisor, name: Bf.TaskSupervisor}
]
Supervisor.start_link(children, strategy: :one_for_one)
start_bf("1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad")
start_bf("3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b")
start_bf("74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f")
:ok
end
 
@spec start_bf(String.t()) :: :ok
def start_bf(target) do
Enum.each(0..25, fn a ->
Enum.each(0..25, fn b ->
Task.Supervisor.async(Bf.TaskSupervisor, fn ->
solve_bf(a, b, target)
end)
end)
end)
:ok
end
 
defp solve_bf(a, b, target) do
Enum.each(0..25, fn x ->
Enum.each(0..25, fn y ->
Enum.each(0..25, fn z ->
candidate = List.to_string([?a + a, ?a + b, ?a + x, ?a + y, ?a + z])
if (check_hash?(candidate, target)) do
Logger.info("SOLVED: #{candidate} = #{target}")
end
end)
end)
end)
:ok
end
 
defp check_hash?(candidate, target) do
target == :crypto.hash(:sha256, candidate)
|> Base.encode16()
|> String.downcase()
end
end
</syntaxhighlight>
{{out}}
<pre>
08:19:43.178 [info] SOLVED: apple = 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b
08:19:43.489 [info] SOLVED: zyzzx = 1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad
08:19:50.224 [info] SOLVED: mmmmm = 74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f
</pre>
 
=={{header|Erlang}}==
There are a total of 8 tasks, each handling a different set of prefixes (abc, def, ghi, jkl, mno, pqr, stuv, wxyz)
<syntaxhighlight lang="erlang">
#! /usr/bin/escript
-mode(compile).
-export([cracker/4, supervisor/3]).
 
hexdigit(N) when (N >= 0) and (N =< 9) -> N + $0;
hexdigit(N) when (N >= 10) and (N < 16) -> N - 10 + $a.
 
hexbyte(N) -> [hexdigit(N bsr 4), hexdigit(N band 15)].
 
match(Key, Hash) ->
B = crypto:hash(sha256, Key),
Hash == lists:append([hexbyte(X) || <<X:8/integer>> <= B]).
 
cracker(Prefixes, Rest, Hashes, Boss) ->
Results = [[[P|Q], Hash]
|| P <- Prefixes, Q <- Rest, Hash <- Hashes, match([P|Q], Hash)],
Boss ! {done, Results}.
 
supervisor(0, Results, Caller) -> Caller ! {done, Results};
supervisor(Tasks, Results, Caller) ->
receive
{done, Cracked} -> supervisor(Tasks - 1, Cracked ++ Results, Caller)
end.
 
main(_) ->
Tasks = ["abc", "def", "ghi", "jkl", "mno", "pqr", "stuv", "wxyz"],
Letter = lists:seq($a, $z),
Rest = [[B, C, D, E] || B <- Letter, C <- Letter, D <- Letter, E <- Letter],
Hashes = [
"1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad",
"3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
"74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f"
],
Boss = spawn(?MODULE, supervisor, [length(Tasks), [], self()]),
[spawn(?MODULE, cracker, [Prefixes, Rest, Hashes, Boss])
|| Prefixes <- Tasks],
 
receive
{done, Results} -> Results
end,
 
[io:format("~s: ~s~n", Result) || Result <- Results].
</syntaxhighlight>
{{Out}}
<pre>
$ ./par-brute.erl
zyzzx: 1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad
mmmmm: 74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f
apple: 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b
</pre>
 
=={{header|F_Sharp|F#}}==
<langsyntaxhighlight lang="fsharp">
(*
Nigel Galloway February 21st., 2017
Line 673 ⟶ 813:
 
for r in n1.Result@n2.Result@n3.Result@n4.Result@n5.Result@n6.Result@n7.Result@n8.Result do printfn "%s" r
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 680 ⟶ 820:
apple
zyzzx
</pre>
 
=={{header|FreeBASIC}}==
{{trans|Visual_Basic_.NET}}
{{trans|BaCon}}
<syntaxhighlight lang="freebasic">Function SHA_256(Byval message As String) As String
#Macro Ch (x, y, z)
(((x) And (y)) Xor ((Not (x)) And z))
#EndMacro
#Macro Maj (x, y, z)
(((x) And (y)) Xor ((x) And (z)) Xor ((y) And (z)))
#EndMacro
#Macro sigma0 (x)
(((x) Shr 2 Or (x) Shl 30) Xor ((x) Shr 13 Or (x) Shl 19) Xor ((x) Shr 22 Or (x) Shl 10))
#EndMacro
#Macro sigma1 (x)
(((x) Shr 6 Or (x) Shl 26) Xor ((x) Shr 11 Or (x) Shl 21) Xor ((x) Shr 25 Or (x) Shl 7))
#EndMacro
#Macro sigma2 (x)
(((x) Shr 7 Or (x) Shl 25) Xor ((x) Shr 18 Or (x) Shl 14) Xor ((x) Shr 3))
#EndMacro
#Macro sigma3 (x)
(((x) Shr 17 Or (x) Shl 15) Xor ((x) Shr 19 Or (x) Shl 13) Xor ((x) Shr 10))
#EndMacro
Dim As Long i, j
Dim As Ubyte Ptr ww1
Dim As Uinteger<32> Ptr ww4
Dim As Ulongint l = Len(message)
' set the first bit after the message to 1
message = message + Chr(1 Shl 7)
' add one char to the length
Dim As Ulong padding = 64 - ((l + 1) Mod (512 \ 8))
' check if we have enough room for inserting the length
If padding < 8 Then padding += 64
message += String(padding, Chr(0)) ' adjust length
Dim As Ulong l1 = Len(message) ' new length
l = l * 8 ' orignal length in bits
' create ubyte ptr to point to l ( = length in bits)
Dim As Ubyte Ptr ub_ptr = Cast(Ubyte Ptr, @l)
For i = 0 To 7 'copy length of message to the last 8 bytes
message[l1 -1 - i] = ub_ptr[i]
Next
'table of constants
Dim As Uinteger<32> K(0 To ...) = { _
&H428a2f98, &H71374491, &Hb5c0fbcf, &He9b5dba5, &H3956c25b, &H59f111f1, _
&H923f82a4, &Hab1c5ed5, &Hd807aa98, &H12835b01, &H243185be, &H550c7dc3, _
&H72be5d74, &H80deb1fe, &H9bdc06a7, &Hc19bf174, &He49b69c1, &Hefbe4786, _
&H0fc19dc6, &H240ca1cc, &H2de92c6f, &H4a7484aa, &H5cb0a9dc, &H76f988da, _
&H983e5152, &Ha831c66d, &Hb00327c8, &Hbf597fc7, &Hc6e00bf3, &Hd5a79147, _
&H06ca6351, &H14292967, &H27b70a85, &H2e1b2138, &H4d2c6dfc, &H53380d13, _
&H650a7354, &H766a0abb, &H81c2c92e, &H92722c85, &Ha2bfe8a1, &Ha81a664b, _
&Hc24b8b70, &Hc76c51a3, &Hd192e819, &Hd6990624, &Hf40e3585, &H106aa070, _
&H19a4c116, &H1e376c08, &H2748774c, &H34b0bcb5, &H391c0cb3, &H4ed8aa4a, _
&H5b9cca4f, &H682e6ff3, &H748f82ee, &H78a5636f, &H84c87814, &H8cc70208, _
&H90befffa, &Ha4506ceb, &Hbef9a3f7, &Hc67178f2 }
Dim As Uinteger<32> h0 = &H6a09e667
Dim As Uinteger<32> h1 = &Hbb67ae85
Dim As Uinteger<32> h2 = &H3c6ef372
Dim As Uinteger<32> h3 = &Ha54ff53a
Dim As Uinteger<32> h4 = &H510e527f
Dim As Uinteger<32> h5 = &H9b05688c
Dim As Uinteger<32> h6 = &H1f83d9ab
Dim As Uinteger<32> h7 = &H5be0cd19
Dim As Uinteger<32> a, b, c, d, e, f, g, h
Dim As Uinteger<32> t1, t2, w(0 To 63)
For j = 0 To (l1 -1) \ 64 ' split into block of 64 bytes
ww1 = Cast(Ubyte Ptr, @message[j * 64])
ww4 = Cast(Uinteger<32> Ptr, @message[j * 64])
For i = 0 To 60 Step 4 'little endian -> big endian
Swap ww1[i ], ww1[i +3]
Swap ww1[i +1], ww1[i +2]
Next i
For i = 0 To 15 ' copy the 16 32bit block into the array
W(i) = ww4[i]
Next i
For i = 16 To 63 ' fill the rest of the array
w(i) = sigma3(W(i -2)) + W(i -7) + sigma2(W(i -15)) + W(i -16)
Next i
a = h0 : b = h1 : c = h2 : d = h3 : e = h4 : f = h5 : g = h6 : h = h7
For i = 0 To 63
t1 = h + sigma1(e) + Ch(e, f, g) + K(i) + W(i)
t2 = sigma0(a) + Maj(a, b, c)
h = g : g = f : f = e
e = d + t1
d = c : c = b : b = a
a = t1 + t2
Next i
h0 += a : h1 += b : h2 += c : h3 += d
h4 += e : h5 += f : h6 += g : h7 += h
Next j
Dim As String answer = Hex(h0, 8) + Hex(h1, 8) + Hex(h2, 8) + Hex(h3, 8)
answer += Hex(h4, 8) + Hex(h5, 8) + Hex(h6, 8) + Hex(h7, 8)
Return Lcase(answer)
End Function
 
Dim t0 As Double = Timer
Dim Shared sha256fp(0 To 2) As String
sha256fp(0) = "1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad"
sha256fp(1) = "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b"
sha256fp(2) = "74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f"
 
Sub PrintCode(n As Integer)
Dim As String fp = sha256fp(n)
Dim As Integer c1, c2, c3, c4, c5
For c1 = 97 To 122
For c2 = 97 To 122
For c3 = 97 To 122
For c4 = 97 To 122
For c5 = 97 To 122
If fp = SHA_256(Chr(c1)+Chr(c2)+Chr(c3)+Chr(c4)+Chr(c5)) Then
Print Chr(c1)+Chr(c2)+Chr(c3)+Chr(c4)+Chr(c5); " => "; fp
Exit For, For, For, For, For
End If
Next c5
Next c4
Next c3
Next c2
Next c1
End Sub
 
For i As Byte= 0 to 2
PrintCode(i)
Next i
Sleep</syntaxhighlight>
 
=={{header|Frink}}==
This does not use any parallel processing but just demonstrates Frink's built-in password hashing.
<syntaxhighlight lang="frink">hashes = new set["1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad",
"3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
"74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f"]
 
r = new range["a", "z"]
multifor array = [r,r,r,r,r]
{
str = join["", array]
hash = messageDigest[str, "SHA-256"]
if hashes.contains[hash]
println["$str: $hash"]
}</syntaxhighlight>
{{out}}
<pre>
apple: 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b
mmmmm: 74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f
zyzzx: 1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad
</pre>
 
Line 685 ⟶ 991:
This solution runs 26 goroutines, one for each possible password first letter.
Goroutines run in parallel on a multicore system.
<langsyntaxhighlight lang="go">package main
 
import (
Line 736 ⟶ 1,042:
return
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 749 ⟶ 1,055:
<li>monad-par</li>
<li>bytestring</li>
<li>text</li>
<li>split</li>
</ul>
<br/>
Compile with "-O2 -threaded"<br/>
<lang haskell>import Crypto.Hash (hashWith, SHA256 (..), Digest, digestFromByteString)
7.391s elapsed on a 2.5 GHz Dual-Core Intel Core i7 Macbook Pro.
import Control.Monad (replicateM, join)
<syntaxhighlight lang="haskell">import Control.Concurrent (setNumCapabilities)
import Crypto.Hash (hashWith, SHA256 (..), Digest)
import Control.Monad (replicateM, join, (>=>))
import Control.Monad.Par (runPar, get, spawnP)
import Data.Text ByteString (Text, pack)
import Data.Text.Encoding (encodeUtf8)
import Data.List.Split (chunksOf)
import GHC.Conc (getNumProcessors)
import Text.Printf (printf)
 
Line 765 ⟶ 1,073:
[ "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b"
, "74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f"
, "1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad" ]
]
 
bruteForce :: Int -> [(String, String)]
wordVariations :: [Text]
bruteForce n = runPar $ join <$>
wordVariations = pack <$> replicateM 5 ['a'..'z']
(mapM (spawnP . foldr findMatch []) >=> mapM get) chunks
 
bruteForce :: [Text] -> [(String, Text)]
bruteForce xs = runPar $ do
pars <- mapM (spawnP . foldr findMatch []) chunks
result <- mapM get pars
pure $ join result
where
chunks = chunksOf (26 ^ 5 `div` 10n) xs$ replicateM 5 [97..122]
findMatch s accum
| hashed `elem` hashedValues = (show hashed, sshow bStr) : accum
| otherwise = accum
where
hashedbStr = hashWith SHA256 (encodeUtf8pack s)
hashed = hashWith SHA256 bStr
 
main :: IO ()
main = do
main = mapM_ (uncurry (printf "%s -> %s\n")) (bruteForce wordVariations)</lang>
cpus <- getNumProcessors
setNumCapabilities cpus
printf "Using %d cores\n" cpus
mapM_ (uncurry (printf "%s -> %s\n")) (bruteForce cpus)</syntaxhighlight>
{{out}}
<pre>brute
<pre>3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b -> apple
Using 4 cores
3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b -> apple
74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f -> mmmmm
1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad -> zyzzx
</pre>
Or using worker threads with buffered read/write channels.
 
<p>Here all the possible test strings are batched as a stream that is fed to worker threads via a single read channel (batchChan). Each worker thread listens to the read channel (batchChan) and will write to the write channel (resultChan) when it finds a match. The worker threads loop indefinitely returning to read the next message on the read channel (batchChan). The main thread listens to the write channel (resultChan) and terminates once all three messages have been received.</p>
<syntaxhighlight lang="haskell">import Control.Concurrent (forkIO, setNumCapabilities)
import Control.Concurrent.Chan (Chan, newChan, readChan, writeList2Chan)
import Control.Monad (replicateM, replicateM_, forever)
import Crypto.Hash (SHA256(..), Digest, hashWith)
import Data.Bifunctor (first)
import Data.ByteString (ByteString, pack)
import Data.Char (isDigit)
import Data.List.Split (chunksOf)
import Data.Word (Word8)
import GHC.Conc (getNumProcessors)
import System.Environment (getArgs)
import Text.Printf (printf)
 
type Decrypted = String
type Encrypted = Digest SHA256
type TestString = [Word8]
 
hashedValues :: [Encrypted]
hashedValues = read <$>
[ "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b"
, "74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f"
, "1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad" ]
 
chunks :: [[TestString]]
chunks = chunksOf (10^3) $ replicateM 5 [97..122]
 
findMatch :: TestString -> [(Encrypted, Decrypted)] -> [(Encrypted, Decrypted)]
findMatch w acc
| hashed `elem` hashedValues = (hashed, show bStr):acc
| otherwise = acc
where
bStr = pack w
hashed = hashWith SHA256 bStr
 
searchWorker :: Chan [TestString] -> Chan (Encrypted, Decrypted) -> IO ()
searchWorker batchChan resultChan = forever (readChan batchChan >>= writeList2Chan resultChan . foldr findMatch [])
 
parseInput :: [String] -> Int -> Int
parseInput [] n = n
parseInput (s:_) n = if all isDigit s then read s else n
 
main :: IO ()
main = do
workers <- getArgs
cpus <- getNumProcessors
let wCount = parseInput workers cpus
setNumCapabilities wCount
printf "Using %d workers on %d cpus.\n" wCount cpus
resultChan <- newChan
batchChan <- newChan
replicateM_ wCount (forkIO $ searchWorker batchChan resultChan)
writeList2Chan batchChan chunks
replicateM_ (length hashedValues) (readChan resultChan >>= uncurry (printf "%s -> %s\n") . first show)</syntaxhighlight>
{{out}}
<pre>brute2
Using 4 workers on 4 cpus.
3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b -> "apple"
74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f -> "mmmmm"
1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad -> "zyzzx"</pre>
 
=={{header|Java}}==
Line 797 ⟶ 1,168:
This implementation runs 3 threads (one per hash to crack), and short-stops when a match for a hash is found.
 
<langsyntaxhighlight Javalang="java">import javax.xml.bind.DatatypeConverter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
Line 892 ⟶ 1,263:
 
 
</syntaxhighlight>
</lang>
{{out}}<pre>Hash 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b has the following match : apple
Hash 74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f has the following match : mmmmm
Line 899 ⟶ 1,270:
===Faster Alternative Version===
Combines ideas from the C++ solution and the above Java version. Execution time is about 1.6 seconds on my system (3.2 GHz Quad-Core Intel Core i5, macOS 10.15.3).
<langsyntaxhighlight Javalang="java">import javax.xml.bind.DatatypeConverter;
import java.security.*;
import java.util.*;
Line 980 ⟶ 1,351:
private byte[][] digests;
private AtomicInteger count = new AtomicInteger();
}</langsyntaxhighlight>
{{out}}
<pre>
Line 989 ⟶ 1,360:
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">@everywhere using SHA
 
@everywhere function bruteForceRange(startSerial, numberToDo)
Line 1,010 ⟶ 1,381:
@everywhere perThread = div(26^5, Sys.CPU_CORES)
pmap(x -> bruteForceRange(x * perThread, perThread), 0:Sys.CPU_CORES-1)
</syntaxhighlight>
</lang>
{{out}}<pre>From worker 2: apple --> 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b
From worker 3: zyzzx --> 1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad
Line 1,017 ⟶ 1,388:
=={{header|Kotlin}}==
{{trans|C#}}
<langsyntaxhighlight lang="scala">// version 1.1.51
 
import java.security.MessageDigest
Line 1,069 ⟶ 1,440:
}
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,078 ⟶ 1,449:
</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
 
<langsyntaxhighlight Mathematicalang="mathematica">testPassword[pass_String] :=
If[MemberQ[{16^^1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad,
16^^3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b,
Line 1,090 ⟶ 1,461:
ParallelDo[
testPassword[StringJoin[a, b, c, d, e]],
{a, chars}, {b, chars}, {c, chars}, {d, chars}, {e, chars}]</langsyntaxhighlight>
 
=={{header|Modula-2}}==
<langsyntaxhighlight lang="modula2">MODULE PBF;
FROM FormatString IMPORT FormatString;
FROM SHA256 IMPORT SHA256,Create,Destroy,HashBytes,Finalize,GetHash;
Line 1,257 ⟶ 1,628:
WriteLn;
ReadChar
END PBF.</langsyntaxhighlight>
{{out}}
<pre>apple 3A7BD3E2360A3D29EEA436FCFB7E44C735D117C42D1C1835420B6B9942DD4F1B
Line 1,263 ⟶ 1,634:
zyzzx 1115DD800FEAACEFDF481F1F9070374A2A81E27880F187396DB67958B207CBAD
Done</pre>
 
=={{header|Nim}}==
{{libheader|Nimcrypto}}
Using a thread for each starting character.
Note that the program must be compiled with option --threads:on.
<syntaxhighlight lang="nim">import strutils, threadpool
import nimcrypto
 
const
 
# List of hexadecimal representation of target hashes.
HexHashes = ["1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad",
"3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
"74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f"]
 
# List of target hashes.
Hashes = [MDigest[256].fromHex(HexHashes[0]),
MDigest[256].fromHex(HexHashes[1]),
MDigest[256].fromHex(HexHashes[2])]
 
Letters = 'a'..'z'
 
 
proc findHashes(a: char) =
## Build the arrays of five characters starting with the value
## of "a" and check if their hash matches one of the targets.
## Print the string and the hash value if a match is found.
for b in Letters:
for c in Letters:
for d in Letters:
for e in Letters:
let s = [a, b, c, d, e]
let h = sha256.digest(s)
for i, target in Hashes:
if h == target: # Match.
echo s.join(), " → ", HexHashes[i]
 
 
# Launch a thread for each starting character.
for a in Letters:
spawn findHashes(a)
 
sync()</syntaxhighlight>
 
{{out}}
<pre>apple → 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b
mmmmm → 74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f
zyzzx → 1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad</pre>
 
=={{header|Perl}}==
Uses threads library to do naive search using 26 threads ("aaaaa" .. "azzzz", "baaaa" .. "bzzzz", etc.). No effort is made to early exit.
<langsyntaxhighlight lang="perl">use Digest::SHA qw/sha256_hex/;
use threads;
use threads::shared;
Line 1,293 ⟶ 1,712:
$s++;
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,303 ⟶ 1,722:
=={{header|Phix}}==
Each thread processes one start letter at a time, until they are all done.
<!--<syntaxhighlight lang="phix">(notonline)-->
<lang Phix>include builtins\sha256.e
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">\</span><span style="color: #000000;">sha256</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
include builtins\VM\pThreadN.e -- (shd not be rqd on 0.8.1+)
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">\</span><span style="color: #000000;">VM</span><span style="color: #0000FF;">\</span><span style="color: #000000;">pThreadN</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span> <span style="color: #000080;font-style:italic;">-- (shd not be rqd on 0.8.1+)</span>
function asHex(string s)
<span style="color: #008080;">function</span> <span style="color: #000000;">asHex</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
string res = ""
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
for i=1 to length(s) do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
res &= sprintf("%02X",s[i])
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%02X"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
return res
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
sequence starts
<span style="color: #004080;">sequence</span> <span style="color: #000000;">starts</span>
constant start_cs = init_cs(), -- critical section
<span style="color: #008080;">constant</span> <span style="color: #000000;">start_cs</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">init_cs</span><span style="color: #0000FF;">(),</span> <span style="color: #000080;font-style:italic;">-- critical section</span>
hashes = {x"1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad",
<span style="color: #000000;">hashes</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">x</span><span style="color: #008000;">"1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad"</span><span style="color: #0000FF;">,</span>
x"3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
<span style="color: #000000;">x</span><span style="color: #008000;">"3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b"</span><span style="color: #0000FF;">,</span>
x"74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f"}
<span style="color: #000000;">x</span><span style="color: #008000;">"74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f"</span><span style="color: #0000FF;">}</span>
 
procedure find_passwords()
<span style="color: #008080;">procedure</span> <span style="color: #000000;">find_passwords</span><span style="color: #0000FF;">()</span>
sequence thrashes = {} -- thread-safe copy of hashes
<span style="color: #004080;">sequence</span> <span style="color: #000000;">thrashes</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span> <span style="color: #000080;font-style:italic;">-- thread-safe copy of hashes</span>
enter_cs(start_cs)
<span style="color: #7060A8;">enter_cs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">start_cs</span><span style="color: #0000FF;">)</span>
for i=1 to length(hashes) do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">hashes</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
thrashes = append(thrashes,thread_safe_string(hashes[i]))
<span style="color: #000000;">thrashes</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">thrashes</span><span style="color: #0000FF;">,</span><span style="color: #000000;">thread_safe_string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">hashes</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]))</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
leave_cs(start_cs)
<span style="color: #7060A8;">leave_cs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">start_cs</span><span style="color: #0000FF;">)</span>
while true do
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
string pwd
<span style="color: #004080;">string</span> <span style="color: #000000;">pwd</span>
enter_cs(start_cs)
<span style="color: #7060A8;">enter_cs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">start_cs</span><span style="color: #0000FF;">)</span>
if length(starts)=0 then
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">starts</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
leave_cs(start_cs)
<span style="color: #7060A8;">leave_cs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">start_cs</span><span style="color: #0000FF;">)</span>
exit
<span style="color: #008080;">exit</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
pwd = starts[$]&repeat('a',4)
<span style="color: #000000;">pwd</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">starts</span><span style="color: #0000FF;">[$]&</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'a'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)</span>
starts = starts[1..$-1]
<span style="color: #000000;">starts</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">starts</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
leave_cs(start_cs)
<span style="color: #7060A8;">leave_cs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">start_cs</span><span style="color: #0000FF;">)</span>
while length(pwd) do
<span style="color: #008080;">while</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pwd</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
string hash = sha256(pwd)
<span style="color: #004080;">string</span> <span style="color: #000000;">hash</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sha256</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pwd</span><span style="color: #0000FF;">)</span>
if find(hash,thrashes) then ?{pwd,asHex(hash)} end if
<span style="color: #008080;">if</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">hash</span><span style="color: #0000FF;">,</span><span style="color: #000000;">thrashes</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?{</span><span style="color: #000000;">pwd</span><span style="color: #0000FF;">,</span><span style="color: #000000;">asHex</span><span style="color: #0000FF;">(</span><span style="color: #000000;">hash</span><span style="color: #0000FF;">)}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
for i=5 to 2 by -1 do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">5</span> <span style="color: #008080;">to</span> <span style="color: #000000;">2</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
if pwd[i]!='z' then
<span style="color: #008080;">if</span> <span style="color: #000000;">pwd</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]!=</span><span style="color: #008000;">'z'</span> <span style="color: #008080;">then</span>
pwd[i] += 1
<span style="color: #000000;">pwd</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
exit
end if <span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
pwd[i] = 'a'
<span style="color: #000000;">pwd</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'a'</span>
if i=2 then pwd = "" exit end if
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">then</span> <span style="color: #000000;">pwd</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end while
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
end while
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
exit_thread(0)
<span style="color: #000000;">exit_thread</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
 
for nthreads=4 to 4 do
<span style="color: #008080;">for</span> <span style="color: #000000;">nthreads</span><span style="color: #0000FF;">=</span><span style="color: #000000;">4</span> <span style="color: #008080;">to</span> <span style="color: #000000;">4</span> <span style="color: #008080;">do</span>
atom t0 = time()
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
starts = tagset('a','z',-1)
<span style="color: #000000;">starts</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'a'</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'z'</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
sequence threads = {}
<span style="color: #004080;">sequence</span> <span style="color: #000000;">threads</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
for i=1 to nthreads do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">nthreads</span> <span style="color: #008080;">do</span>
threads = append(threads,create_thread(routine_id("find_passwords"),{}))
<span style="color: #000000;">threads</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">threads</span><span style="color: #0000FF;">,</span><span style="color: #000000;">create_thread</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">routine_id</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"find_passwords"</span><span style="color: #0000FF;">),{}))</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
wait_thread(threads)
<span style="color: #000000;">wait_thread</span><span style="color: #0000FF;">(</span><span style="color: #000000;">threads</span><span style="color: #0000FF;">)</span>
string e = elapsed(time()-t0)
<span style="color: #004080;">string</span> <span style="color: #000000;">e</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">)</span>
printf(1,"completed with %d threads in %s\n",{nthreads,e})
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"completed with %d threads in %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">nthreads</span><span style="color: #0000FF;">,</span><span style="color: #000000;">e</span><span style="color: #0000FF;">})</span>
end for</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}} (with nthreads loop from 1 to 4, and for that case CPU use in Task Manager shows a very clear step pattern.)
<pre>
Line 1,383 ⟶ 1,804:
completed with 4 threads in 12.7s
</pre>
 
=={{header|PureBasic}}==
<syntaxhighlight lang="purebasic">UseSHA2Fingerprint()
 
NewList sha256fp.s()
AddElement(sha256fp()) : sha256fp() = "1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad"
AddElement(sha256fp()) : sha256fp() = "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b"
AddElement(sha256fp()) : sha256fp() = "74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f"
Procedure PrintCode(n.i)
Shared sha256fp()
SelectElement(sha256fp(), n) : fp$ = sha256fp()
For c1 = 'a' To 'z'
For c2 = 'a' To 'z'
For c3 = 'a' To 'z'
For c4 = 'a' To 'z'
For c5 = 'a' To 'z'
If fp$ = StringFingerprint(Chr(c1) + Chr(c2) + Chr(c3) + Chr(c4) + Chr(c5), #PB_Cipher_SHA2, 256); maybe set enconding
PrintN(Chr(c1) + Chr(c2) + Chr(c3) + Chr(c4) + Chr(c5) + " => " + fp$)
Break(5)
EndIf
Next c5
Next c4
Next c3
Next c2
Next c1
EndProcedure
 
Dim mythread(ListSize(sha256fp()))
 
If OpenConsole("")
StartTime.q = ElapsedMilliseconds()
For i=0 To ListSize(sha256fp()) - 1
mythread(i)=CreateThread(@PrintCode(), i)
Next
For i=0 To ListSize(sha256fp()) - 1
WaitThread(mythread(i))
Next
 
PrintN("-----------")
PrintN(Str(ElapsedMilliseconds() - StartTime)+" Milliseconds needed")
Input()
EndIf
End
; EnableThread</syntaxhighlight>
{{out}}
<pre>apple => 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b
mmmmm => 74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f
zyzzx => 1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad
-----------
36955 Milliseconds needed</pre>
 
=={{header|Python}}==
 
<langsyntaxhighlight lang="python">import multiprocessing
from hashlib import sha256
 
h1 = bytes().fromhex("1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad")
h2 = bytes().fromhex("3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b")
h3 = bytes().fromhex("74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f")
 
def brute(firstletterascii: int):
def HashFromSerial(serial):
divisorglobal =h1, 456976h2, h3
letters = []bytearray(5)
letters[0] = firstletterascii
for i in range(5):
for letters[1] in range(97, 97 + 26):
letter, serial = divmod(serial, divisor)
for letters.append[2] in range(97, 97 + int(letter) 26):
divisor /= for letters[3] in range(97, 97 + 26):
return ( for letters,[4] sha256in range(bytes(letters)).digest()97, 97 + 26):
digest = sha256(letters).digest()
 
if digest == h1 or digest == h2 or digest == h3:
password = "".join(chr(x) for x in letters)
print(password + " => " + digest.hex())
return 0
 
def main():
h1 = bytes().fromhex("1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad")
h2 = bytes().fromhex("3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b")
h3 = bytes().fromhex("74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f")
numpasswords = int(26 ** 5)
chunksize = int(numpasswords / multiprocessing.cpu_count())
with multiprocessing.Pool() as p:
for (letters, digest) in p.imap_unorderedmap(HashFromSerialbrute, range(numpasswords)97, chunksize97 + 26)):
if digest == h1 or digest == h2 or digest == h3:
password = "".join(chr(x) for x in letters)
print(password + " => " + digest.hex())
 
 
if __name__ == "__main__":
main()</langsyntaxhighlight>
 
{{out}}
Line 1,426 ⟶ 1,897:
the single threaded version.
 
<langsyntaxhighlight lang="racket">#lang racket/base
(require racket/place
racket/list
Line 1,524 ⟶ 1,995:
.
#"\21\25\335\200\17\352\254\357\337H\37\37\220p7J*\201\342x\200\361\2079m\266yX\262\a\313\255"))
"without parallelism, it works"))</langsyntaxhighlight>
 
{{out}}
Line 1,548 ⟶ 2,019:
(formerly Perl 6)
This solution can be changed from parallel to serial by removing the <code>.race</code> method.
<syntaxhighlight lang="raku" perl6line>use Digest::SHA256::Native;
constant @alpha2 = [X~] <a m p y z> xx 2;
constant @alpha3 = [X~] <e l m p x z> xx 3;
Line 1,566 ⟶ 2,037:
}
 
.say for flat @alpha2.race(:1batch).map: { find_it($_) };</langsyntaxhighlight>
{{Out}}
<pre>apple => 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b
Line 1,573 ⟶ 2,044:
 
Testers can adjust the run speed by replacing the @alpha constants with one of the below:
<syntaxhighlight lang="raku" line>
<lang perl6>
# True to actual RC task, but slowest
constant @alpha2 = 'aa' .. 'zz';
Line 1,581 ⟶ 2,052:
constant @alpha2 = [X~] <a m p y z> xx 2;
constant @alpha3 = [X~] <e l m p x z> xx 3;
</syntaxhighlight>
</lang>
 
=={{header|Rust}}==
Line 1,587 ⟶ 2,058:
In this solution the number of threads is the number of logical processors on the machine. `distribute_work()` distributes the work more or less equally between the threads.
 
<langsyntaxhighlight Rustlang="rust">// [dependencies]
// rust-crypto = "0.2.36"
// num_cpus = "1.7.0"
Line 1,706 ⟶ 2,177:
}
result.clone()
}</langsyntaxhighlight>
 
{{out}}
Line 1,722 ⟶ 2,193:
This example converts the collection of candidate strings into a ParVector as soon as possible, speeding up both the final step to generating the candidates and the search.
 
<langsyntaxhighlight lang="scala">import java.security.MessageDigest
 
import scala.collection.parallel.immutable.ParVector
Line 1,757 ⟶ 2,228:
digester.digest(str.getBytes("UTF-8")).map("%02x".format(_)).mkString
}
}</langsyntaxhighlight>
 
An unfortunate side-effect of jumping straight into a ParVector, though, is that the entire list of candidate strings must be computed before attempting to find a match. This means that even modestly large charsets and/or strings can make the memory usage and runtime blow up.
Line 1,765 ⟶ 2,236:
Notice that def is used in place of val when working with the list of candidates. This is because val holds onto the head, which means it would fill up memory over time with the backlog of candidates already checked. Using def lets the program discard candidates after they are checked.
 
<langsyntaxhighlight lang="scala">import java.security.MessageDigest
 
import scala.annotation.tailrec
Line 1,813 ⟶ 2,284:
digester.digest(str.getBytes("UTF-8")).map("%02x".format(_)).mkString
}
}</langsyntaxhighlight>
 
As a final example, we can clean this code up with some method chaining and currying to get this:
 
<langsyntaxhighlight lang="scala">import java.security.MessageDigest
 
import scala.collection.parallel.immutable.ParVector
Line 1,850 ⟶ 2,321:
.map(_.to(ParVector).find(str => getHash(str) == hash)) //Convert each chunk into a ParVector and search it
.collectFirst{case Some(res) => res} //Get the first hit if one is found
}</langsyntaxhighlight>
 
{{out}}
Line 1,866 ⟶ 2,337:
=={{header|Sidef}}==
{{trans|Perl}}
<langsyntaxhighlight lang="ruby">func invert_sha256(hash) {
 
var letters = @('a'..'z')
Line 1,894 ⟶ 2,365:
var phrase = invert_sha256(t)
say "#{t} : #{phrase}"
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,901 ⟶ 2,372:
74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f : mmmmm
</pre>
 
=={{header|Swift}}==
<syntaxhighlight lang="swift">import Foundation
import CryptoKit
 
extension String {
func hexdata() -> Data {
Data(stride(from: 0, to: count, by: 2).map {
let a = index(startIndex, offsetBy: $0)
let b = index(after: a)
return UInt8(self[a ... b], radix: 16)!
})
}
}
 
DispatchQueue.concurrentPerform(iterations: 26) { (a) in
let goal1 = "1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad".hexdata()
let goal2 = "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b".hexdata()
let goal3 = "74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f".hexdata()
var letters: [UInt8] = [(UInt8)(a + 97), 0, 0, 0, 0]
for b: UInt8 in 97...122 {
letters[1] = b
for c: UInt8 in 97...122 {
letters[2] = c
for d: UInt8 in 97...122 {
letters[3] = d
for e: UInt8 in 97...122 {
letters[4] = e
let digest = SHA256.hash(data: letters)
if digest == goal1 || digest == goal2 || digest == goal3 {
let password = String(bytes: letters, encoding: .ascii)!
let hexhash = digest.map { String(format: "%02x", $0) }.joined()
print("\(password) => \(hexhash)")
}
}
}
}
}
}</syntaxhighlight>
 
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<langsyntaxhighlight lang="vbnet">Imports System.Text
 
Module Module1
Line 1,956 ⟶ 2,466:
End Sub
 
End Module</langsyntaxhighlight>
{{out}}
<pre>mmmmm => 74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f
apple => 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b
zyzzx => 1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad</pre>
 
=={{header|Wren}}==
{{libheader|Wren-crypto}}
{{libheader|Wren-fmt}}
Wren supports concurrency by way of co-operatively scheduled fibers and, as required by the task description, the work has been divided up between 26 fibers with each fiber taking a different initial letter.
 
However, from an execution speed viewpoint, there is no point in doing so because Wren's VM is single threaded and can only run one fiber at a time. As it takes around 50 seconds on my machine to process a single initial letter (456,976 calls to sha256) this means that an overall runtime of about 22 minutes is needed to find the passwords corresponding to the 3 hashes.
 
Currently, parallel calculations are impossible in Wren-cli. However, if Wren is being embedded, it might be possible for a suitable host to run several Wren VM's in parallel and divide a task up between them to improve execution time.
<syntaxhighlight lang="wren">import "./crypto" for Sha256
 
var hashes = [
"1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad",
"3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
"74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f"
]
 
var findHash = Fn.new { |i|
var bytes = List.filled(5, 0)
var r = 97..122
bytes[0] = i
for (j in r) {
bytes[1] = j
for (k in r) {
bytes[2] = k
for (l in r) {
bytes[3] = l
for (m in r) {
bytes[4] = m
var d = Sha256.digest(bytes)
for (hash in hashes) {
if (hash == d) {
var s = bytes.map { |b| String.fromByte(b) }.join()
System.print("%(s) => %(d)")
hashes.remove(hash)
if (hashes.count == 0) return
}
}
}
}
}
}
}
 
for (i in 0..25) {
var fib = Fiber.new(findHash)
fib.call(97+i)
}</syntaxhighlight>
 
{{out}}
<pre>
apple => 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b
mmmmm => 74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f
zyzzx => 1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad
</pre>
 
=={{header|zkl}}==
Line 1,974 ⟶ 2,539:
Uses the message hashing extension library (DLL).
{{trans|==C sharp|C#}}
<langsyntaxhighlight lang="zkl">var [const] MsgHash=Import.lib("zklMsgHash");
var [const] gotEm=Atomic.Int(); // global signal for all threads
 
Line 1,994 ⟶ 2,559:
}
}
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">hashes:=T("3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
"74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f",
"1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad");
Line 2,009 ⟶ 2,574:
s+=n;
}
hashes2go.waitFor(0); // wait until all cracked, just exit, OS kills threads</langsyntaxhighlight>
<pre>
mmmmm --> 74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f
1

edit