Thanks Bill and Devon for the responses. I guess I’m prejudiced against 
negative numbers and should have read a little farther down in the foreigns 
page.

So the _3&(128!:6)^:2 bfh header_hex works as you say returning now packed 
binary as characters. Which now need to be converted into hex if I care to read 
them. 

So I applied the following:
    ,hfd a. i. _3&(128!:6)^:2 bfh header_hex
1dbd981fe6985776b644b173a4d0385ddc1aa2a829688d1e0000000000000000

And get back the correct answer.
When I run timing on my MacBook Pro circa 2016 I get the following timing which 
surprised me:

NB. My old way with extrinsic multiple calls
   timespacex '3&(128!:6) bfh 3&(128!:6) bfh header_hex'
1.1e_5 7040

NB. Bill’s way using the power conjunction
   timespacex ',hfd a. i. _3&(128!:6)^:2 bfh header_hex'
2.6e_5 14976

NB. Bill’s way leaving the result in binary character array
   timespacex '_3&(128!:6)^:2 bfh header_hex'
1.1e_5 6848

So the extra time seems to be due to the sequence of calls:  ,hfd a. i.
‘bfh’ takes very little time and relies on ‘dfh’ for its processing:
   timespacex 'bfh 
''b9d751533593ac10cdfb7b8e03cad8babc67d8eaeac0a3699b82857dacac9390'''
6e_6 5888

‘a. i.’ Is similarly quick I won’t reproduce the timing

I would expect that ‘hfd’ is similarly quick but it turns out that if is slower 
than ‘bfh’

NB. Preprocess to obtain a decimal array (I ran timespacex a few times and 
report the lowest time)
   decimalarray =: a. i. _3&(128!:6)^:2 bfh header_hex
   timespacex 'hfd decimalarray'
1.6e_5 12736

‘hfd’ produces a 2 dimensional array (multiple rows with 2 colums) I guess 
that’s where the extra processing lies?  

‘pdfesc_jzplot_’ which transcribes bytes into printable characters or escape 
sequences takes a longer time as well though I haven’t delved into its source 
code as yet:
 
 binarray =: _3&(128!:6)^:2 bfh header_hex  
 pdfesc_jzplot_"1 binarray
\035\275\230\037\346\230Wv\266D\261s\244\3208]\334\032\242\250\)h\215\036\000\000\000\000\000\000\000\000

timespacex 'pdfesc_jzplot_"1 binarray'
3.5e_5 6656

> On Apr 12, 2020, at 4:40 AM, bill lam <[email protected]> wrote:
> 
> try
> _3&(128!:6)^:2 bfh header_hex
> 
> On Sun, Apr 12, 2020, 3:50 PM Thomas McGuire <[email protected] 
> <mailto:[email protected]>> wrote:
> 
>> In a round about way (it started with reading slashdot) I was researching
>> Bitcoin hashing. I came across a python explanation of taking a bitcoin
>> header and SHA256 hashing it twice to see if it produces the desired number
>> of leading (or terminating depending on the endian of your machine) '0’s.
>> 
>> The snippet of python code is here at a bitcoin wiki site:
>> https://en.bitcoin.it/wiki/Block_hashing_algorithm 
>> <https://en.bitcoin.it/wiki/Block_hashing_algorithm> <
>> https://en.bitcoin.it/wiki/Block_hashing_algorithm 
>> <https://en.bitcoin.it/wiki/Block_hashing_algorithm>>
>> 
>> I won’t reproduce it in its entirety here since it’s only a few lines of
>> code I figured I should be able to do the same in J.
>> 
>> First I grabbed the header as ascii hex
>> 
>>   hex_header =:
>> '0100000081cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a308000000000000e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122bc7f5d74df2b9441a42a14695'
>> 
>> Then came the issue of turning this into binary. After reviewing the J
>> programming archives finding a thread on packed python structures, a few
>> attempts in J and some code in C to make sure I was doing it right, I came
>> to the realization that I only had to index pairs of hex characters into
>> ‘a.’ After using the ‘dfh’ function to convert the pair. So I made a bfs
>> tacit to do the work:
>> 
>> bfh =: a. {~ [: dfh _2 ]\ ]
>> 
>> (As an aside I cheated and used the 13 : functional form and let J figure
>> out the tacit.)
>> 
>>   NB. Python double hash:
>> hashlib.sha256(hashlib.sha256(header_bin).digest()).digest().
>> 
>>   3&(128!:6)^:2 bfh header_hex    NB. Seemingly direct implementation in J
>> 8ac7142a625bdd47e177ab584d60de449d0a844eb56173bd1c9aa0dbe69b61a4
>> 
>> Now the above is the incorrect answer. The reason being is that our SHA
>> foreigns convert the answer from underlying binary to a hex string
>> representation. I need to convert the answer with ‘bfh’ and then call the
>> SHA256 algorithm again:
>> 
>>   3&(128!:6) bfh 3&(128!:6) bfh header_hex
>> 1dbd981fe6985776b644b173a4d0385ddc1aa2a829688d1e0000000000000000
>> 
>> This is the correct double hash that is agreement with the wiki article
>> listed above.
>> 
>> So 2 questions from all of this:
>> 
>> 1) is there a more efficient way of converting a string of hex characters
>> into a binary character array?
>> 
>> 2) Shouldn’t the SHA algorithms send the raw binary back so that you can
>> use the power conjunction with it to do multiple hashes?
>> ----------------------------------------------------------------------
>> For information about J forums see http://www.jsoftware.com/forums.htm 
>> <http://www.jsoftware.com/forums.htm>
>> 
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm 
> <http://www.jsoftware.com/forums.htm>
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to