Il mio per il 2016 in Bitcoin! PCG.SE Puzzle di Capodanno 2016


17

Nel protocollo Bitcoin, 2016 è un numero molto speciale. La "difficoltà" di trovare un hash per creare un nuovo blocco viene regolata ogni 2.016 blocchi per cambiare approssimativamente una volta ogni due settimane.

Questo numero è stato scelto perché la difficoltà si adatta in modo che ogni blocco impieghi circa 10 minuti per essere trovato, e in due settimane ci sono 2 × 7 × 24 × 6 = 2.016 periodi di dieci minuti.


Per commemorare questa coincidenza numerica, il problema del nuovo anno di quest'anno riguarda Bitcoin - in particolare, l'algoritmo di hashing che usa per firmare i blocchi, SHA-256.

Il tuo compito è creare un programma che prenderà l'input di byte (almeno in ASCII) e produrrà un nonce in byte (nel formato che preferisci) che produrrà un hash SHA-256 contenente 2016nella sua rappresentazione base64 quando aggiunto all'originale ingresso byte.

Ecco alcuni esempi di soluzioni valide, per gentile concessione dei motori che le persone hanno già generato, nonché degli hash che hanno prodotto:

> foo
Nonce: 196870
SHA256 hash: OCUdDDtQ42wUlKz2016x+NROo8P2lbJf8F4yCKedTLE=

> bar
Nonce: 48230
SHA256 hash: CNcaOCQgT7bnlQzQPXNwuBu8/LYEdk2016khRaROyZk=

> happynewyear
Nonce: 1740131
SHA256 hash: XsKke6z2016BzB+wRNCm53LKJ6TW6ir66GwuC8oz1nQ=

> 2016
Nonce: 494069
SHA256 hash: rWAHW2YFhHCr22016zw+Sog6aW76eImgO5Lh72u6o5s=

(note: the nonces don't actually have to be ASCII numbers; you can do
 any byte input you find convenient.)

L'unica libreria pre-costruita (diversa dalle funzioni standard di input e output) che il tuo programma può usare è una SHA256(bytes)funzione che accetta l'input di byte e restituisce un hash SHA256, in qualsiasi formato incluso base64.

Vince il programma per fare questo nel minor numero di byte di codice sorgente.


1
Chiamami pazzo, ma questo mining di bitcoin non è un altro nome?
Codefun64

1
Inoltre, definire una "libreria pre-costruita". La funzione SHA-256 della mia lingua produce l'hash, ma non l'hash Base64. Pertanto, avrei anche bisogno di usare la conversione in byte, quindi la conversione in caratteri, quindi la conversione in Base64.
LegionMammal978,

@ LegionMammal978 Una "libreria pre-costruita" sarebbe qualsiasi funzione definita al di fuori del codice che conta per questa sfida. Quindi puoi creare una funzione wrapper base64 per la tua funzione SHA-256, al fine di usarla in questo problema.
Joe Z.

@ Codefun64 Questo è un problema di codice che simula la procedura utilizzata nel mining di Bitcoin, ma non lo stesso per i bitcoin.
Joe Z.

Risposte:


7

Perl 5.10+, 39 + 18 = 57 byte

sha256_base64($_.++$i)!~2016?redo:say$i

Questo deve essere eseguito con l' -nMDigest::SHA=/./opzione della riga di comando, inclusa nel conteggio dei byte. Utilizza anche la sayfunzione Perl 5.10+ e quindi deve essere eseguito con l' opzione -M5.010(o -E) della riga di comando, che è considerata gratuita. L'input deve essere fornito su stdin, senza una nuova riga finale (a meno che non si desideri che la nuova riga sia considerata parte dell'input).

Esempi:

$ echo -n foo | perl -nMDigest::SHA=/./ -E 'sha256_base64($_.++$i)!~2016?redo:say$i'
196870
$ echo -n bar | perl -nMDigest::SHA=/./ -E 'sha256_base64($_.++$i)!~2016?redo:say$i'
48230
$ echo -n happynewyear | perl -nMDigest::SHA=/./ -E 'sha256_base64($_.++$i)!~2016?redo:say$i'
1740131
$ echo -n 2016 | perl -nMDigest::SHA=/./ -E 'sha256_base64($_.++$i)!~2016?redo:say$i'
494069

8

Mathematica, 94

(For[i=0,IntegerDigits[4Hash[#<>ToString@++i,"SHA256"],64]~SequenceCount~{54,52,53,58}<1,];i)&

Questa funzione proverà numeri interi positivi come candidati. Sono necessari più di 4 minuti sul mio laptop per ottenere la risposta corretta.

%["foo"]
(* 196870 *)

L' ~5ximplementazione più lunga ma più rapida ( ) fa uso della parallelizzazione:

f[k_]:=
    Do[If[Length@#>0,Return[i+#[[1,1]]]]&@
        Position[ParallelMap[IntegerDigits[4Hash[k<>ToString@#,"SHA256"],64]
            ~SequenceCount~{54,52,53,58}&,i+Range@1*^4],1]
        ,{i,0,∞,1*^4}]

2
Dovremmo creare una versione golf di Wolfram Language, con ogni comando sostituito da uno o due caratteri. In realtà, dato il numero di comandi, potremmo aver bisogno di usare tre caratteri per alcuni di quelli meno comuni.
Michael Stern,

@MichaelStern Non posso essere più d'accordo.
njpipeorgan,


@ LegionMammal978 Fantastico! A proposito, perché non prendere in considerazione un nome migliore come "WOLF"?
njpipeorgan,

5

Rubino, 87 86 byte

Non sono sicuro di aver compreso correttamente la sfida, ma 196870se si inserisce tra qualche secondo foo.

require"digest"
gets.chop!
$.+=1until/2016/=~Digest::SHA256.base64digest("#$_#$.")
p$.

5

PowerShell, 150 152 153 byte

while([Convert]::ToBase64String([Security.Cryptography.SHA256]::Create().ComputeHash([Text.Encoding]::UTF8.GetBytes("$args$i")))-notmatch2016){$i++}$i

Esempio

PS > .\BitCoin.ps1 foo
196870

PS > .\BitCoin.ps1 bar
48230

PS > .\BitCoin.ps1 happynewyear
1740131

PS > .\BitCoin.ps1 2016
494069

2

C #, 179 byte

s=>{int i=0;while(!System.Convert.ToBase64String(System.Security.Cryptography.SHA256.Create().ComputeHash(System.Text.Encoding.UTF8.GetBytes(s+i))).Contains("2016"))i++;return i;}

Simile alla soluzione PowerShell, solo più a lungo.


Sono molte parole chiave.
Joe Z.

1
@JoeZ. Questo è C # per te.
LegionMammal978,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.