Mój na 2016 w Bitcoinach! PCG.SE New Year's Puzzle 2016

17

W protokole Bitcoin 2016 to bardzo szczególna liczba. „Trudność” znalezienia skrótu w celu utworzenia nowego bloku jest dostosowywana co 2016 bloków w celu przybliżonej zmiany raz na dwa tygodnie.

Ta liczba została wybrana, ponieważ trudność dostosowuje się tak, że znalezienie każdego bloku zajmuje około 10 minut, a za dwa tygodnie są 2 × 7 × 24 × 6 = 2016 dziesięciominutowych okresów.


Aby upamiętnić ten numeryczny zbieg okoliczności, tegoroczny problem noworoczny dotyczy Bitcoinów - w szczególności algorytmu haszującego używanego do podpisywania bloków, SHA-256.

Twoim zadaniem jest stworzenie programu, który pobierze dane bajtowe (co najmniej ASCII) i wyświetli wartość nonce w bajtach (w wybranym przez Ciebie formacie), która po dodaniu do oryginału wygeneruje skrót SHA-256 zawierający 2016w swojej reprezentacji base64 wprowadzanie bajtów.

Oto kilka przykładów prawidłowych rozwiązań, dzięki uprzejmości silników, które ludzie już wygenerowali, a także wygenerowanych przez nich skrótów:

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

Jedyną gotową biblioteką (inną niż standardowe funkcje wejścia i wyjścia), z której może korzystać Twój program, jest SHA256(bytes)funkcja pobierająca dane bajtowe i zwracająca skrót SHA256 w dowolnym formacie, w tym base64.

Program do wykonania tego w najmniejszej liczbie bajtów kodu źródłowego wygrywa.

Joe Z.
źródło
1
Nazwij mnie szalonym, ale czy to nie wydobywanie bitcoinów pod inną nazwą?
Codefun64
1
Zdefiniuj także „gotową bibliotekę”. Funkcja SHA-256 w moim języku tworzy skrót, ale nie skrót Base64. Dlatego musiałbym również użyć konwersji do bajtów, następnie konwersji na znaki, a następnie konwersji do Base64.
LegionMammal978
@ LegionMammal978 „Wstępnie zbudowana biblioteka” to dowolna funkcja zdefiniowana poza kodem, która liczy się dla tego wyzwania. Możesz więc utworzyć funkcję opakowującą base64 dla swojej funkcji SHA-256, aby użyć jej w tym problemie.
Joe Z.
@ Codefun64 Jest to problem z kodem, który symuluje procedurę wykorzystywaną przy wydobywaniu bitcoinów, ale sam nie wydobywa bitcoinów.
Joe Z.

Odpowiedzi:

7

Perl 5.10+, 39 + 18 = 57 bajtów

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

Należy to uruchomić za pomocą -nMDigest::SHA=/./przełącznika wiersza polecenia, który jest uwzględniony w liczbie bajtów. Korzysta również z funkcji Perl 5.10+ sayi dlatego musi być uruchamiany za pomocą przełącznika linii poleceń -M5.010(lub -E), który jest uważany za wolny. Dane wejściowe powinny być podawane na standardowym wejściu, bez końcowego nowego wiersza (chyba że chcesz, aby nowy wiersz był uważany za część wejścia).

Przykłady:

$ 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
źródło
8

Mathematica, 94

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

Ta funkcja wypróbuje dodatnie liczby całkowite jako kandydatów. Prawidłowa odpowiedź na moim laptopie zajmuje 4 minuty.

%["foo"]
(* 196870 *)

W ~5ximplementacji dłuższej, ale szybszej ( ) wykorzystywana jest równoległ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
źródło
2
Powinniśmy stworzyć golfową wersję języka Wolfram, z każdym poleceniem zastępowanym przez jedną lub dwie postacie. W rzeczywistości, biorąc pod uwagę liczbę poleceń, możemy potrzebować użyć trzech znaków w przypadku niektórych mniej popularnych.
Michael Stern
@MichaelStern Nie mogę się więcej zgodzić.
njpipeorgan
@MichaelStern Zrobił to.
LegionMammal978
@ LegionMammal978 Fantastyczne! Przy okazji, dlaczego nie rozważyć lepszej nazwy, takiej jak „WOLF”?
njpipeorgan
5

Rubin, 87 86 bajtów

Nie jestem pewien, czy poprawnie zrozumiałem wyzwanie, ale znajdziesz je 196870za kilka sekund, jeśli wpiszesz foo.

require"digest"
gets.chop!
$.+=1until/2016/=~Digest::SHA256.base64digest("#$_#$.")
p$.
daniero
źródło
5

PowerShell, 150 152 153 bajty

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

Przykład

PS > .\BitCoin.ps1 foo
196870

PS > .\BitCoin.ps1 bar
48230

PS > .\BitCoin.ps1 happynewyear
1740131

PS > .\BitCoin.ps1 2016
494069
beatcracker
źródło
2

C #, 179 bajtów

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

Podobne do rozwiązania PowerShell, tylko dłużej.

LegionMammal978
źródło
To dużo słów kluczowych.
Joe Z.
1
@JoeZ. To C # dla ciebie.
LegionMammal978