Байты некорректно передаются в base64 из C# в Java

252
19 октября 2017, 08:37

Есть вот такой вот кусок кода на c# который конвертит интовский массив в base64.

int[] mas = new int[4] { 127, 15, 25, 118 };
byte[] binData = new byte[2 + 2 + 4 + 4];
BitConverter.GetBytes((ushort)mas[0]).CopyTo(binData, 0);
BitConverter.GetBytes((ushort)mas[1]).CopyTo(binData, 2);
BitConverter.GetBytes((uint)mas[2]).CopyTo(binData, 4);
BitConverter.GetBytes((uint)mas[3]).CopyTo(binData, 8);
string BASE64 = Convert.ToBase64String(binData);
Console.WriteLine(BASE64);

После этого я копирую получившуюся base64 последовательность и в java разбираю её по байтам с помощью ByteBuffer'а. Вот код.

byte[] decoded = Base64.getDecoder().decode("fwAPABkAAAB2AAAA");
ByteBuffer tel=ByteBuffer.wrap(decoded);
int agg_id   =   tel.getInt(4);
int status   =  tel.get(8);

getInt по сути должен брать по 4 байта и и собирать эти 4 байта назад в число интовского типа. В байтах получается вот такая вот последовательность:

127 0 15 0 25 0 0 0 118 0 0 0

То есть getInt(4) должен взять 25 0 0 0. И сделать из них назад число 25 типа int. Но почему то в переменную agg_id записывается вот такое вот значение 419430400. Дебажил полностью проваливаясь в getInt и всё смотрел полностью но так и не понял почему такой результат. Может кто то подсказать в чём дело?

Answer 1

Как уже написал @AndreyM в комментариях при передаче изменился порядок байтов в представлении числа.

... getInt(4) должен взять 25 0 0 0. И сделать из них назад число 25 типа int. Но почему то в переменную agg_id записывается вот такое вот значение 419430400

25*256*256*256 = 419430400, т.е. ByteBuffer считает первый байт старшим.

В документации ByteBuffer действительно указано, что по-умолчанию действительно принят порядок от старшего к младшему:

... The initial order of a byte buffer is always BIG_ENDIAN.

Изменить порядок можно с помощью метода ByteBuffer.order:

ByteBuffer tel=ByteBuffer.wrap(decoded);
tel.order(ByteOrder.LITTLE_ENDIAN);
int agg_id   =   tel.getInt(4);
...

Для сведения, порядок байтов, который использует BitConverter.GetBytes определяется свойствами машины:

The order of bytes in the array returned by the GetBytes method depends on whether the computer architecture is little-endian or big-endian.

Порядок в текущей системе можно проверить с помощью BitConverter.IsLittleEndian.

READ ALSO
Свойство IsReadOnly в ICollection<T>

Свойство IsReadOnly в ICollection<T>

Пытаюсь разобраться в написании собственных коллекций (да и вообще по глубже разобраться в коллекциях)

205
Перемещение файла в корзину

Перемещение файла в корзину

Имеется заданный путь к файлу, подскажите, как переместить его в корзину?

329
MYSQL C# ошибка при вызове хранимой процедуры

MYSQL C# ошибка при вызове хранимой процедуры

Добрый верчерЯ на C# и MySql делал проект онлайн меню заказа еды

282