Criando uma seqüência ISO-8859-1 de um HEX-string em Java, pedaços deslocando
-
06-07-2019 - |
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:
- Existe alguma maneira mais simples (de preferência sem bit de manipulação) para fazer esta conversão?
- 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
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.