Получение строкового представления большого целого числа и преобразование его в массив байтов в Java

#java #bytearray #endianness #bitcoin

#java #массивы #Порядковый номер #биткойн

Вопрос:

По сути, моя проблема двоякая и относится довольно конкретно к RPC биткойнов. Я пишу майнер на Java для Litecoin (побочный продукт BTC), и мне нужно взять строку, которая выглядит как:

 000000000000000000000000000000000000000000000000000000ffff0f0000
  

Преобразуйте его так, чтобы оно выглядело как

 00000fffff000000000000000000000000000000000000000000000000000000
  

(Который, я полагаю, переключается с младшего на большой конечный)

Затем мне нужно превратить эту строку в массив байтов —

Я посмотрел на класс Hex из org.apache, String.toByte() и фрагмент кода, который выглядит как:

 public static byte[] toByta(char[] data) {
    if (data == null) return null;
    // ----------
    byte[] byts = new byte[data.length * 2];
    for (int i = 0; i < data.length; i  )
        System.arraycopy(toByta(data[i]), 0, byts, i * 2, 2);
    return byts;
}
  

Итак, по сути: каков наилучший способ в Java изменить порядковый номер? И каков наилучший способ взять строковое представление числа и преобразовать его в массив байтов для хэширования?

РЕДАКТИРОВАТЬ: у меня был неправильный результат после изменения порядкового номера.

Комментарии:

1. Вероятно, наиболее эффективным было бы пропустить преобразование в конце строки и просто создать массив байтов непосредственно из массива символов в конце строки, по два байта за раз. Легко написать свой собственный преобразователь шестнадцатеричных символов в двоичные байты, чтобы вы могли избежать скопирования массива.

2. Но обратите внимание, что продемонстрированное вами преобразование в конце было неправильным. Первые пять шестнадцатеричных цифр должны быть равны нулю.

3. Обратите внимание, что ваш новый массив байтов должен быть ВДВОЕ меньше массива символов, а не вдвое больше его длины.

4. Я изменил преобразование в конце, чтобы оно было правильным. Почему это должно составлять половину длины массива символов? Я думал, что символы были по одному байту каждый?

5. @D.vanderbleek Java использует UTF-16 внутри

Ответ №1:

  1. Integer и BigInteger оба имеют методы toString, использующие радиус, поэтому вы можете получить шестнадцатеричную строку.
  2. Вы можете создать StringBuffer из этой строки и вызвать reverse().
  3. Затем вы преобразуете обратно в строку с помощью toString(), затем получаете байты с помощью getBytes();

Не знаю, является ли это «лучшим», но это требует небольшой работы с вашей стороны.

Если вам нужна лучшая скорость, вызовите getBytes() для исходной шестнадцатеричной строки неправильного направления (с шага 1) и измените ее на место, используя цикл for. например

 for (int i=0; i<bytes.length/2; i  ) {
   byte temp = bytes[i];
   bytes[i] = bytes[bytes.length - i];
   bytes[bytes.length - i] = temp;
}