difficulty-algorithms
difficulty-algorithms copied to clipboard
Difficulty algorithm for interesting hashes instead of lowest target
If you use sha256 on this message:
The Fed Sux $8.135031041634 trillion's worth.
You'll see the hash is:
ccccca55112f200bbbadd7944477442228750ee76bba5dd520faa7be00d460fc
The decimal part after in the $8.1 T was functioning as the nonce in looking for an interesting hash as opposed to looking for the lowest target. As it indicates, it took 35 billion nonces. I defined "order" in the search as the most hex symbols that are repeats. The number of repeats in the hash is 21. The expected number of leading zeros in 35 B hashes is only 8. It has a lot more of repeats because they don't need to be leading, contiguous, or restricted to "0". Even just 300k hashes can find some simple-looking strings.
Perl on my systems was just as fast as Python in solving sha256 (1 M/s) after installing SHA256 module with:
$ cpan install Crypt:Digest:SHA256
The script:
#!usr/bin/perl
# usage: $ perl file_name.pl
use Crypt::Digest::SHA256 sha256_hex;
$|=1; # flush output immediately.
$nonce = 1;
$win = 14; # initial difficulty
while(1) {
$nonce++;
$message = "The Fed Sux \$8.$nonce trillion's worth.";
$k = $hash = sha256_hex($m); # get hex hash
next if $k !~ /^.?(.)\1+.?(.)\2+/; # go to next nonce if it's probably not a good winner.
$k = ~s/(.)\1+/\1/g; # remove all chars that repeat previous char. The slowest step.
$s = 64 - length($k); # count chars removed
next if $score < $win; # go to next nonce if it's not at least as good as previous win
$win = $score;
print "$hash $score $message\n\07"; # print winner. The \07 causes a beep
open(F,">>fed_sux.txt"); print F "$hash $score $message\n"; close F; # save winners in file
}
The above can be run as a compressed 1-liner directly on the command line (after Crypt::Digest module is installed) by copy-pasting the following.
perl -e 'use Crypt::Digest::SHA256 sha256_hex;$|=1;$nonce=1;$w=14;while(1){$nonce++;$m="The Fed Sux \$8.$nonce trillion'\''s worth.";$k=$j=sha256_hex($m);next if $k!~/^.?(.)\1+.?(.)\2+/;$k=~s/(.)\1+/\1/g;$s=64-length($k);next if $s<$w;$w=$s;print "$j $s $m\n\07";open(F,">>fed_sux.txt");print F "$j $s $m\n";close F;}'
Instead of printing just the best winners, I gave the above a difficulty algorithm (WTEMA = ~ASERT) to keep changing the difficulty up and down to let good hashes print to the command line according to a block time. Each message with its nonce is the same as a block header except it doesn't include the prior block's hash. Here's the Perl script with plenty of comments.
https://github.com/zawy12/difficulty-algorithms/blob/master/fed_sux.pl
Each step up in difficulty would be 16x harder if this just counted leading (hex) zeros.
Each of the following metrics for "order" took about 100 M hashes
The above method:
$out2 =~ s/(.)\1+/$1/g; # remove all sequential repeats. The shortest resulting string is the highest "order"
c5551118690e5216e04cc727dbe3eee0ee660681fecf99112555c7777d455111
Biased towards 3's
$out2 =~ s/(.)\1\1+/$1/g; # at least 2 repeats
3dddc793ee0b5b34e3c61111abbb9788810fff2ec65a3456f7c6aaa48ad22299
Shannon entropy at 140 M hashes had 3.2 instead of 4 bits per hex and you can
intuitively see there's some order but have to reason out why.
ba8a56220650d15120e53a2bb0102e2e65ed0215212b5922a2e2b929221b2a26
PoW
0000000ea5cded1564efef1223ec9783bff30511d754b27a9454765b12e86a85
An 8x8 matrix of hex values looking for any adjacent repeats in the matrix gave this after only 8 M hashes. Notice it found a lot of a's in the middle of the matrix.
b6a6dd000ee31d2a6aaaa85967aaaccb189aaac29bf3aaa3718ccc5005bc414f
The following string was found at 13 B hashes is the result of giving 2x credit if next hex was the same, zero credit for the one after, and then 1 credit for the 3rd & 4th. It gave interesting results quickly at 330k. This gave 21 "repeats" (not necessarily sequential due to the scoring) in 1/3 the hashes it took the above "direct repeat" method.
799b1a255555557917787cbbbb82d42292ea6222c766a5d13333f42fffd18c81
This 2.87 B number hashes to something that has only numbers and a's in the hex:
2873302938
16a1672809451a31932425263276a01529707039473360a5201491241722a824
This was a little lucky because you'd expect one of these that's missing 5 of the possible symbols to occur only once every
16^64 / (16-5)^64 = 26 B hashes
Displaying the sha256 outputs in a 16x16 binary matrix to represent black and white pixels failed to show any recognizable match to a target image. For example, I tried to let a random search match a heart that was 3 pixels wide by scoring a 1 for each correct pixel. A compression scheme that allows a lot of error in the compressed values might work better.