Bitcoins에서 2016 년 광산! PCG.SE 새해 퍼즐 2016


17

비트 코인 프로토콜에서 2016 은 매우 특별한 숫자입니다. 새로운 블록을 생성하기 위해 해시를 찾는 "난이도"는 2,016 블록마다 2 주마다 한 번씩 변화를 근사하도록 조정됩니다.

이 숫자는 모든 블록을 발견하는 데 약 10 분이 걸리고 난이도 자체 조정이 이루어지기 때문에 선택되었으며, 2 주 안에 2 × 7 × 24 × 6 = 2,016 개의 10 분 간격이 있습니다.


이러한 수치 적 우연의 일치를 기념하기 위해 올해의 새해 문제는 비트 코인, 특히 블록 서명에 사용되는 해싱 알고리즘 인 SHA-256에 관한 것입니다.

당신의 임무는 바이트 입력 (적어도 ASCII)을 취하고 원본에 추가 될 때 base64 표현에 포함 2016된 SHA-256 해시를 생성하는 nonce를 바이트 단위로 (선택한 형식으로) 출력하는 프로그램을 만드는 것입니다. 바이트 입력.

다음은 사람들이 이미 생성 한 엔진과 그들이 만든 해시를 통해 유효한 솔루션의 예입니다.

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

프로그램에서 사용할 수있는 유일한 사전 빌드 라이브러리 (표준 입력 및 출력 함수 제외) SHA256(bytes)는 바이트 입력을 사용하고 base64를 포함한 모든 형식의 SHA256 해시를 반환하는 함수입니다.

가장 적은 바이트의 소스 코드에서이를 수행하는 프로그램이 이깁니다.


1
날 미치게하지만이 비트 코인 채굴은 다른 이름으로 아닌가요?
Codefun64

1
또한 "사전 빌드 된 라이브러리"를 정의하십시오. 내 언어의 SHA-256 함수는 해시를 생성하지만 Base64 해시는 생성하지 않습니다. 따라서 바이트로 변환 한 다음 문자로 변환 한 다음 Base64로 변환해야합니다.
LegionMammal978

@ LegionMammal978 "사전 빌드 된 라이브러리"는이 챌린지를 계산하는 코드 외부에서 정의 된 함수입니다. 따라서이 문제에서 사용하기 위해 SHA-256 함수에 대한 base64 랩퍼 함수를 ​​작성할 수 있습니다.
Joe Z.

@ Codefun64 이것은 비트 코인 채굴에 사용 된 절차 를 시뮬레이트하는 코드 문제 이지만 비트 코인을 채굴하지는 않습니다.
Joe Z.

답변:


7

Perl 5.10+, 39 + 18 = 57 바이트

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

이것은 -nMDigest::SHA=/./바이트 수에 포함 된 명령 행 스위치 로 실행해야합니다 . 또한 Perl 5.10+ say기능을 사용 하므로 무료로 간주 되는 -M5.010(또는 -E) 명령 행 스위치 로 실행해야합니다 . 입력은 줄 바꿈이없는 stdin에 제공되어야합니다 (줄 바꿈을 입력의 일부로 간주하지 않는 한).

예 :

$ 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

매스 매 티카, 94

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

이 함수는 양수를 후보로 시도합니다. 정답을 얻으려면 랩톱에서 4 분 이상 걸립니다.

%["foo"]
(* 196870 *)

더 길지만 빠른 ~5x구현은 병렬화를 사용합니다.

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
모든 명령을 한두 문자로 대체하여 Wolfram Language의 골프 버전을 만들어야합니다. 실제로는 명령 수가 많기 때문에 일반적이지 않은 명령에는 세 개의 문자를 사용해야합니다.
Michael Stern

@MichaelStern 더 이상 동의 할 수 없습니다.
njpipeorgan

@MichaelStern 그랬어 .
LegionMammal978

트윗 담아 가기 Btw, "WOLF"와 같은 더 나은 이름을 고려해 보시겠습니까?
njpipeorgan 0

5

루비, 87 86 바이트

문제를 올바르게 이해했는지 확실하지 않지만 196870입력하면 몇 초 안에 발견 됩니다 foo.

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

5

PowerShell을 150 152 153 바이트

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

PS > .\BitCoin.ps1 foo
196870

PS > .\BitCoin.ps1 bar
48230

PS > .\BitCoin.ps1 happynewyear
1740131

PS > .\BitCoin.ps1 2016
494069

2

C #, 179 바이트

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

PowerShell 솔루션과 유사하며 더 길어집니다.


많은 키워드입니다.
Joe Z.

1
@JoeZ. 그것은 당신을위한 C #입니다.
LegionMammal978
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.