Разделить два больших шестнадцатеричных диапазона на меньшие равные диапазоны

#python #numpy #range #hex #bitcoin

Вопрос:

Я застрял на проблеме уже несколько дней. Я пробовал много вещей, включая преобразование шестнадцатеричного числа в десятичное, а затем преобразование обратно, но мне не повезло.

Для тех, кому интересно, я создаю программное обеспечение для тех, кто смотрит на головоломку Bitcoin 120. https://privatekeys.pw/puzzles/bitcoin-puzzle-tx

У меня есть следующие диапазоны

 Start_Range = 0x800000000000000000000000000000
End_Range = 0xffffffffffffffffffffffffffffff
 

Numpy сказал, что они слишком большие, чтобы разделить их как целый диапазон.

Мой желаемый результат потенциально мог бы составлять 500 000-1 000 000 равных поддиапазонов между этими двумя шестнадцатеричными диапазонами в многомерном списке.

т.е. опустить 0x

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

Спасибо за любую помощь, я застрял на этом почти неделю.

Ответ №1:

Ваши строковые литералы действительно слишком длинные, чтобы преобразовать их в целые числа.

Но вы можете «разделить» их на 2 части:

  • «нижняя» часть, последние 16 шестнадцатеричных цифр,
  • «верхняя» часть, первые 14 шестнадцатеричных цифр.

На самом деле, вас интересуют только обе «верхние части», поэтому установите границы диапазона в виде строк, содержащих шестнадцатеричные цифры, без начального «0x»:

 Start_Range = '800000000000000000000000000000'
End_Range   = 'ffffffffffffffffffffffffffffff'
 

Затем установите обе «верхние части» каждой границы как:

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

на этот раз как целые числа.

Вычислите также размер этого диапазона:

 siz = x2 - x1
 

Когда вы их распечатаете, вы получите:

 36028797018963968 72057594037927935 36028797018963967
 

Для простоты предположим, что вы хотите разделить исходный диапазон всего
на 10 поддиапазонов, поэтому определите:

 n = 10
 

И чтобы сгенерировать таблицу границ поддиапазонов, выполните:

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

Вы можете распечатать границы каждого поддиапазона и их размеры с помощью следующего кода:

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

получение:

  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
 

Конечно, «истинное» значение каждой границы можно вычислить, умножив каждое
значение на 2 ** 32 , но на самом деле они вам не нужны (выражаются в виде целого числа).

Разделите также ваши исходные значения на «нижнюю» и «верхнюю» части и решите, к какому «целевому поддиапазону» он относится, основываясь исключительно на верхней части рассматриваемого значения.

Редактировать

Небольшая поправка: верхний предел последнего поддиапазона на самом деле равен x2 (вычисленный ранее).