Como converter uma matriz de bytes em uma sequência hexadecimal em Java?
649
Eu tenho uma matriz de bytes cheia de números hexadecimais e imprimi-la da maneira mais fácil é inútil, porque há muitos elementos não imprimíveis. O que eu preciso é o código hexadecimal exato na forma de:3a5f771c
Por que não tentar primeiro e nos mostrar o que você tem? Você não tem nada a perder e tudo a ganhar. O número inteiro tem um toHexString(...)método que pode ajudar se é isso que você está procurando. Também é String.format(...)possível fazer alguns truques de formatação usando a %2xsequência de códigos.
"O que eu preciso é do código hexadecimal exato na forma de: 3a5f771c ..." - você solicitou uma forma exata, mas não forneceu um exemplo exato. Seguindo o que você forneceu, converta os quatro primeiros bytes em uma sequência e concatene as elipses na sequência.
JWW
1
Com a ajuda do fluxo no Java 8, ele pode ser simplesmente implementado como: String estática byteArrayToHex (byte [] a) {retorne IntStream.range (0, comprimento) .mapToObj (i -> String.format ("% 02x ", a [i])) .reduce ((acc, v) -> acc +" "+ v) .get (); }
tibetty 10/10/1919
Respostas:
901
A partir da discussão aqui , e especialmente desta resposta, esta é a função que atualmente uso:
Meus próprios benchmarks minúsculos (um milhão de bytes por mil vezes, 256 bytes 10 milhões de vezes) mostraram que era muito mais rápido do que qualquer outra alternativa, cerca da metade do tempo em arrays longos. Comparado à resposta da qual tirei, alternar para operações bit a bit - como sugerido na discussão - reduziu em cerca de 20% o tempo para arrays longos. (Edit: Quando digo que é mais rápido que as alternativas, quero dizer o código alternativo oferecido nas discussões. O desempenho é equivalente ao Commons Codec, que usa código muito semelhante.)
Versão 2k20, com relação às seqüências compactas Java 9:
Acabei de encontrar javax.xml.bind.DataTypeConverter , parte da distribuição padrão. Por que isso não ocorre quando você coloca esse tipo de problema no Google? Muitas ferramentas úteis, incluindo String printHexBinary(byte[])e byte[] parseHexBinary(String). printHexBinaryé, no entanto, muito (2x) mais lento que a função nesta resposta. (Eu verifiquei a fonte; ela usa a stringBuilder. parseHexBinaryUsa uma matriz.) Na verdade, para a maioria dos propósitos, é rápido o suficiente e você provavelmente já a possui.
maybeWeCouldStealAVan
75
+1 para a resposta desde Android não tem DataTypeConverter
Vaiden
7
@maybeWeCouldStealAVan: O JDK 7 agora é de código aberto. Devemos enviar um patch para melhorar o desempenho printHexBinary?
Kevinarpe
3
@maybeWeCouldStealAVan, você poderia explicar como isso funciona. Eu sigo na maioria das vezes, mas gosto muito de entender o que está acontecendo ao usar código. Obrigado!
JjNford 12/07
24
javax.xml.bind.DataTypeConverterestá a ser removido a partir de Java 11.
O Empalador
421
A biblioteca do Apache Commons Codec tem uma classe Hex para fazer exatamente esse tipo de trabalho.
import org.apache.commons.codec.binary.Hex;String foo ="I am a string";byte[] bytes = foo.getBytes();System.out.println(Hex.encodeHexString( bytes ));
@cytinus - Meu voto negativo ocorreu há 4 meses, então não tenho muita certeza do que estava pensando, mas provavelmente estava me opondo ao tamanho da biblioteca. Esta é uma pequena função dentro do programa; não é necessário adicionar uma biblioteca tão volumosa ao projeto para executá-la.
ArtOfWarfare
6
@ArtOfWarefare Concordo, por isso, em vez de import org.apache.commons.codec.*;você poderia fazerimport org.apache.commons.codec.binary.Hex;
Cytinus
12
@ArtOfWarfare Eu tenho que discordar. A única coisa terrível é que as bibliotecas do apache commons não são incluídas por padrão no JRE e JDK. Existem algumas bibliotecas que são tão úteis que realmente deveriam estar no seu caminho de classe por padrão, e essa é uma delas.
precisa saber é o seguinte
29
Eu recomendo que esta resposta seja trocada como a resposta principal. Sempre vote para usar uma biblioteca de código-fonte aberto bem testada e com desempenho sobre um código personalizado que não melhora.
Dmitriy Likhten 26/02
6
Ou, caso você use BouncyCastle ( org.bouncycastle: bcprov-jdk15on ), você pode usar esta classe org.bouncycastle.util.encoders.HexString toHexString(byte[] data)
No Java 8 e versões anteriores, o JAXB fazia parte da biblioteca padrão do Java. Foi preterido no Java 9 e removido com o Java 11 , como parte de um esforço para mover todos os pacotes Java EE para suas próprias bibliotecas. É uma longa história . Agora, javax.xml.bindnão existe, e se você deseja usar o JAXB, que contém DatatypeConverter, precisará instalar a API JAXB e o JAXB Runtime do Maven.
Uma boa solução, embora infelizmente não seja válida no Android.
Kazriko
@Kazriko, talvez você queira ler code.google.com/p/dalvik/wiki/JavaxPackages . É uma maneira de obter classes javax no Android. Mas se você deseja converter apenas em hexadecimal, não vale a pena.
PhoneixS
13
DatatypeConverter não acessível a partir de JDK 9 é
pmcollins
3
@PhoneixS Ele ainda está lá, mas não faz parte do tempo de execução padrão (devido aos módulos Java 9).
Spotlight
2
não confie no javax.xml.bind, ele compila bem, mas não pode ser encontrado em tempo de execução. se o fizer, estar preparado para lidar java.lang.NoClassDefFoundError
Dmitry
227
Solução mais simples, sem bibliotecas externas, sem constantes de dígitos:
Isso é muito lento, em média 1000 vezes mais lento (com 162 bytes) do que o da resposta superior. Evite usar String.Format se o desempenho for importante.
pt123
8
Talvez devagar. É bom para coisas que acontecem ocasionalmente, como login ou similar.
Ponteiro Nulo
29
Se estiver lento, e daí? No meu caso de uso, é apenas para uma instrução de depuração, então obrigado por este fragmento de código.
vikingsteve
8
Reutilizar uma biblioteca incluindo arquivos JAR extras de várias dezenas de kB não seria exatamente eficiente se tudo o que você precisa é dessa função (em algumas plataformas como Android, todo o Jar é incluído no aplicativo final). E, às vezes, um código mais curto e mais claro é melhor quando o desempenho não é necessário.
personne3000
2
@ personne3000, talvez, mas nesse caso você precisa de suporte ao fluxo, não um recurso de chamada única. este é fácil de entender e lembrar, e portanto manter.
No Guava você também pode usar new HashCode(bytes).toString().
precisa saber é o seguinte
1
A partir da goiaba 22.0 éHashCode.fromBytes(checksum).toString()
Devstr
43
Este oneliner simples funciona para mim. String result = new BigInteger(1, inputBytes).toString(16);
EDIT - Usar isso removerá os zeros à esquerda, mas ele trabalhou no meu caso de uso. Obrigado @Voicu por apontar
@ Voicu ... E adicionará um zero inicial 50% do tempo.
Maarten Bodewes
27
Aqui estão algumas opções comuns ordenadas de simples (one-liner) a complexas (enorme biblioteca). Se você está interessado em desempenho, consulte os micro benchmarks abaixo.
Opção 1: snippet de código - Simples
Uma solução muito simples é usar a BigIntegerrepresentação hexadecimal da:
newBigInteger(1, someByteArray).toString(16)
Observe que, como ele lida com números que não sejam seqüências de bytes arbitrárias , ele omitirá zeros à esquerda - isso pode ou não ser o que você deseja (por exemplo, 000AE3vs 0AE3para uma entrada de 3 bytes). Isso também é muito lento, cerca de 100x mais lento em comparação com a próxima opção.
Opção 2: snippet de código - avançado
Aqui está um trecho de código completo, com cópia e colável que suporta maiúsculas / minúsculas e endianness . Ele é otimizado para minimizar a complexidade da memória e maximizar o desempenho e deve ser compatível com todas as versões modernas do Java (5+).
privatestaticfinalchar[] LOOKUP_TABLE_LOWER =newchar[]{0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x61,0x62,0x63,0x64,0x65,0x66};privatestaticfinalchar[] LOOKUP_TABLE_UPPER =newchar[]{0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};publicstaticString encode(byte[] byteArray,boolean upperCase,ByteOrder byteOrder){// our output size will be exactly 2x byte-array lengthfinalchar[] buffer =newchar[byteArray.length *2];// choose lower or uppercase lookup tablefinalchar[] lookup = upperCase ? LOOKUP_TABLE_UPPER : LOOKUP_TABLE_LOWER;int index;for(int i =0; i < byteArray.length; i++){// for little endian we count from last to first
index =(byteOrder ==ByteOrder.BIG_ENDIAN)? i : byteArray.length - i -1;// extract the upper 4 bit and look up char (0-A)
buffer[i <<1]= lookup[(byteArray[index]>>4)&0xF];// extract the lower 4 bit and look up char (0-A)
buffer[(i <<1)+1]= lookup[(byteArray[index]&0xF)];}returnnewString(buffer);}publicstaticString encode(byte[] byteArray){return encode(byteArray,false,ByteOrder.BIG_ENDIAN);}
O código fonte completo com licença e decodificador Apache v2 pode ser encontrado aqui .
Opção 3: Usando uma pequena biblioteca otimizada: bytes-java
Enquanto trabalhava no meu projeto anterior, criei este pequeno kit de ferramentas para trabalhar com bytes em Java. Não possui dependências externas e é compatível com Java 7+. Inclui, entre outros, um HEX en / decodificador muito rápido e bem testado:
Claro que existem os bons codecs comuns . ( avisando a opinião adiante ) Enquanto trabalhava no projeto descrito acima, analisei o código e fiquei bastante decepcionado; muitos códigos desorganizados duplicados, codecs obsoletos e exóticos provavelmente só são úteis para muito poucas implementações lentas e bem projetadas e de engenharia de codecs populares (especificamente Base64). Portanto, eu tomaria uma decisão informada se você quiser usá-lo ou como alternativa. De qualquer forma, se você ainda quiser usá-lo, aqui está um trecho de código:
Opção Realmente Não 8: Compatibilidade com Java 9+ ou 'Não use JAXBs javax / xml / bind / DatatypeConverter'
Nas versões anteriores do Java (8 e abaixo), o código Java para JAXB foi incluído como dependência de tempo de execução. Desde a modularização do Java 9 e do Jigsaw, seu código não pode acessar outro código fora do módulo sem declaração explícita. Esteja ciente de que você recebe uma exceção como:
ao executar em uma JVM com Java 9+. Nesse caso, mude as implementações para qualquer uma das alternativas acima. Veja também esta questão .
Micro Benchmarks
Aqui estão os resultados de um simples micro benchmark JMH que codifica matrizes de bytes de tamanhos diferentes . Os valores são operações por segundo, portanto, quanto maior, melhor.
Observe que os micro benchmarks muitas vezes não representam o comportamento do mundo real, portanto, leve esses resultados com um pouco de sal.
|Name(ops/s)|16byte|32byte|128byte|0.95 MB ||----------------------|-----------:|-----------:|----------:|--------:||Opt1:BigInteger|2,088,514|1,008,357|133,665|4||Opt2/3:BytesLib|20,423,170|16,049,841|6,685,522|825||Opt4:ApacheCommons|17,503,857|12,382,018|4,319,898|529||Opt5:Guava|10,177,925|6,937,833|2,094,658|257||Opt6:Spring|18,704,986|13,643,374|4,904,805|601||Opt7: BC |7,501,666|3,674,422|1,077,236|152||Opt8: JAX-B |13,497,736|8,312,834|2,590,940|346|
Especificações: JDK 8u202, i7-7700K, Win10, 24 GB de RAM. Veja a referência completa aqui .
O mais elegante, como ele também observa, acho que é este:
staticfinalString HEXES ="0123456789ABCDEF";publicstaticString getHex(byte[] raw ){if( raw ==null){returnnull;}finalStringBuilder hex =newStringBuilder(2* raw.length );for(finalbyte b : raw ){
hex.append(HEXES.charAt((b &0xF0)>>4)).append(HEXES.charAt((b &0x0F)));}return hex.toString();}
Outros métodos estavam em execução no meu exemplo de 64 bytes em 5ms, este é executado em 0ms. Provavelmente é melhor por falta de outras funções String, como formato.
Joseph Lust
if (raw == null) return nullnão falha rápido. Por que você usaria uma nullchave?
Maarten Bodewes
Suponho que seja um hábito inserir validações. Nesse caso, evitamos qualquer exceção de referência nula e deixamos que o chamador lide com dados incorretos.
Michael Bisbjerg 27/02
16
Com o menor custo de armazenamento da tabela de pesquisa, essa implementação é simples e muito rápida.
Por que não inicializar a BYTE2HEXmatriz com um forciclo simples ?
icza
@icza Isso é possível com um campo final estático (também conhecido como constante)?
Nevelis 06/07/19
1
@evelevel Pode ser atribuído em um static { }bloco.
131318
1
@icza porque é mais rápido codificar uma tabela de pesquisa do que gerá-la. Aqui, a complexidade da memória é trocada com a complexidade do tempo, ou seja. precisa de mais memória, mas mais rápido (cada assim ligeiramente em ambas as extremidades)
Patrick Favre
8
Que tal agora?
String byteToHex(finalbyte[] hash){Formatter formatter =newFormatter();for(byte b : hash){
formatter.format("%02x", b);}String result = formatter.toString();
formatter.close();return result;}
É uma adaptação um pouco mais flexível da resposta aceita. Pessoalmente, mantenho a resposta aceita e essa sobrecarga, utilizáveis em mais contextos.
Se o seu debuffer tem um dia ruim, tente cluing em StringBuilder instanciação com um número de caracteres para o suporte: StringBuilder buf = new StringBuilder(data.length * 2);.
13136
2
Ok, então existem várias maneiras de fazer isso, mas se você decidir usar uma biblioteca, sugiro bisbilhotar no seu projeto para ver se algo foi implementado em uma biblioteca que já faz parte do seu projeto antes de adicionar uma nova biblioteca. apenas para fazer isso. Por exemplo, se você ainda não possui
Adicionar uma jarra de utilidade para uma função simples não é uma boa opção. Em vez disso, monte suas próprias classes de utilitários. é possível uma implementação mais rápida.
Não é possível encontrar nesta solução nenhuma solução que não
Use um loop
Use javax.xml.bind.DatatypeConverter que compila bem, mas geralmente lança java.lang.NoClassDefFoundError em tempo de execução.
Aqui está uma solução que não possui as falhas acima (nenhuma promessa é minha, mas não tem outras falhas)
import java.math.BigInteger;importstatic java.lang.System.out;publicfinalclassApp2{// | proposed solution.publicstaticString encode(byte[] bytes){finalint length = bytes.length;// | BigInteger constructor throws if it is given an empty array.if(length ==0){return"00";}finalint evenLength =(int)(2*Math.ceil(length /2.0));finalString format ="%0"+ evenLength +"x";finalString result =String.format (format,newBigInteger(bytes));return result;}publicstaticvoid main(String[] args)throwsException{// 00
out.println(encode(newbyte[]{}));// 01
out.println(encode(newbyte[]{1}));//203040
out.println(encode(newbyte[]{0x20,0x30,0x40}));// 416c6c20796f75722062617365206172652062656c6f6e6720746f2075732e
out.println(encode("All your base are belong to us.".getBytes()));}}
Não consegui obter isso em 62 opcodes, mas se você puder viver sem preenchimento de 0, caso o primeiro byte seja menor que 0x10, a solução a seguir usará apenas 23 opcodes. Realmente mostra como soluções "fáceis de implementar" como "pad com zero se o comprimento da string for ímpar" podem ficar bem caras se uma implementação nativa ainda não estiver disponível (ou, neste caso, se o BigInteger tivesse a opção de prefixar zeros em para sequenciar).
publicstaticString encode(byte[] bytes){finalint length = bytes.length;// | BigInteger constructor throws if it is given an empty array.if(length ==0){return"00";}returnnewBigInteger(bytes).toString(16);}
Minha solução é baseada na solução de maybeWeCouldStealAVan, mas não depende de nenhuma tabela de pesquisa adicionalmente alocada. Ele não usa nenhuma ferramenta de conversão de 'int-to-char' (na verdade Character.forDigit(), executa algumas comparações para verificar qual é realmente o dígito) e, portanto, pode ser um pouco mais lenta. Por favor, sinta-se livre para usá-lo onde quiser. Felicidades.
publicstaticString bytesToHex(finalbyte[] bytes){finalint numBytes = bytes.length;finalchar[] container =newchar[numBytes *2];for(int i =0; i < numBytes; i++){finalint b = bytes[i]&0xFF;
container[i *2]=Character.forDigit(b >>>4,0x10);
container[i *2+1]=Character.forDigit(b &0xF,0x10);}returnnewString(container);}
publicstaticbyte[] hexStringToByteArray(String s){int len = s.length();byte[] data =newbyte[len /2];for(int i =0; i < len; i +=2){
data[i /2]=(byte)((Character.digit(s.charAt(i),16)<<4)+Character.digit(s.charAt(i+1),16));}return data;}
privatestaticString bytesToHexString(byte[] bytes,int length){if(bytes ==null|| length ==0)returnnull;StringBuilder ret =newStringBuilder(2*length);for(int i =0; i < length ; i++){int b;
b =0x0f&(bytes[i]>>4);
ret.append("0123456789abcdef".charAt(b));
b =0x0f& bytes[i];
ret.append("0123456789abcdef".charAt(b));}return ret.toString();}
toHexString(...)
método que pode ajudar se é isso que você está procurando. Também éString.format(...)
possível fazer alguns truques de formatação usando a%2x
sequência de códigos.Respostas:
A partir da discussão aqui , e especialmente desta resposta, esta é a função que atualmente uso:
Meus próprios benchmarks minúsculos (um milhão de bytes por mil vezes, 256 bytes 10 milhões de vezes) mostraram que era muito mais rápido do que qualquer outra alternativa, cerca da metade do tempo em arrays longos. Comparado à resposta da qual tirei, alternar para operações bit a bit - como sugerido na discussão - reduziu em cerca de 20% o tempo para arrays longos. (Edit: Quando digo que é mais rápido que as alternativas, quero dizer o código alternativo oferecido nas discussões. O desempenho é equivalente ao Commons Codec, que usa código muito semelhante.)
Versão 2k20, com relação às seqüências compactas Java 9:
fonte
String printHexBinary(byte[])
ebyte[] parseHexBinary(String)
.printHexBinary
é, no entanto, muito (2x) mais lento que a função nesta resposta. (Eu verifiquei a fonte; ela usa astringBuilder
.parseHexBinary
Usa uma matriz.) Na verdade, para a maioria dos propósitos, é rápido o suficiente e você provavelmente já a possui.printHexBinary
?javax.xml.bind.DataTypeConverter
está a ser removido a partir de Java 11.A biblioteca do Apache Commons Codec tem uma classe Hex para fazer exatamente esse tipo de trabalho.
fonte
import org.apache.commons.codec.*;
você poderia fazerimport org.apache.commons.codec.binary.Hex;
org.bouncycastle.util.encoders.Hex
String toHexString(byte[] data)
O método
javax.xml.bind.DatatypeConverter.printHexBinary()
, parte da Arquitetura Java para Ligação XML (JAXB) , era uma maneira conveniente de converter abyte[]
em uma sequência hexadecimal. ADatatypeConverter
classe também incluiu muitos outros métodos úteis de manipulação de dados.No Java 8 e versões anteriores, o JAXB fazia parte da biblioteca padrão do Java. Foi preterido no Java 9 e removido com o Java 11 , como parte de um esforço para mover todos os pacotes Java EE para suas próprias bibliotecas. É uma longa história . Agora,
javax.xml.bind
não existe, e se você deseja usar o JAXB, que contémDatatypeConverter
, precisará instalar a API JAXB e o JAXB Runtime do Maven.Exemplo de uso:
Vai resultar em:
Esta resposta é a mesma que esta .
fonte
Solução mais simples, sem bibliotecas externas, sem constantes de dígitos:
fonte
Uma solução Goiaba, para ser completo:
Agora
hex
é"48656c6c6f20776f726c64"
.fonte
new HashCode(bytes).toString()
.HashCode.fromBytes(checksum).toString()
Este oneliner simples funciona para mim.
String result = new BigInteger(1, inputBytes).toString(16);
EDIT - Usar isso removerá os zeros à esquerda, mas ele trabalhou no meu caso de uso. Obrigado @Voicu por apontar
fonte
Aqui estão algumas opções comuns ordenadas de simples (one-liner) a complexas (enorme biblioteca). Se você está interessado em desempenho, consulte os micro benchmarks abaixo.
Opção 1: snippet de código - Simples
Uma solução muito simples é usar a
BigInteger
representação hexadecimal da:Observe que, como ele lida com números que não sejam seqüências de bytes arbitrárias , ele omitirá zeros à esquerda - isso pode ou não ser o que você deseja (por exemplo,
000AE3
vs0AE3
para uma entrada de 3 bytes). Isso também é muito lento, cerca de 100x mais lento em comparação com a próxima opção.Opção 2: snippet de código - avançado
Aqui está um trecho de código completo, com cópia e colável que suporta maiúsculas / minúsculas e endianness . Ele é otimizado para minimizar a complexidade da memória e maximizar o desempenho e deve ser compatível com todas as versões modernas do Java (5+).
O código fonte completo com licença e decodificador Apache v2 pode ser encontrado aqui .
Opção 3: Usando uma pequena biblioteca otimizada: bytes-java
Enquanto trabalhava no meu projeto anterior, criei este pequeno kit de ferramentas para trabalhar com bytes em Java. Não possui dependências externas e é compatível com Java 7+. Inclui, entre outros, um HEX en / decodificador muito rápido e bem testado:
Você pode conferir no Github: bytes-java .
Opção 4: Apache Commons Codec
Claro que existem os bons codecs comuns . ( avisando a opinião adiante ) Enquanto trabalhava no projeto descrito acima, analisei o código e fiquei bastante decepcionado; muitos códigos desorganizados duplicados, codecs obsoletos e exóticos provavelmente só são úteis para muito poucas implementações lentas e bem projetadas e de engenharia de codecs populares (especificamente Base64). Portanto, eu tomaria uma decisão informada se você quiser usá-lo ou como alternativa. De qualquer forma, se você ainda quiser usá-lo, aqui está um trecho de código:
Opção 5: Google Guava
Mais frequentemente, você já tem o Goiaba como uma dependência. Se sim, basta usar:
Opção 6: Spring Security
Se você usar a estrutura do Spring com o Spring Security, poderá usar o seguinte:
Opção 7: Castelo Inflável
Se você já usa a estrutura de segurança Bouncy Castle, pode usar seu
Hex
utilitário:Opção Realmente Não 8: Compatibilidade com Java 9+ ou 'Não use JAXBs javax / xml / bind / DatatypeConverter'
Nas versões anteriores do Java (8 e abaixo), o código Java para JAXB foi incluído como dependência de tempo de execução. Desde a modularização do Java 9 e do Jigsaw, seu código não pode acessar outro código fora do módulo sem declaração explícita. Esteja ciente de que você recebe uma exceção como:
ao executar em uma JVM com Java 9+. Nesse caso, mude as implementações para qualquer uma das alternativas acima. Veja também esta questão .
Micro Benchmarks
Aqui estão os resultados de um simples micro benchmark JMH que codifica matrizes de bytes de tamanhos diferentes . Os valores são operações por segundo, portanto, quanto maior, melhor. Observe que os micro benchmarks muitas vezes não representam o comportamento do mundo real, portanto, leve esses resultados com um pouco de sal.
Especificações: JDK 8u202, i7-7700K, Win10, 24 GB de RAM. Veja a referência completa aqui .
fonte
Use a classe DataTypeConverter
javax.xml.bind.DataTypeConverter
String hexString = DatatypeConverter.printHexBinary(bytes[] raw);
fonte
Eu usaria algo assim para comprimento fixo, como hashes:
fonte
Encontrei três maneiras diferentes aqui: http://www.rgagnon.com/javadetails/java-0596.html
O mais elegante, como ele também observa, acho que é este:
fonte
if (raw == null) return null
não falha rápido. Por que você usaria umanull
chave?Com o menor custo de armazenamento da tabela de pesquisa, essa implementação é simples e muito rápida.
fonte
BYTE2HEX
matriz com umfor
ciclo simples ?static { }
bloco.Que tal agora?
fonte
Não precisamos usar nenhuma biblioteca externa ou escrever código com base em loops e constantes.
Basta isso:
fonte
Eu prefiro usar isso:
É uma adaptação um pouco mais flexível da resposta aceita. Pessoalmente, mantenho a resposta aceita e essa sobrecarga, utilizáveis em mais contextos.
fonte
Normalmente, uso o seguinte método para a declaração debuf, mas não sei se é a melhor maneira de fazê-lo ou não
fonte
StringBuilder buf = new StringBuilder(data.length * 2);
.Ok, então existem várias maneiras de fazer isso, mas se você decidir usar uma biblioteca, sugiro bisbilhotar no seu projeto para ver se algo foi implementado em uma biblioteca que já faz parte do seu projeto antes de adicionar uma nova biblioteca. apenas para fazer isso. Por exemplo, se você ainda não possui
talvez você tenha ...
fonte
Se você estiver usando a estrutura Spring Security, poderá usar:
fonte
Adicionar uma jarra de utilidade para uma função simples não é uma boa opção. Em vez disso, monte suas próprias classes de utilitários. é possível uma implementação mais rápida.
fonte
Uma pequena variante da solução proposta por @maybewecouldstealavan, que permite agrupar visualmente N bytes na sequência hexadecimal de saída:
Isso é:
fonte
Não é possível encontrar nesta solução nenhuma solução que não
Aqui está uma solução que não possui as falhas acima (nenhuma promessa é minha, mas não tem outras falhas)
Não consegui obter isso em 62 opcodes, mas se você puder viver sem preenchimento de 0, caso o primeiro byte seja menor que 0x10, a solução a seguir usará apenas 23 opcodes. Realmente mostra como soluções "fáceis de implementar" como "pad com zero se o comprimento da string for ímpar" podem ficar bem caras se uma implementação nativa ainda não estiver disponível (ou, neste caso, se o BigInteger tivesse a opção de prefixar zeros em para sequenciar).
fonte
Minha solução é baseada na solução de maybeWeCouldStealAVan, mas não depende de nenhuma tabela de pesquisa adicionalmente alocada. Ele não usa nenhuma ferramenta de conversão de 'int-to-char' (na verdade
Character.forDigit()
, executa algumas comparações para verificar qual é realmente o dígito) e, portanto, pode ser um pouco mais lenta. Por favor, sinta-se livre para usá-lo onde quiser. Felicidades.fonte
// Mudar bytes é mais eficiente // Você também pode usar este
fonte
Se você está procurando uma matriz de bytes exatamente como esta para python, eu converti essa implementação Java em python.
fonte
fonte
Aqui está uma
java.util.Base64
implementação do tipo (parcial), não é bonita?fonte
fonte
fonte