Pregunta

Estoy tratando de convertir un HEX-secuencia de una Cadena codificada en ISO-8859-1, UTF-8 o UTF-16BE.Es decir, tengo una Cadena parecida a: "0422043504410442" esto representa a los personajes: "Test" en UTF-16BE.

El código que he usado para convertir entre los dos formatos:

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);
}

Esto parece funcionar muy bien para mí, pero todavía tengo dos preguntas con respecto a esto:

  1. ¿Hay alguna manera más sencilla (preferiblemente sin bit de manejo) para hacer esta conversión?
  2. ¿Cómo debo interpretar la línea: int value = (high << 4) | low;?

Estoy familiarizado con los conceptos básicos de los bits de manejo, aunque no en todos, con la sintaxis de Java.Yo creo que la primera parte mayús todos los bits a la izquierda por 4 pasos.Aunque el resto no lo entiendo y por qué sería útil en esta situación determinada.

Pido disculpas por cualquier confusión en mi pregunta, por favor hágamelo saber si debo aclarar nada.Gracias.//Abeansits

¿Fue útil?

Solución

¿Hay alguna forma más sencilla (preferiblemente sin manejo de bits) para hacer esta conversión?

Ninguno que yo conozca: la única simplificación parece analizar todo el byte a la vez en lugar de analizar dígito a dígito (por ejemplo, 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;
}

¿Cómo debo interpretar la línea: int value = (high < < 4) | bajo ;?

mire este ejemplo para sus dos ú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

Otros consejos

Puede reemplazar el << y | en este caso con * y +, pero no lo recomiendo.

La expresión

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

es equivalente a

int value = high * 16 + low;

La sustracción de 256 para obtener un valor entre -128 y 127 es innecesario.Simplemente casting, por ejemplo, 128, un byte se produce el resultado correcto.El menor de 8 bits de la int 128 el mismo patrón, como el byte -128:0x80.

Me gustaría escribir simplemente como:

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

¿Hay alguna forma más simple (preferiblemente   sin manejo de bits) para hacer esto   conversión?

Puede usar el Hex class en Apache commons, pero internamente, hará lo mismo, quizás con pequeñas diferencias.

  

¿Cómo debo interpretar la línea: int value = (high << 4) | low;?

Esto combina dos dígitos hexadecimales, cada uno de los cuales representa 4 bits, en un valor de 8 bits sin signo almacenado como un int. Las siguientes dos líneas convierten esto en un Java byte firmado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top