Parallel brute force: Difference between revisions
Content added Content deleted
m (Minor edit to C++ code) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 15: | Line 15: | ||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
{{libheader|CryptAda}} |
{{libheader|CryptAda}} |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_IO; |
||
with CryptAda.Digests.Message_Digests.SHA_256; |
with CryptAda.Digests.Message_Digests.SHA_256; |
||
Line 86: | Line 86: | ||
Work := new Worker (First => C); |
Work := new Worker (First => C); |
||
end loop; |
end loop; |
||
end Brute_Force;</ |
end Brute_Force;</syntaxhighlight> |
||
=={{header|BaCon}}== |
=={{header|BaCon}}== |
||
< |
<syntaxhighlight lang="qbasic">PRAGMA INCLUDE <openssl/sha.h> |
||
PRAGMA LDFLAGS -lcrypto |
PRAGMA LDFLAGS -lcrypto |
||
Line 134: | Line 134: | ||
NEXT |
NEXT |
||
NEXT |
NEXT |
||
WEND</ |
WEND</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 144: | Line 144: | ||
=={{header|C}}== |
=={{header|C}}== |
||
{{trans|C#}} |
{{trans|C#}} |
||
< |
<syntaxhighlight lang="c">// $ gcc -o parabrutfor parabrutfor.c -fopenmp -lssl -lcrypto |
||
// $ export OMP_NUM_THREADS=4 |
// $ export OMP_NUM_THREADS=4 |
||
// $ ./parabrutfor |
// $ ./parabrutfor |
||
Line 214: | Line 214: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>apple => 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b |
<pre>apple => 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b |
||
Line 222: | Line 222: | ||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
using System.Linq; |
using System.Linq; |
||
using System.Text; |
using System.Text; |
||
Line 262: | Line 262: | ||
return true; |
return true; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 271: | Line 271: | ||
=={{header|C++}}== |
=={{header|C++}}== |
||
{{libheader|OpenSSL}} |
{{libheader|OpenSSL}} |
||
< |
<syntaxhighlight lang="cpp">#include <atomic> |
||
#include <cstdio> |
#include <cstdio> |
||
#include <cstring> |
#include <cstring> |
||
Line 383: | Line 383: | ||
pf.find_passwords(hashes); |
pf.find_passwords(hashes); |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 395: | Line 395: | ||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
{{libheader|clojure.math.combinatorics}} |
{{libheader|clojure.math.combinatorics}} |
||
< |
<syntaxhighlight lang="clojure">(ns rosetta.brute-force |
||
(:require [clojure.math.combinatorics :refer [selections]]) ;; https://github.com/clojure/math.combinatorics |
(:require [clojure.math.combinatorics :refer [selections]]) ;; https://github.com/clojure/math.combinatorics |
||
(:import [java.util Arrays] |
(:import [java.util Arrays] |
||
Line 475: | Line 475: | ||
(some (partial check-candidate target-bytes sha256) |
(some (partial check-candidate target-bytes sha256) |
||
(selections space 5))))))) |
(selections space 5))))))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre>Answer found for: 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b => apple |
<pre>Answer found for: 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b => apple |
||
Line 484: | Line 484: | ||
{{libheader|lparallel}} |
{{libheader|lparallel}} |
||
{{libheader|ironclad}} |
{{libheader|ironclad}} |
||
< |
<syntaxhighlight lang="lisp">(defpackage #:parallel-brute-force |
||
(:use #:cl |
(:use #:cl |
||
#:lparallel)) |
#:lparallel)) |
||
Line 529: | Line 529: | ||
(end-kernel)))) |
(end-kernel)))) |
||
(dolist (r results) |
(dolist (r results) |
||
(format t "~A: ~A~%" (first r) (second r)))))</ |
(format t "~A: ~A~%" (first r) (second r)))))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>apple: 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b |
<pre>apple: 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b |
||
Line 537: | Line 537: | ||
=={{header|D}}== |
=={{header|D}}== |
||
There is at least one more method not shown for doing the task in parallel, which uses the std.concurrency module instead. |
There is at least one more method not shown for doing the task in parallel, which uses the std.concurrency module instead. |
||
< |
<syntaxhighlight lang="d">import std.digest.sha; |
||
import std.parallelism; |
import std.parallelism; |
||
import std.range; |
import std.range; |
||
Line 590: | Line 590: | ||
return true; |
return true; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 602: | Line 602: | ||
{{libheader| System.Threading}} |
{{libheader| System.Threading}} |
||
{{libheader| DCPsha256}}[[https://github.com/StephenGenusa/DCPCrypt]] |
{{libheader| DCPsha256}}[[https://github.com/StephenGenusa/DCPCrypt]] |
||
<syntaxhighlight lang="delphi"> |
|||
<lang Delphi> |
|||
program Parallel_Brute_Force; |
program Parallel_Brute_Force; |
||
Line 677: | Line 677: | ||
Writeln('Enter to exit'); |
Writeln('Enter to exit'); |
||
readln; |
readln; |
||
end.</ |
end.</syntaxhighlight> |
||
=={{header|Erlang}}== |
=={{header|Erlang}}== |
||
There are a total of 8 tasks, each handling a different set of prefixes (abc, def, ghi, jkl, mno, pqr, stuv, wxyz) |
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"> |
|||
<lang Erlang> |
|||
#! /usr/bin/escript |
#! /usr/bin/escript |
||
-mode(compile). |
-mode(compile). |
||
Line 724: | Line 724: | ||
[io:format("~s: ~s~n", Result) || Result <- Results]. |
[io:format("~s: ~s~n", Result) || Result <- Results]. |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
Line 734: | Line 734: | ||
=={{header|F_Sharp|F#}}== |
=={{header|F_Sharp|F#}}== |
||
< |
<syntaxhighlight lang="fsharp"> |
||
(* |
(* |
||
Nigel Galloway February 21st., 2017 |
Nigel Galloway February 21st., 2017 |
||
Line 756: | Line 756: | ||
for r in n1.Result@n2.Result@n3.Result@n4.Result@n5.Result@n6.Result@n7.Result@n8.Result do printfn "%s" r |
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}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 768: | Line 768: | ||
{{trans|Visual_Basic_.NET}} |
{{trans|Visual_Basic_.NET}} |
||
{{trans|BaCon}} |
{{trans|BaCon}} |
||
< |
<syntaxhighlight lang="freebasic">Function SHA_256(Byval message As String) As String |
||
#Macro Ch (x, y, z) |
#Macro Ch (x, y, z) |
||
(((x) And (y)) Xor ((Not (x)) And z)) |
(((x) And (y)) Xor ((Not (x)) And z)) |
||
Line 908: | Line 908: | ||
PrintCode(i) |
PrintCode(i) |
||
Next i |
Next i |
||
Sleep</ |
Sleep</syntaxhighlight> |
||
=={{header|Frink}}== |
=={{header|Frink}}== |
||
This does not use any parallel processing but just demonstrates Frink's built-in password hashing. |
This does not use any parallel processing but just demonstrates Frink's built-in password hashing. |
||
< |
<syntaxhighlight lang="frink">hashes = new set["1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad", |
||
"3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b", |
"3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b", |
||
"74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f"] |
"74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f"] |
||
Line 923: | Line 923: | ||
if hashes.contains[hash] |
if hashes.contains[hash] |
||
println["$str: $hash"] |
println["$str: $hash"] |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 934: | Line 934: | ||
This solution runs 26 goroutines, one for each possible password first letter. |
This solution runs 26 goroutines, one for each possible password first letter. |
||
Goroutines run in parallel on a multicore system. |
Goroutines run in parallel on a multicore system. |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 985: | Line 985: | ||
return |
return |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,003: | Line 1,003: | ||
Compile with "-O2 -threaded"<br/> |
Compile with "-O2 -threaded"<br/> |
||
7.391s elapsed on a 2.5 GHz Dual-Core Intel Core i7 Macbook Pro. |
7.391s elapsed on a 2.5 GHz Dual-Core Intel Core i7 Macbook Pro. |
||
< |
<syntaxhighlight lang="haskell">import Control.Concurrent (setNumCapabilities) |
||
import Crypto.Hash (hashWith, SHA256 (..), Digest) |
import Crypto.Hash (hashWith, SHA256 (..), Digest) |
||
import Control.Monad (replicateM, join, (>=>)) |
import Control.Monad (replicateM, join, (>=>)) |
||
Line 1,035: | Line 1,035: | ||
setNumCapabilities cpus |
setNumCapabilities cpus |
||
printf "Using %d cores\n" cpus |
printf "Using %d cores\n" cpus |
||
mapM_ (uncurry (printf "%s -> %s\n")) (bruteForce cpus)</ |
mapM_ (uncurry (printf "%s -> %s\n")) (bruteForce cpus)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>brute |
<pre>brute |
||
Line 1,046: | Line 1,046: | ||
<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> |
<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.Concurrent.Chan (Chan, newChan, readChan, writeList2Chan) |
||
import Control.Monad (replicateM, replicateM_, forever) |
import Control.Monad (replicateM, replicateM_, forever) |
||
Line 1,098: | Line 1,098: | ||
replicateM_ wCount (forkIO $ searchWorker batchChan resultChan) |
replicateM_ wCount (forkIO $ searchWorker batchChan resultChan) |
||
writeList2Chan batchChan chunks |
writeList2Chan batchChan chunks |
||
replicateM_ (length hashedValues) (readChan resultChan >>= uncurry (printf "%s -> %s\n") . first show)</ |
replicateM_ (length hashedValues) (readChan resultChan >>= uncurry (printf "%s -> %s\n") . first show)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>brute2 |
<pre>brute2 |
||
Line 1,111: | Line 1,111: | ||
This implementation runs 3 threads (one per hash to crack), and short-stops when a match for a hash is found. |
This implementation runs 3 threads (one per hash to crack), and short-stops when a match for a hash is found. |
||
< |
<syntaxhighlight lang="java">import javax.xml.bind.DatatypeConverter; |
||
import java.security.MessageDigest; |
import java.security.MessageDigest; |
||
import java.security.NoSuchAlgorithmException; |
import java.security.NoSuchAlgorithmException; |
||
Line 1,206: | Line 1,206: | ||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}}<pre>Hash 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b has the following match : apple |
{{out}}<pre>Hash 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b has the following match : apple |
||
Hash 74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f has the following match : mmmmm |
Hash 74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f has the following match : mmmmm |
||
Line 1,213: | Line 1,213: | ||
===Faster Alternative Version=== |
===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). |
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). |
||
< |
<syntaxhighlight lang="java">import javax.xml.bind.DatatypeConverter; |
||
import java.security.*; |
import java.security.*; |
||
import java.util.*; |
import java.util.*; |
||
Line 1,294: | Line 1,294: | ||
private byte[][] digests; |
private byte[][] digests; |
||
private AtomicInteger count = new AtomicInteger(); |
private AtomicInteger count = new AtomicInteger(); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,303: | Line 1,303: | ||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
< |
<syntaxhighlight lang="julia">@everywhere using SHA |
||
@everywhere function bruteForceRange(startSerial, numberToDo) |
@everywhere function bruteForceRange(startSerial, numberToDo) |
||
Line 1,324: | Line 1,324: | ||
@everywhere perThread = div(26^5, Sys.CPU_CORES) |
@everywhere perThread = div(26^5, Sys.CPU_CORES) |
||
pmap(x -> bruteForceRange(x * perThread, perThread), 0:Sys.CPU_CORES-1) |
pmap(x -> bruteForceRange(x * perThread, perThread), 0:Sys.CPU_CORES-1) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}}<pre>From worker 2: apple --> 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b |
{{out}}<pre>From worker 2: apple --> 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b |
||
From worker 3: zyzzx --> 1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad |
From worker 3: zyzzx --> 1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad |
||
Line 1,331: | Line 1,331: | ||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
{{trans|C#}} |
{{trans|C#}} |
||
< |
<syntaxhighlight lang="scala">// version 1.1.51 |
||
import java.security.MessageDigest |
import java.security.MessageDigest |
||
Line 1,383: | Line 1,383: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,394: | Line 1,394: | ||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
< |
<syntaxhighlight lang="mathematica">testPassword[pass_String] := |
||
If[MemberQ[{16^^1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad, |
If[MemberQ[{16^^1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad, |
||
16^^3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b, |
16^^3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b, |
||
Line 1,404: | Line 1,404: | ||
ParallelDo[ |
ParallelDo[ |
||
testPassword[StringJoin[a, b, c, d, e]], |
testPassword[StringJoin[a, b, c, d, e]], |
||
{a, chars}, {b, chars}, {c, chars}, {d, chars}, {e, chars}]</ |
{a, chars}, {b, chars}, {c, chars}, {d, chars}, {e, chars}]</syntaxhighlight> |
||
=={{header|Modula-2}}== |
=={{header|Modula-2}}== |
||
< |
<syntaxhighlight lang="modula2">MODULE PBF; |
||
FROM FormatString IMPORT FormatString; |
FROM FormatString IMPORT FormatString; |
||
FROM SHA256 IMPORT SHA256,Create,Destroy,HashBytes,Finalize,GetHash; |
FROM SHA256 IMPORT SHA256,Create,Destroy,HashBytes,Finalize,GetHash; |
||
Line 1,571: | Line 1,571: | ||
WriteLn; |
WriteLn; |
||
ReadChar |
ReadChar |
||
END PBF.</ |
END PBF.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>apple 3A7BD3E2360A3D29EEA436FCFB7E44C735D117C42D1C1835420B6B9942DD4F1B |
<pre>apple 3A7BD3E2360A3D29EEA436FCFB7E44C735D117C42D1C1835420B6B9942DD4F1B |
||
Line 1,582: | Line 1,582: | ||
Using a thread for each starting character. |
Using a thread for each starting character. |
||
Note that the program must be compiled with option --threads:on. |
Note that the program must be compiled with option --threads:on. |
||
< |
<syntaxhighlight lang="nim">import strutils, threadpool |
||
import nimcrypto |
import nimcrypto |
||
Line 1,619: | Line 1,619: | ||
spawn findHashes(a) |
spawn findHashes(a) |
||
sync()</ |
sync()</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,628: | Line 1,628: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
Uses threads library to do naive search using 26 threads ("aaaaa" .. "azzzz", "baaaa" .. "bzzzz", etc.). No effort is made to early exit. |
Uses threads library to do naive search using 26 threads ("aaaaa" .. "azzzz", "baaaa" .. "bzzzz", etc.). No effort is made to early exit. |
||
< |
<syntaxhighlight lang="perl">use Digest::SHA qw/sha256_hex/; |
||
use threads; |
use threads; |
||
use threads::shared; |
use threads::shared; |
||
Line 1,655: | Line 1,655: | ||
$s++; |
$s++; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,665: | Line 1,665: | ||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
Each thread processes one start letter at a time, until they are all done. |
Each thread processes one start letter at a time, until they are all done. |
||
<!--< |
<!--<syntaxhighlight lang="phix">(notonline)--> |
||
<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> |
<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> |
||
<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> |
<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> |
||
Line 1,727: | Line 1,727: | ||
<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> |
<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> |
||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
<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.) |
{{out}} (with nthreads loop from 1 to 4, and for that case CPU use in Task Manager shows a very clear step pattern.) |
||
<pre> |
<pre> |
||
Line 1,749: | Line 1,749: | ||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
< |
<syntaxhighlight lang="purebasic">UseSHA2Fingerprint() |
||
NewList sha256fp.s() |
NewList sha256fp.s() |
||
Line 1,792: | Line 1,792: | ||
EndIf |
EndIf |
||
End |
End |
||
; EnableThread</ |
; EnableThread</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>apple => 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b |
<pre>apple => 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b |
||
Line 1,802: | Line 1,802: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
< |
<syntaxhighlight lang="python">import multiprocessing |
||
from hashlib import sha256 |
from hashlib import sha256 |
||
Line 1,828: | Line 1,828: | ||
if __name__ == "__main__": |
if __name__ == "__main__": |
||
main()</ |
main()</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,840: | Line 1,840: | ||
the single threaded version. |
the single threaded version. |
||
< |
<syntaxhighlight lang="racket">#lang racket/base |
||
(require racket/place |
(require racket/place |
||
racket/list |
racket/list |
||
Line 1,938: | Line 1,938: | ||
. |
. |
||
#"\21\25\335\200\17\352\254\357\337H\37\37\220p7J*\201\342x\200\361\2079m\266yX\262\a\313\255")) |
#"\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"))</ |
"without parallelism, it works"))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,962: | Line 1,962: | ||
(formerly Perl 6) |
(formerly Perl 6) |
||
This solution can be changed from parallel to serial by removing the <code>.race</code> method. |
This solution can be changed from parallel to serial by removing the <code>.race</code> method. |
||
<lang |
<syntaxhighlight lang="raku" line>use Digest::SHA256::Native; |
||
constant @alpha2 = [X~] <a m p y z> xx 2; |
constant @alpha2 = [X~] <a m p y z> xx 2; |
||
constant @alpha3 = [X~] <e l m p x z> xx 3; |
constant @alpha3 = [X~] <e l m p x z> xx 3; |
||
Line 1,980: | Line 1,980: | ||
} |
} |
||
.say for flat @alpha2.race(:1batch).map: { find_it($_) };</ |
.say for flat @alpha2.race(:1batch).map: { find_it($_) };</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>apple => 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b |
<pre>apple => 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b |
||
Line 1,987: | Line 1,987: | ||
Testers can adjust the run speed by replacing the @alpha constants with one of the below: |
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 |
# True to actual RC task, but slowest |
||
constant @alpha2 = 'aa' .. 'zz'; |
constant @alpha2 = 'aa' .. 'zz'; |
||
Line 1,995: | Line 1,995: | ||
constant @alpha2 = [X~] <a m p y z> xx 2; |
constant @alpha2 = [X~] <a m p y z> xx 2; |
||
constant @alpha3 = [X~] <e l m p x z> xx 3; |
constant @alpha3 = [X~] <e l m p x z> xx 3; |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
Line 2,001: | Line 2,001: | ||
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. |
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. |
||
< |
<syntaxhighlight lang="rust">// [dependencies] |
||
// rust-crypto = "0.2.36" |
// rust-crypto = "0.2.36" |
||
// num_cpus = "1.7.0" |
// num_cpus = "1.7.0" |
||
Line 2,120: | Line 2,120: | ||
} |
} |
||
result.clone() |
result.clone() |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,136: | Line 2,136: | ||
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. |
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. |
||
< |
<syntaxhighlight lang="scala">import java.security.MessageDigest |
||
import scala.collection.parallel.immutable.ParVector |
import scala.collection.parallel.immutable.ParVector |
||
Line 2,171: | Line 2,171: | ||
digester.digest(str.getBytes("UTF-8")).map("%02x".format(_)).mkString |
digester.digest(str.getBytes("UTF-8")).map("%02x".format(_)).mkString |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
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. |
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 2,179: | Line 2,179: | ||
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. |
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. |
||
< |
<syntaxhighlight lang="scala">import java.security.MessageDigest |
||
import scala.annotation.tailrec |
import scala.annotation.tailrec |
||
Line 2,227: | Line 2,227: | ||
digester.digest(str.getBytes("UTF-8")).map("%02x".format(_)).mkString |
digester.digest(str.getBytes("UTF-8")).map("%02x".format(_)).mkString |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
As a final example, we can clean this code up with some method chaining and currying to get this: |
As a final example, we can clean this code up with some method chaining and currying to get this: |
||
< |
<syntaxhighlight lang="scala">import java.security.MessageDigest |
||
import scala.collection.parallel.immutable.ParVector |
import scala.collection.parallel.immutable.ParVector |
||
Line 2,264: | Line 2,264: | ||
.map(_.to(ParVector).find(str => getHash(str) == hash)) //Convert each chunk into a ParVector and search it |
.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 |
.collectFirst{case Some(res) => res} //Get the first hit if one is found |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,280: | Line 2,280: | ||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
{{trans|Perl}} |
{{trans|Perl}} |
||
< |
<syntaxhighlight lang="ruby">func invert_sha256(hash) { |
||
var letters = @('a'..'z') |
var letters = @('a'..'z') |
||
Line 2,308: | Line 2,308: | ||
var phrase = invert_sha256(t) |
var phrase = invert_sha256(t) |
||
say "#{t} : #{phrase}" |
say "#{t} : #{phrase}" |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,317: | Line 2,317: | ||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
< |
<syntaxhighlight lang="swift">import Foundation |
||
import CryptoKit |
import CryptoKit |
||
Line 2,353: | Line 2,353: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Visual Basic .NET}}== |
=={{header|Visual Basic .NET}}== |
||
{{trans|C#}} |
{{trans|C#}} |
||
< |
<syntaxhighlight lang="vbnet">Imports System.Text |
||
Module Module1 |
Module Module1 |
||
Line 2,409: | Line 2,409: | ||
End Sub |
End Sub |
||
End Module</ |
End Module</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>mmmmm => 74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f |
<pre>mmmmm => 74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f |
||
Line 2,423: | Line 2,423: | ||
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. |
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="ecmascript">import "/crypto" for Sha256 |
||
var hashes = [ |
var hashes = [ |
||
Line 2,461: | Line 2,461: | ||
var fib = Fiber.new(findHash) |
var fib = Fiber.new(findHash) |
||
fib.call(97+i) |
fib.call(97+i) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,482: | Line 2,482: | ||
Uses the message hashing extension library (DLL). |
Uses the message hashing extension library (DLL). |
||
{{trans|==C sharp|C#}} |
{{trans|==C sharp|C#}} |
||
< |
<syntaxhighlight lang="zkl">var [const] MsgHash=Import.lib("zklMsgHash"); |
||
var [const] gotEm=Atomic.Int(); // global signal for all threads |
var [const] gotEm=Atomic.Int(); // global signal for all threads |
||
Line 2,502: | Line 2,502: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="zkl">hashes:=T("3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b", |
||
"74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f", |
"74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f", |
||
"1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad"); |
"1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad"); |
||
Line 2,517: | Line 2,517: | ||
s+=n; |
s+=n; |
||
} |
} |
||
hashes2go.waitFor(0); // wait until all cracked, just exit, OS kills threads</ |
hashes2go.waitFor(0); // wait until all cracked, just exit, OS kills threads</syntaxhighlight> |
||
<pre> |
<pre> |
||
mmmmm --> 74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f |
mmmmm --> 74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f |