Khai thác năm 2016 bằng Bitcoin! Câu đố năm mới PCG.SE 2016


17

Trong giao thức Bitcoin, năm 2016 là một con số rất đặc biệt. "Khó khăn" của việc tìm kiếm một hàm băm để tạo một khối mới được điều chỉnh cứ sau 2.016 khối để thay đổi gần đúng cứ sau hai tuần.

Con số này được chọn là do độ khó tự điều chỉnh sao cho mỗi khối mất khoảng 10 phút để được tìm thấy và trong hai tuần, có 2 × 7 × 24 × 6 = 2.016 khoảng thời gian mười phút.


Để kỷ niệm sự trùng hợp về số này, vấn đề năm mới của năm nay là về Bitcoin - cụ thể là thuật toán băm mà nó sử dụng để ký các khối, SHA-256.

Nhiệm vụ của bạn là tạo ra một chương trình sẽ lấy đầu vào byte (ít nhất là ASCII) và xuất ra một byte không theo byte (theo định dạng bạn chọn) sẽ tạo ra hàm băm SHA-256 chứa 2016trong biểu diễn base64 của nó khi được thêm vào bản gốc đầu vào byte.

Dưới đây là một số ví dụ về các giải pháp hợp lệ, lịch sự của các công cụ mà mọi người đã tạo ra, cũng như các băm mà họ tạo ra:

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

Thư viện được xây dựng sẵn duy nhất (ngoài các hàm đầu vào và đầu ra tiêu chuẩn) mà chương trình của bạn có thể sử dụng là một SHA256(bytes)hàm lấy đầu vào byte và trả về hàm băm SHA256, ở bất kỳ định dạng nào kể cả base64.

Chương trình để làm điều này trong vài byte mã nguồn chiến thắng.


1
Gọi tôi là điên, nhưng đây không phải là khai thác bitcoin bằng tên khác sao?
Codefun64

1
Ngoài ra, xác định một "thư viện được xây dựng trước". Hàm SHA-256 của ngôn ngữ của tôi tạo ra hàm băm, nhưng không phải hàm băm Base64. Do đó, tôi cũng cần sử dụng chuyển đổi thành byte, sau đó chuyển đổi thành ký tự, sau đó chuyển đổi thành Base64.
LegionMammal978

@ LegionMammal978 Một "thư viện dựng sẵn" sẽ là bất kỳ chức năng nào được xác định bên ngoài mã được tính cho thử thách này. Vì vậy, bạn có thể tạo chức năng bao bọc base64 cho chức năng SHA-256 của mình, để sử dụng nó trong vấn đề này.
Joe Z.

@ Codefun64 Đây là một vấn đề về mã mô phỏng quy trình được sử dụng trong khai thác Bitcoin, nhưng bản thân nó không khai thác bitcoin.
Joe Z.

Câu trả lời:


7

Perl 5.10+, 39 + 18 = 57 byte

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

Điều này cần phải được chạy với -nMDigest::SHA=/./chuyển đổi dòng lệnh, được bao gồm trong số byte. Nó cũng sử dụng saytính năng Perl 5.10+ và do đó cần phải được chạy bằng công tắc dòng lệnh -M5.010(hoặc -E), được coi là miễn phí. Đầu vào phải được cung cấp trên stdin, không có dòng mới (trừ khi bạn muốn dòng mới được coi là một phần của đầu vào).

Ví dụ:

$ 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

Toán học, 94

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

Hàm này sẽ thử các số nguyên dương làm ứng viên. Phải mất hơn 4 phút trên máy tính xách tay của tôi để có câu trả lời chính xác.

%["foo"]
(* 196870 *)

Tuy nhiên, ~5xviệc triển khai ( ) lâu hơn sẽ sử dụng song song hóa:

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
Chúng ta nên tạo một phiên bản chơi gôn của Ngôn ngữ Wolfram, với mỗi lệnh được thay thế bằng một hoặc hai ký tự. Trên thực tế, với số lượng lệnh, chúng ta có thể cần sử dụng ba ký tự cho một số ký tự ít phổ biến hơn.
Michael Stern

@MichaelStern Tôi không thể đồng ý nhiều hơn.
njpipe tổ chức


@ LegionMammal978 Tuyệt vời! Btw, tại sao không xem xét một cái tên tốt hơn như "WOLF"?
njpipeorgan

5

Ruby, 87 86 byte

Tôi không chắc mình đã hiểu đúng thách thức hay chưa, nhưng nó sẽ tìm thấy 196870trong vài giây nếu bạn nhập 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

Thí dụ

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

Tương tự như giải pháp PowerShell, chỉ cần lâu hơn.


Đó là rất nhiều từ khóa.
Joe Z.

1
@JoeZ. Đó là C # dành cho bạn.
LegionMammal978
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.