Pergunta

Estou calculando a soma de verificação de 16 bits nos meus dados que preciso enviar ao servidor para que ele deve recalcular e combinar com a soma de verificação fornecida. Valor de soma de verificação que estou recebendo está no int, mas tenho apenas 2 bytes para enviar o valor. Então estou lançando int para short enquanto ligava shortToBytes método. Isso funciona bem até que o valor da soma de verificação seja inferior a 32767 a partir de então, estou obtendo valores negativos.

Coisa é que Java não tem primitivas não assinadas, então não consigo enviar valores maiores que o valor máximo de assinado short permitido.

Como posso fazer isso, convertendo int para curto e enviar a rede sem se preocupar com truncamento e assinado e não assinado.

Também em ambos os lados, tenho o programa Java em execução.

   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();
    }
Foi útil?

Solução

Você ainda está obtendo o mesmo valor de bit que o servidor. Então, para ver o valor numérico certo, substitua o ByteBuffer.wrap(baValue).getShort() para um ByteBuffer.wrap(baValue).getInt(). Isso deve fornecer o mesmo valor numérico que o servidor.

Outras dicas

char é um tipo de 16 bits não assinado. Na verdade, é o único tipo não assinado em Java. Você pode usá -lo para calcular a soma de verificação e depois usar um ByteBuffer Para obter os bytes ou simplesmente usar bit e e mudar para obter os bytes.

Ter em mente que bytes são assinados.

Em primeiro lugar, Java int, short e byte Todos os tipos não são assinados não assinados. Em segundo lugar, quando você lança um java int para um short, etc, você terá truncamento silencioso.

Se isso importa depende da natureza do algoritmo de soma de verificação. Se for uma soma simples ou um algoritmo bit -bit, há uma boa chance de que o algoritmo esteja bem quando implementado usando números inteiros assinados por Java. Por exemplo, essas somas de verificação de 16 bits "negativas" podem estar corretas quando interpretadas por algo que espera valores não assinados.

Por outro lado, a semântica de multiplicação e divisão é tal que sabores assinados e não assinados devem ser tratados separadamente. (Pelo menos, é isso que deduzo da abordagem não científica de olhar para o conjunto de instruções X86 ... que possui instruções separadas para multiplicação e divisão assinadas versus não assinadas.)

EDITAR Eu entendo que você está calculando o CRC-16. Como isso pode ser calculado mudando e xoring, não deve haver preocupações com números assinados versus não assinados durante o cálculo.

Em suma, você não tem nada com que se preocupar.

Quando você diz que está obtendo valores negativos, presumo que você quer dizer quando leu o valor de 16 bits e o converte em um número inteiro. A razão para isso é que a extensão do sinal faz com que o bit mais significativo (que é 1) seja replicado quando o short é ampliado para um int. A solução alternativa simples é bit e o número inteiro reconstruído com 0xFFFF, o que garantirá que apenas os 16 bits menos significativos sejam diferentes de zero.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top