Pergunta

Eu estou tentando converter uma seqüência-HEX para uma string codificada em ambos, ISO-8859-1, UTF-8 ou UTF-16BE. Ou seja, eu tenho uma String parecendo: "0422043504410442" este representa os caracteres:. "Test" em UTF-16BE

O código que usei para converter entre os dois formatos foi:

private static String hex2String(String hex, String encoding) throws UnsupportedEncodingException {
    char[] hexArray = hex.toCharArray();

    int length = hex.length() / 2;
    byte[] rawData = new byte[length];
    for(int i=0; i<length; i++){
        int high = Character.digit(hexArray[i*2], 16);
        int low = Character.digit(hexArray[i*2+1], 16);
        int value = (high << 4) | low;
        if( value > 127)
                value -= 256;
        rawData[i] = (byte) value;
    }
    return new String(rawData, encoding);
}

Este parece funcionar bem para mim, mas eu ainda tenho duas perguntas sobre isso:

  1. Existe alguma maneira mais simples (de preferência sem bit de manipulação) para fazer esta conversão?
  2. Como posso interpretar a linha:? int value = (high << 4) | low;

Estou familiarizado com os conceitos básicos de bit-assistência, embora não em tudo com a sintaxe Java. Eu acredito que a primeira parte deslocar todos os bits à esquerda por 4 etapas. Embora o resto eu não entendo e por que seria útil nesta determinada situação.

Peço desculpas por qualquer confusão na minha pergunta, por favor, deixe-me saber se eu deveria esclarecer nada. Obrigado. // Abeansits

Foi útil?

Solução

Existe alguma maneira mais simples (de preferência sem bit de manipulação) para fazer esta conversão?

Nenhum eu conheço - o único simplificação parece analisar todo o byte de uma só vez, em vez de analisar dígito por dígito (por exemplo, usando int value = Integer.parseInt(hex.substring(i * 2, i * 2 + 2), 16);)

public static byte[] hexToBytes(final String hex) {
  final byte[] bytes = new byte[hex.length() / 2];
  for (int i = 0; i < bytes.length; i++) {
    bytes[i] = (byte) Integer.parseInt(hex.substring(i * 2, i * 2 + 2), 16);
  }
  return bytes;
}

Como posso interpretar a linha: valor int = (alta << 4) | baixo;?

olhar para este exemplo para seus dois últimos dígitos (42):

int high = 4; // binary 0100
int low = 2; // binary 0010
int value = (high << 4) | low;

int value = (0100 << 4) | 0010; // shift 4 to left
int value = 01000000 | 0010; // bitwise or
int value = 01000010;
int value = 66; // 01000010 == 0x42 == 66

Outras dicas

Você pode substituir o << e | neste caso com * e +, mas eu não recomendo.

A expressão

int value = (high << 4) | low;

é equivalente a

int value = high * 16 + low;

A subtração de 256 para obter um valor entre -128 e 127 é desnecessário. Simplesmente fundição, por exemplo, 128 a um byte vai produzir o resultado correcto. As mais baixas 8 bits do int 128 têm o mesmo padrão que o byte -128:. 0x80

Eu escrevê-lo simplesmente como:

rawData[i] = (byte) ((high << 4) | low);

Existe alguma maneira mais simples (de preferência sem bit de manipulação) para fazer isso conversão?

Você pode usar o Hex classe em commons Apache, mas internamente, ele vai fazer a mesma coisa, talvez com pequenas diferenças.

Como posso interpretar a linha:? int value = (high << 4) | low;

Este combina dois dígitos hexadecimais, cada um dos quais representa 4 bits, para um valor de 8 bits sem sinal armazenado como um int. As próximas duas linhas converter isso em um byte Java assinado.

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