100 lines
4.0 KiB
Racket
100 lines
4.0 KiB
Racket
#lang racket/base
|
|
(require racket/place
|
|
racket/list
|
|
racket/match
|
|
;; requires sha package. install it in DrRacket's "File/Install Package..."
|
|
;; or with raco:
|
|
;; % raco pkg install sha
|
|
sha
|
|
(only-in openssl/sha1 hex-string->bytes))
|
|
|
|
(define (brute css targs)
|
|
(define (sub-work i) (let ((cs (list-ref css i))) (in-range (car cs) (cdr cs))))
|
|
(define-values (as bs cs ds es) (apply values (map sub-work (range 5))))
|
|
(define s (make-bytes 5))
|
|
(for*/list ((a as) #:when (bytes-set! s 0 a)
|
|
(b bs) #:when (bytes-set! s 1 b)
|
|
(c cs) #:when (bytes-set! s 2 c)
|
|
(d ds) #:when (bytes-set! s 3 d)
|
|
(e es) #:when (bytes-set! s 4 e)
|
|
(h (in-value (sha256 s)))
|
|
(t (in-list targs))
|
|
#:when (bytes=? t h))
|
|
(eprintf "found ~s -> ~s~%" t s)
|
|
(cons (bytes-copy s) t)))
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
(unless (place-enabled?) (error "We're using places... they're not enabled!"))
|
|
|
|
(define target-list
|
|
(map hex-string->bytes
|
|
(list "1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad"
|
|
"3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b"
|
|
"74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f")))
|
|
|
|
(define (run-place/assign-task sub-task)
|
|
(define there (place here
|
|
(match-define (cons work targs) (place-channel-get here))
|
|
(place-channel-put here (brute work targs))))
|
|
(place-channel-put there (cons sub-task target-list))
|
|
there)
|
|
|
|
(define (task->subtasks css n-tasks)
|
|
(match css
|
|
[(list (and initial-range (cons A Z+)) common-tail ...)
|
|
(define step (quotient (+ n-tasks (- Z+ A)) n-tasks))
|
|
(for/list ((a (in-range A Z+ step)))
|
|
;; replace the head with a sub-task head
|
|
(cons (cons a (min (+ a step) Z+)) common-tail))]))
|
|
|
|
(define readable-pair (match-lambda [(cons x (app bytes->hex-string s)) (cons x s)]))
|
|
|
|
(define (parallel-brute css (n-tasks (processor-count)))
|
|
(define the-places (map run-place/assign-task (task->subtasks css n-tasks)))
|
|
(define collected-results (append* (map place-channel-get the-places)))
|
|
(map readable-pair collected-results))
|
|
|
|
(define 5-char-lowercase-work
|
|
(make-list 5 (cons (char->integer #\a) (add1 (char->integer #\z)))))
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
(module+ main
|
|
(time (parallel-brute 5-char-lowercase-work)))
|
|
|
|
;; ---------------------------------------------------------------------------------------------------
|
|
(module+ test
|
|
(require rackunit)
|
|
(check-equal?
|
|
(bytes->hex-string (sha256 #"mmmmm"))
|
|
"74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f"
|
|
"SHA-256 works as expected")
|
|
|
|
(check-equal?
|
|
(hex-string->bytes "74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f")
|
|
#"t\341\273b\370\332\273\201%\245\210R\266;\337n\256\366g\313V\254\177|\333\246\3270\\P\242/"
|
|
"This is the raw value we'll be hashing to")
|
|
|
|
(define m-idx (char->integer #\m))
|
|
(define m-idx+ (add1 m-idx))
|
|
(check-equal?
|
|
(brute (make-list 5 (cons m-idx m-idx+)) target-list)
|
|
(list
|
|
(cons
|
|
#"mmmmm"
|
|
#"t\341\273b\370\332\273\201%\245\210R\266;\337n\256\366g\313V\254\177|\333\246\3270\\P\242/")))
|
|
|
|
;; Brute works without parallelism
|
|
;; check when you have the time... it takes a minute (literally)
|
|
(check-equal?
|
|
(time
|
|
(brute 5-char-lowercase-work target-list))
|
|
'((#"apple"
|
|
. #":{\323\3426\n=)\356\2446\374\373~D\3075\321\27\304-\34\0305B\vk\231B\335O\e")
|
|
(#"mmmmm"
|
|
.
|
|
#"t\341\273b\370\332\273\201%\245\210R\266;\337n\256\366g\313V\254\177|\333\246\3270\\P\242/")
|
|
(#"zyzzx"
|
|
.
|
|
#"\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"))
|