Home > Blockchain >  Split two large hex ranges into smaller equal ranges
Split two large hex ranges into smaller equal ranges

Time:10-23

I have been stuck on a problem for quite a few days. I have tried many things including converting hex to dec and then converting back again, but I have had no luck.

For those that are interested, I am creating software for someone who is looking at the Bitcoin 120 Puzzle. https://privatekeys.pw/puzzles/bitcoin-puzzle-tx

The ranges I have are

Start_Range = 0x800000000000000000000000000000
End_Range = 0xffffffffffffffffffffffffffffff

Numpy has said they are too big to split as a whole range.

My wanted outcome would potentially 500,000 - 1,000,000 equal subranges ranges between these two hex ranges in a multidimensional list.

i.e. omitting the 0x

[[80000, 800FF], ....]

Thanks for any help, I have been stuck for nearly a week on this.

CodePudding user response:

Your string literals are indeed too long to covert them to integers.

But you can "split" them into 2 parts:

  • the "lower" part, last 16 hex digits,
  • the "upper" part, first 14 hex digits.

Actually, you are interested only in both "upper parts", so set your range borders as strings containig hex digits, without the initial "0x":

Start_Range = '800000000000000000000000000000'
End_Range   = 'ffffffffffffffffffffffffffffff'

Then set both "upper parts" of each border as:

x1 = int(Start_Range[0:14], 16)
x2 = int(End_Range[0:14], 16)

this time as integers.

Compute also the size of this range:

siz = x2 - x1

When you print them, you will get:

36028797018963968 72057594037927935 36028797018963967

For simplicity, assume that you want to split your source range into just 10 subranges, so define:

n = 10

And to generate the table of subrange borders, run:

tbl = np.arange(x1, x2, siz // n)

You can print borders of each subrange and their sizes with the following code:

t1 = tbl[0]
for i in range(1, len(tbl)):
    t2 = tbl[i]
    print(f'{i:3}:  {t1},  {t2},  {t2 - t1}')
    t1 = t2

getting:

 1:  36028797018963968,  39631676720860364,  3602879701896396
 2:  39631676720860364,  43234556422756760,  3602879701896396
 3:  43234556422756760,  46837436124653156,  3602879701896396
 4:  46837436124653156,  50440315826549552,  3602879701896396
 5:  50440315826549552,  54043195528445948,  3602879701896396
 6:  54043195528445948,  57646075230342344,  3602879701896396
 7:  57646075230342344,  61248954932238740,  3602879701896396
 8:  61248954932238740,  64851834634135136,  3602879701896396
 9:  64851834634135136,  68454714336031532,  3602879701896396
10:  68454714336031532,  72057594037927928,  3602879701896396

Of course, the "true" value of each border can be computed multiplying each value by 2 ** 32, but you actually don't need them (expressed as an integer).

Split also your source values into "lower" and "upper" parts and decide to which "target subrange" it goes based solely on the upper part of the value in question.

Edit

A small correction: The upper limit of the last subrange is actually x2 (computed earlier).

  • Related