Mina para 2016 em Bitcoins! PCG.SE Ano Novo 2016

17

No protocolo Bitcoin, 2016 é um número muito especial. A "dificuldade" de encontrar um hash para criar um novo bloco é ajustada a cada 2.016 blocos para aproximar a alteração uma vez a cada duas semanas.

Esse número foi escolhido porque a dificuldade se ajusta de modo que cada bloco leva cerca de 10 minutos para ser encontrado e, em duas semanas, existem 2 × 7 × 24 × 6 = 2.016 períodos de dez minutos.


Para comemorar essa coincidência numérica, o problema do ano novo é sobre Bitcoin - especificamente, o algoritmo de hash usado para assinar blocos, SHA-256.

Sua tarefa é criar um programa que receba entrada de bytes (pelo menos ASCII) e produza um nonce em bytes (no formato de sua escolha) que produzirá um hash SHA-256 contendo 2016em sua representação base64 quando anexado ao original entrada de bytes.

Aqui estão alguns exemplos de soluções válidas, cortesia dos motores que as pessoas já geraram, bem como os hashes que eles produziram:

> 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.)

A única biblioteca pré-criada (além das funções de entrada e saída padrão) que seu programa pode usar é uma SHA256(bytes)função que recebe entrada de bytes e retorna um hash SHA256, em qualquer formato, incluindo base64.

O programa para fazer isso no menor número de bytes de código-fonte vence.

Joe Z.
fonte
11
Pode me chamar de louco, mas essa mineração de bitcoin não tem outro nome?
precisa saber é o seguinte
11
Além disso, defina uma "biblioteca pré-criada". A função SHA-256 do meu idioma produz o hash, mas não o hash Base64. Portanto, eu também precisaria usar a conversão em bytes, a conversão em caracteres e a conversão em Base64.
LegionMammal978 01/01
@ LegionMammal978 Uma "biblioteca pré-criada" seria qualquer função definida fora do código que conta para esse desafio. Portanto, você pode criar uma função de wrapper base64 para sua função SHA-256, para usá-la neste problema.
Joe Z.
@ Codefun64 Este é um problema de código que simula o procedimento usado na mineração de Bitcoin, mas não é o mesmo para bitcoins.
Joe Z.

Respostas:

7

Perl 5.10+, 39 + 18 = 57 bytes

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

Isso precisa ser executado com a -nMDigest::SHA=/./opção de linha de comando, incluída na contagem de bytes. Ele também usa o sayrecurso Perl 5.10+ e, portanto, precisa ser executado com a opção de linha de comando -M5.010(ou -E), que é considerada livre. A entrada deve ser fornecida no stdin, sem uma nova linha à direita (a menos que você queira que a nova linha seja considerada parte da entrada).

Exemplos:

$ 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
Ilmari Karonen
fonte
8

Mathematica, 94

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

Esta função tentará números inteiros positivos como candidatos. Demora mais de 4 minutos no meu laptop para obter a resposta correta.

%["foo"]
(* 196870 *)

Uma ~5ximplementação mais longa, porém mais rápida ( ), faz uso da paralelização:

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}]
njpipeorgan
fonte
2
Devemos criar uma versão para golfe do Wolfram Language, com todos os comandos substituídos por um ou dois caracteres. Na verdade, dado o número de comandos, podemos precisar usar três caracteres para alguns dos menos comuns.
Michael Stern
@MichaelStern Não posso concordar mais.
Njpipeorgan
@MichaelStern Fiz isso.
precisa
@ LegionMammal978 Fantastic! Aliás, por que não considerar um nome melhor como "LOBO"?
Njpipeorgan 18/03/19
5

Ruby, 87 86 bytes

Não tenho certeza se entendi o desafio corretamente, mas ele encontra 196870em alguns segundos se você inserir foo.

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

PowerShell, 150 152 153 bytes

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

Exemplo

PS > .\BitCoin.ps1 foo
196870

PS > .\BitCoin.ps1 bar
48230

PS > .\BitCoin.ps1 happynewyear
1740131

PS > .\BitCoin.ps1 2016
494069
beatcracker
fonte
2

C #, 179 bytes

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;}

Semelhante à solução PowerShell, apenas por mais tempo.

LegionMammal978
fonte
São muitas palavras-chave.
Joe Z.
11
@JoeZ. Isso é c # para você.
LegionMammal978