преобразование Java в короткие - PullRequest
0 голосов
/ 21 марта 2010

Я рассчитываю 16-битную контрольную сумму на моих данных, которые мне нужно отправить на сервер, где они должны пересчитать и сопоставить с предоставленной контрольной суммой. Значение контрольной суммы, которое я получаю, находится в int, но у меня есть только 2 байта для отправки значения. Так что я передаю int в short при вызове метода shortToBytes. Это работает нормально, пока значение контрольной суммы не станет меньше 32767, после чего я получу отрицательные значения.

Дело в том, что в java нет беззнаковых примитивов, поэтому я не могу отправить значения, превышающие максимально допустимое значение short.

Как я могу это сделать, преобразовав int в short и отправив по сети, не беспокоясь об усечении и подписанном и неподписанном int.

Также с обеих сторон у меня запущена Java-программа.

   private byte[] shortToBytes(short sh) {
        byte[] baValue = new byte[2];
        ByteBuffer buf = ByteBuffer.wrap(baValue);
        return buf.putShort(sh).array();
    }

    private short bytesToShort(byte[] buf, int offset) {
        byte[] baValue = new byte[2];
        System.arraycopy(buf, offset, baValue, 0, 2);
        return ByteBuffer.wrap(baValue).getShort();
    }

Ответы [ 4 ]

1 голос
/ 21 марта 2010

char - 16-разрядный тип без знака. Фактически это единственный неподписанный тип в Java. Вы можете использовать его для вычисления контрольной суммы, а затем использовать ByteBuffer для получения байтов или просто использовать побитовое и правое смещение для получения байтов.

Имейте в виду, что byte s подписано.

1 голос
/ 21 марта 2010

Вы по-прежнему получаете то же битовое значение, что и сервер.Таким образом, чтобы увидеть правильное числовое значение, замените ByteBuffer.wrap(baValue).getShort() на ByteBuffer.wrap(baValue).getInt().Это должно дать вам то же числовое значение, что и сервер.

1 голос
/ 21 марта 2010

Во-первых, все типы Java int, short и byte подписаны, а не подписаны. Во-вторых, когда вы приведете Java int к short и т. Д., Вы получите тихое усечение.

Вопрос, имеет ли это значение, зависит от природы алгоритма контрольной суммы. Если это простая сумма, или побитовый алгоритм, есть хороший шанс, что алгоритм будет хорошо работать, если реализован с помощью целых чисел со знаком Java. Например, эти «отрицательные» 16-битные контрольные суммы могут быть правильными, если они интерпретируются чем-то, ожидающим значения без знака.

С другой стороны, семантика умножения и деления такова, что варианты со знаком и без знака должны обрабатываться отдельно. (По крайней мере, это то, что я делаю из ненаучного подхода к просмотру набора команд x86 ... в котором есть отдельные инструкции для умножения и деления со знаком и без знака.)

РЕДАКТИРОВАТЬ Я понимаю, что вы рассчитываете CRC-16. Поскольку это можно вычислить с помощью сдвига и XORing, при вычислении не должно быть беспокойства относительно чисел со знаком или без знака.

Короче, вам не о чем беспокоиться.

0 голосов
/ 21 марта 2010

Когда вы говорите, что получаете отрицательные значения, я предполагаю, что вы имеете в виду, когда вы читаете 16-битное значение и конвертируете его в целое число. Причина этого заключается в том, что расширение знака приводит к репликации самого значимого бита (равного 1), когда short увеличивается до int. Простой обходной путь - это побитовое и восстановленное целое число с 0xFFFF, что обеспечит ненулевое значение только 16 младших разрядов.

...