¡Mina para 2016 en Bitcoins! PCG.SE Puzzle de Año Nuevo 2016

17

En el protocolo Bitcoin, 2016 es un número muy especial. La "dificultad" de encontrar un hash para crear un nuevo bloque se ajusta cada 2,016 bloques para cambiar aproximadamente una vez cada dos semanas.

Se eligió este número porque la dificultad se ajusta a sí misma para que cada bloque demore unos 10 minutos en encontrarse, y en dos semanas, hay 2 × 7 × 24 × 6 = 2,016 períodos de diez minutos.


Para conmemorar esta coincidencia numérica, el problema de Año Nuevo de este año es sobre Bitcoin, específicamente, el algoritmo de hash que usa para firmar bloques, SHA-256.

Su tarea es crear un programa que tomará la entrada de bytes (al menos en ASCII) y generará un nonce en bytes (en el formato que elija) que producirá un hash SHA-256 que contenga 2016en su representación base64 cuando se agregue al original entrada de byte.

Aquí hay algunos ejemplos de soluciones válidas, cortesía de los motores que la gente ya ha generado, así como los hash que produjeron:

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

La única biblioteca precompilada (que no sean las funciones de entrada y salida estándar) que su programa puede usar es una SHA256(bytes)función que toma la entrada de bytes y devuelve un hash SHA256, en cualquier formato, incluido base64.

El programa para hacer esto en la menor cantidad de bytes de código fuente gana.

Joe Z.
fuente
1
Llámame loco, pero ¿no es esta minería de bitcoin con otro nombre?
Codefun64
1
Además, defina una "biblioteca preconstruida". La función SHA-256 de mi lenguaje produce el hash, pero no el hash Base64. Por lo tanto, también necesitaría usar la conversión a bytes, luego la conversión a caracteres, luego la conversión a Base64.
LegionMammal978
@ LegionMammal978 Una "biblioteca preconstruida" sería cualquier función definida fuera del código que cuenta para este desafío. Por lo tanto, puede crear una función de contenedor base64 para su función SHA-256, para usarla en este problema.
Joe Z.
@ Codefun64 Este es un problema de código que simula el procedimiento utilizado en la minería de Bitcoin, pero no extrae bitcoins.
Joe Z.

Respuestas:

7

Perl 5.10+, 39 + 18 = 57 bytes

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

Esto debe ejecutarse con el -nMDigest::SHA=/./interruptor de línea de comando, que se incluye en el recuento de bytes. También utiliza la función Perl 5.10+ say, por lo que debe ejecutarse con el -M5.010(o -E) interruptor de línea de comando, que se considera libre. La entrada debe proporcionarse en stdin, sin una nueva línea final (a menos que desee que la nueva línea se considere parte de la entrada).

Ejemplos:

$ 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
fuente
8

Mathematica, 94

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

Esta función intentará enteros positivos como candidatos. Toma más de 4 minutos en mi computadora portátil para obtener la respuesta correcta.

%["foo"]
(* 196870 *)

Una ~5ximplementación más larga pero más rápida ( ) hace uso de la paralelización:

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
fuente
2
Deberíamos crear una versión de golf de Wolfram Language, con cada comando reemplazado por uno o dos caracteres. En realidad, dada la cantidad de comandos, podríamos necesitar usar tres caracteres para algunos de los menos comunes.
Michael Stern
@ MichaelStern No puedo estar más de acuerdo.
njpipeorgan
@MichaelStern hizo eso.
LegionMammal978
@ LegionMammal978 ¡Fantástico! Por cierto, ¿por qué no considerar un nombre mejor como "LOBO"?
njpipeorgan
5

Rubí, 87 86 bytes

No estoy seguro si entendí el desafío correctamente, pero se encuentra 196870en unos segundos si ingresas foo.

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

PowerShell, 150 152 153 bytes

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

Ejemplo

PS > .\BitCoin.ps1 foo
196870

PS > .\BitCoin.ps1 bar
48230

PS > .\BitCoin.ps1 happynewyear
1740131

PS > .\BitCoin.ps1 2016
494069
beatcracker
fuente
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;}

Similar a la solución PowerShell, solo que más tiempo.

LegionMammal978
fuente
Esas son muchas palabras clave.
Joe Z.
1
@JoeZ. Eso es C # para ti.
LegionMammal978