Я ищу объяснение какой-то странности, которую я видел в чьем-то коде elses, они извлекали значение "int64" из сторонней библиотеки, читая из атрибута LDAP, эта библиотека вернула массив байтов. Чтобы получить значение, они пробовали что-то вроде
String s = new String(bytesFrom3rdParty);
BigInteger i = new BigInteger(s.getBytes());
System.out.println(i.toString());
С некоторыми длинными значениями это давало неверный результат, которого не ожидалось. Для меня выделялись две вещи:
- Почему go из байтового массива -> String -> Bytes -> BigInteger
- Зачем использовать BigInteger для 64-битных чисел c значение.
В любом случае я провел небольшой эксперимент
private static byte[] longToByteArray(Long l) {
return ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong(l).array();
}
private static Long byteArrayToLong(byte[] bytes) {
return ByteBuffer.wrap(bytes).getLong();
}
public static void main(String[] args) {
for (long l = 0L; l < 1000; l++) {
byte[] origBytes = longToByteArray(l);
String s = new String(origBytes);
byte[] stringBytes = s.getBytes();
Long origL = byteArrayToLong(origBytes);
Long stringL = byteArrayToLong(stringBytes);
System.out.println(origL.toString() + " " + stringL.toString());
}
}
Как я и подозревал, пропуск преобразования в строку, а затем обратно в массив байтов, устранил проблему, вывод из выше это что-то вроде
124 124
125 125
126 126
127 127
128 239
129 239
130 239
131 239
132 239
И затем значение правой руки снова исправляется, когда оно достигает 256
254 239
255 239
256 256
257 257
258 258
259 259
260 260
261 261
262 262
263 263
264 264
Итак, пара вопросов от меня
- Почему значение правой руки неверно? Я предполагаю, что это как-то связано с преобразованием между 64-битным длинным значением в 32-битное строковое значение?
- Почему неправильное значение не изменяется, пока значение
l
не достигнет 256?