Eu estou procurando uma maneira de converter uma seqüência longa (de um despejo), que representa valores hexadecimais em uma matriz de bytes.
Eu não poderia ter formulado melhor do que a pessoa que postou a mesma pergunta aqui .
Mas, para mantê-lo original, vou dizer do meu jeito: suponha que eu tenha uma string "00A0BF"
que gostaria de interpretar como a
byte[] {0x00,0xA0,0xBf}
O que devo fazer?
Eu sou um novato em Java e acabei usando BigInteger
e cuidando dos principais zeros hexadecimais. Mas acho feio e tenho certeza de que estou perdendo algo simples.
BigInteger
aqui .String.getBytes()
não funcionará como você pensa. Tive que aprender isso da maneira mais difícil.if ("FF".getBytes() != "ff".getBytes()) { System.out.println("Try again"); }
Respostas:
Aqui está uma solução que eu acho melhor do que qualquer outra postada até agora:
Razões pelas quais é uma melhoria:
Seguro com zeros à esquerda (ao contrário do BigInteger) e com valores de bytes negativos (ao contrário de Byte.parseByte)
Não converte a String em um
char[]
nem cria objetos StringBuilder e String para cada byte.Nenhuma dependência de biblioteca que pode não estar disponível
Sinta-se à vontade para adicionar verificação de argumento por meio de
assert
ou exceções, se o argumento não for seguro.fonte
One-liners:
Advertências :
eckes
)Fabian
por observar isso), mas você pode usar o código-fonte se o seu sistema faltarjavax.xml
por algum motivo. Obrigado a @Bert Regelink
por extrair a fonte.fonte
java.se
conjunto raiz (padrão) , portanto resultará em um, aClassNotFoundException
menos que você especifique--add-modules java.se.ee
javax.xml.bind.DatatypeConverter
já fornece um método para codificar / decodificar dados Base64. VejaparseBase64Binary()
eprintBase64Binary()
.DataTypeConverter
, o Java SE 11 removeu completamente a API JAXB e agora está incluído apenas no Java EE. Você também pode adicioná-lo como uma dependência do Maven, conforme sugerido aqui: stackoverflow.com/a/43574427/7347751A classe Hex no commons-codec deve fazer isso por você.
http://commons.apache.org/codec/
fonte
Agora você pode usar BaseEncoding no
guava
para alcançar este objetivo.Para inverter, use
fonte
Na verdade, acho que a solução BigInteger é muito boa:
Edit: Não é seguro para zeros à esquerda , conforme observado no pôster.
fonte
Para aqueles que estão interessados no código real por trás dos One-liners do FractalizeR (eu precisava que, já que o javax.xml.bind não estivesse disponível para Android (por padrão)), isso vem de com.sun.xml.internal.bind. DatatypeConverterImpl.java :
fonte
O
HexBinaryAdapter
fornece a capacidade de empacotar e desempacotar entreString
ebyte[]
.Esse é apenas um exemplo que eu digitei ... Na verdade, eu apenas o uso como está e não preciso criar um método separado para usá-lo.
fonte
Aqui está um método que realmente funciona (com base em várias respostas semi-corretas anteriores):
O único problema possível que posso ver é se a string de entrada é extremamente longa; chamar toCharArray () faz uma cópia da matriz interna da string.
EDIT: Ah, e, a propósito, os bytes são assinados em Java; portanto, sua string de entrada é convertida em [0, -96, -65] em vez de [0, 160, 191]. Mas você provavelmente já sabia disso.
fonte
No android, se você estiver trabalhando com hex, poderá tentar o okio .
uso simples:
e o resultado será
fonte
O
BigInteger()
método de java.math é muito lento e não é recomendável.Integer.parseInt(HEXString, 16)
pode causar problemas com alguns caracteres sem converter para dígito / número inteiro
um método de trabalho bem:
Função:
Divirta-se, boa sorte
fonte
EDIT: como apontado por @mmyers, esse método não funciona na entrada que contém substrings correspondentes a bytes com o conjunto de bits alto ("80" - "FF"). A explicação está na identificação do bug: 6259307 Byte.parseByte não está funcionando conforme anunciado na documentação do SDK .
fonte
Para o que vale, aqui está outra versão que suporta strings de comprimento ímpar, sem recorrer à concatenação de strings.
fonte
Eu sempre usei um método como
esse método divide-se em valores hexadecimais delimitados por espaço, mas não seria difícil dividir a string em outros critérios, como em agrupamentos de dois caracteres.
fonte
Byte
/byte
caso: maior conjunto de bits sem levar -)Eu gosto da solução Character.digit, mas aqui está como eu a resolvi
fonte
O código apresentado por Bert Regelink simplesmente não funciona. Tente o seguinte:
fonte
Achei o Kernel Panic a solução mais útil para mim, mas tive problemas se a sequência hexadecimal fosse um número ímpar. resolveu assim:
Estou adicionando um número de números hexadecimais a uma matriz, por isso passo a referência à matriz que estou usando e o int que preciso converter e retornar a posição relativa do próximo número hexadecimal. Portanto, a matriz de bytes final tem [0] número de pares hexadecimais, [1] [...] pares hexadecimais e, em seguida, o número de pares ...
fonte
Com base na solução votada pelo op, o seguinte deve ser um pouco mais eficiente:
Porque: a conversão inicial em uma matriz char poupa as verificações de comprimento em charAt
fonte
Se você prefere os fluxos Java 8 como seu estilo de codificação, isso pode ser alcançado usando apenas primitivas JDK.
Os
, 0, s2.size()
parâmetros na função concatenar do coletor podem ser omitidos se você não se importar em capturarIOException
.fonte
fonte
Minha solução formal:
É como a função hex2bin () do PHP, mas no estilo Java.
Exemplo:
fonte
Tarde para a festa, mas eu juntei a resposta acima de DaveL em uma classe com a ação inversa - para o caso de ajudar.
E classe de teste JUnit:
fonte
Eu sei que este é um tópico muito antigo, mas ainda assim gostaria de acrescentar meu centavo.
Se eu realmente precisar codificar uma simples cadeia hexadecimal para conversor binário, gostaria de fazer o seguinte.
fonte
De longe não é a solução mais limpa. Mas funciona para mim e está bem formatado:
A saída:
fonte
Eu acho que vai fazer isso por você. Eu o juntei de uma função semelhante que retornava os dados como uma string:
fonte
Para mim, essa foi a solução, HEX = "FF01" e depois dividida em FF (255) e 01 (01)
fonte