Ben onaltılık sayılarla dolu bir bayt dizisi var ve birçok yazdırılamaz öğeleri olduğundan kolay yolu oldukça anlamsız baskı. Ne ihtiyacım tam hexcode şeklinde:3a5f771c
Ben onaltılık sayılarla dolu bir bayt dizisi var ve birçok yazdırılamaz öğeleri olduğundan kolay yolu oldukça anlamsız baskı. Ne ihtiyacım tam hexcode şeklinde:3a5f771c
Yanıtlar:
Buradaki tartışmadan ve özellikle bu cevaptan, şu anda kullandığım işlev budur:
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars);
}
Kendi küçük ölçütlerim (bir bin bayt, bin kez, 256 bayt, 10 milyon kez), diğer dizilerden çok daha hızlı olduğunu, uzun dizilerin yaklaşık yarısında olduğunu gösterdi. Aldığım cevaba kıyasla, tartışmada önerildiği gibi bitsel ops'a geçiş - uzun diziler için zamanın yaklaşık% 20'sini kesti. (Düzenle: Alternatiflerden daha hızlı olduğunu söylediğimde, tartışmalarda sunulan alternatif kodu kastediyorum. Performans, çok benzer kod kullanan Commons Codec'e eşdeğerdir.)
Java 9 kompakt dizeleriyle ilgili 2k20 sürümü:
private static final byte[] HEX_ARRAY = "0123456789ABCDEF".toByteArray();
public static String bytesToHex(byte[] bytes) {
byte[] hexChars = new byte[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars, StandardCharsets.UTF_8);
}
String printHexBinary(byte[])
ve byte[] parseHexBinary(String)
. printHexBinary
ancak, bu yanıttaki işlevden çok (2x) daha yavaştır. ; (Bir kullanır Kaynağını kontrol stringBuilder
. parseHexBinary
Gerçekten, olsa da, çoğu amaç için yeterince hızlı olduğunu ve muhtemelen zaten sahip bir dizi kullanır.).
printHexBinary
?
javax.xml.bind.DataTypeConverter
Java 11'den kaldırılıyor.
Apache Commons Codec kütüphanesi vardır Hex işin sadece bu tür yapmak için sınıf.
import org.apache.commons.codec.binary.Hex;
String foo = "I am a string";
byte[] bytes = foo.getBytes();
System.out.println( Hex.encodeHexString( bytes ) );
import org.apache.commons.codec.*;
bunu yapabilirsinimport org.apache.commons.codec.binary.Hex;
org.bouncycastle.util.encoders.Hex
bu yöntemle:String toHexString(byte[] data)
Yöntem javax.xml.bind.DatatypeConverter.printHexBinary()
, XML Bağlama için Java Mimarisi'nin (JAXB) bir parçası olan, byte[]
bir hex dizesine dönüştürmenin uygun bir yoluydu . DatatypeConverter
Sınıf bir çok başka yararlı veri manipülasyon yöntemlerini içermektedir.
Java 8 ve önceki sürümlerinde JAXB, Java standart kitaplığının bir parçasıydı. Bu edilmiş kaldırılmış Java 9 ile ve kaldırıldı Java 11 ile kendi kütüphanelerindeki içine tüm Java EE paketlerini taşımak için bir çabanın parçası olarak,. Uzun bir hikaye . Şimdi, javax.xml.bind
mevcut değil ve içeren JAXB'yi kullanmak istiyorsanız DatatypeConverter
, JAXB API'sını ve JAXB Çalışma Zamanı'nı yüklemeniz gerekir .
Örnek kullanım:
byte bytes[] = {(byte)0, (byte)0, (byte)134, (byte)0, (byte)61};
String hex = javax.xml.bind.DatatypeConverter.printHexBinary(bytes);
Sonuçlanacak:
000086003D
Bu cevap aynı bu bir .
En basit çözüm, harici kütük yok, basamak sabitleri yok:
public static String byteArrayToHex(byte[] a) {
StringBuilder sb = new StringBuilder(a.length * 2);
for(byte b: a)
sb.append(String.format("%02x", b));
return sb.toString();
}
Tamlık için bir Guava çözümü:
import com.google.common.io.BaseEncoding;
...
byte[] bytes = "Hello world".getBytes(StandardCharsets.UTF_8);
final String hex = BaseEncoding.base16().lowerCase().encode(bytes);
Şimdi hex
ise "48656c6c6f20776f726c64"
.
new HashCode(bytes).toString()
.
HashCode.fromBytes(checksum).toString()
Bu basit oneliner benim için çalışıyor
String result = new BigInteger(1, inputBytes).toString(16);
EDIT - Bunu kullanmak sıfırları kaldıracak, ama hey kullanım durumum için çalıştı. İşaret ettiğin için teşekkürler @Voicu
Basit (tek astarlı) ve karmaşık (büyük kütüphane) arasında sıralanan bazı yaygın seçenekler şunlardır. Performansla ilgileniyorsanız, aşağıdaki mikro kriterlere bakın.
Çok basit bir çözüm, BigInteger
'ın hex temsilini kullanmaktır:
new BigInteger(1, someByteArray).toString(16)
Bu, rasgele bayt dizeleri olmayan sayıları işlediğinden , baştaki sıfırları atlayacağına dikkat edin - bu, istediğiniz gibi olabilir veya olmayabilir (örneğin , 3 baytlık bir giriş için vs ). Bu da çok yavaş, yaklaşık 100x daha yavaş000AE3
0AE3
sonraki seçeneğe göre .
Burada, bir tam özellikli kopya edilir ve pasteable kodu destekleyen snippet'ine üst / küçük harf ve endianness'ın . Bellek karmaşıklığını en aza indirecek ve performansı en üst düzeye çıkaracak şekilde optimize edilmiştir ve tüm modern Java sürümleriyle (5+) uyumlu olmalıdır.
private static final char[] LOOKUP_TABLE_LOWER = new char[]{0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
private static final char[] LOOKUP_TABLE_UPPER = new char[]{0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46};
public static String encode(byte[] byteArray, boolean upperCase, ByteOrder byteOrder) {
// our output size will be exactly 2x byte-array length
final char[] buffer = new char[byteArray.length * 2];
// choose lower or uppercase lookup table
final char[] 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)];
}
return new String(buffer);
}
public static String encode(byte[] byteArray) {
return encode(byteArray, false, ByteOrder.BIG_ENDIAN);
}
Apache v2 lisansı ve kod çözücüye sahip tam kaynak kodu burada bulunabilir .
Önceki projem üzerinde çalışırken, Java'daki baytlarla çalışmak için bu küçük araç setini oluşturdum. Harici bir bağımlılığı yoktur ve Java 7+ ile uyumludur. Diğerlerinin yanı sıra çok hızlı ve iyi test edilmiş bir HEX en / dekoder içerir:
import at.favre.lib.bytes.Bytes;
...
Bytes.wrap(someByteArray).encodeHex()
Github'da kontrol edebilirsiniz : bytes-java .
Tabii ki iyi 'ol commons codec bileşenleri var . ( uyarı uyarısı ) Yukarıda özetlenen proje üzerinde çalışırken kodu analiz ettim ve oldukça hayal kırıklığına uğradım; bir çok yinelenmemiş örgütlenmemiş kod, eski ve egzotik kodekler muhtemelen popüler kodeklerin (özellikle Base64) çok az ve oldukça mühendis ve yavaş uygulamaları için yararlıdır. Bu nedenle, onu kullanmak ya da bir alternatif kullanmak istiyorsanız bilinçli bir karar verirdim. Her neyse, hala kullanmak istiyorsanız, bir kod snippet'i:
import org.apache.commons.codec.binary.Hex;
...
Hex.encodeHexString(someByteArray));
Çoğu zaman Guava'ya bağımlılık olarak sahip değilsiniz . Öyleyse sadece kullanın:
import com.google.common.io.BaseEncoding;
...
BaseEncoding.base16().lowerCase().encode(someByteArray);
Eğer kullanırsanız Bahar çerçeve ile Bahar Güvenlik aşağıdakileri kullanabilirsiniz:
import org.springframework.security.crypto.codec.Hex
...
new String(Hex.encode(someByteArray));
Zaten Bouncy Castle güvenlik çerçevesini kullanıyorsanız, onun Hex
util kullanabilirsiniz :
import org.bouncycastle.util.encoders.Hex;
...
Hex.toHexString(someByteArray);
Önceki Java (8 ve altı) sürümlerinde JAXB için Java kodu çalışma zamanı bağımlılığı olarak dahil edilmiştir. Java 9 ve Jigsaw modülerizasyonu nedeniyle , kodunuz açık bir bildirim olmadan modülünün dışındaki diğer koda erişemez. Bu nedenle, aşağıdaki gibi bir istisna alırsanız unutmayın:
java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
Java 9+ ile bir JVM üzerinde çalışırken. Öyleyse, uygulamaları yukarıdaki alternatiflerden herhangi birine geçirin. Ayrıca bu soruya bakın .
Farklı boyutlardaki bayt dizilerini kodlayan basit bir JMH mikro karşılaştırmalı değerlendirmesinin sonuçları . Değerler saniyedeki işlemlerdir, dolayısıyla daha yüksek daha iyidir. Mikro kriterlerin sıklıkla gerçek dünya davranışını temsil etmediğini unutmayın, bu nedenle bu sonuçları bir tuz tanesi ile alın.
| Name (ops/s) | 16 byte | 32 byte | 128 byte | 0.95 MB |
|----------------------|-----------:|-----------:|----------:|--------:|
| Opt1: BigInteger | 2,088,514 | 1,008,357 | 133,665 | 4 |
| Opt2/3: Bytes Lib | 20,423,170 | 16,049,841 | 6,685,522 | 825 |
| Opt4: Apache Commons | 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 |
Özellikler: JDK 8u202, i7-7700K, Win10, 24GB Ram. Tüm karşılaştırmalı değerlendirmeyi buradan görebilirsiniz .
DataTypeConverter sınıfını kullanmajavax.xml.bind.DataTypeConverter
String hexString = DatatypeConverter.printHexBinary(bytes[] raw);
Karma uzunluklar için böyle bir şey kullanırdım, karma gibi:
md5sum = String.format("%032x", new BigInteger(1, md.digest()));
Burada üç farklı yol buldum: http://www.rgagnon.com/javadetails/java-0596.html
En zarif olanı, ayrıca belirttiği gibi, bence bu:
static final String HEXES = "0123456789ABCDEF";
public static String getHex( byte [] raw ) {
if ( raw == null ) {
return null;
}
final StringBuilder hex = new StringBuilder( 2 * raw.length );
for ( final byte b : raw ) {
hex.append(HEXES.charAt((b & 0xF0) >> 4))
.append(HEXES.charAt((b & 0x0F)));
}
return hex.toString();
}
if (raw == null) return null
hızlı başarısız değil. Neden hiç null
anahtar kullanasýn ?
Arama tablosunu depolamanın küçük maliyetiyle bu uygulama basit ve çok hızlıdır.
private static final char[] BYTE2HEX=(
"000102030405060708090A0B0C0D0E0F"+
"101112131415161718191A1B1C1D1E1F"+
"202122232425262728292A2B2C2D2E2F"+
"303132333435363738393A3B3C3D3E3F"+
"404142434445464748494A4B4C4D4E4F"+
"505152535455565758595A5B5C5D5E5F"+
"606162636465666768696A6B6C6D6E6F"+
"707172737475767778797A7B7C7D7E7F"+
"808182838485868788898A8B8C8D8E8F"+
"909192939495969798999A9B9C9D9E9F"+
"A0A1A2A3A4A5A6A7A8A9AAABACADAEAF"+
"B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF"+
"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"+
"D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF"+
"E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF"+
"F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF").toCharArray();
;
public static String getHexString(byte[] bytes) {
final int len=bytes.length;
final char[] chars=new char[len<<1];
int hexIndex;
int idx=0;
int ofs=0;
while (ofs<len) {
hexIndex=(bytes[ofs++] & 0xFF)<<1;
chars[idx++]=BYTE2HEX[hexIndex++];
chars[idx++]=BYTE2HEX[hexIndex];
}
return new String(chars);
}
BYTE2HEX
Diziyi neden basit bir for
döngü ile başlatmıyorsunuz?
static { }
blok halinde atanabilir .
Buna ne dersin?
String byteToHex(final byte[] hash)
{
Formatter formatter = new Formatter();
for (byte b : hash)
{
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}
Bunu kullanmayı tercih ediyorum:
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes, int offset, int count) {
char[] hexChars = new char[count * 2];
for ( int j = 0; j < count; j++ ) {
int v = bytes[j+offset] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
Kabul edilen cevabın biraz daha esnek bir uyarlamasıdır. Şahsen, hem kabul edilen cevabı hem de bu aşırı yüklenmeyi daha fazla bağlamda kullanılabilir tutuyorum.
Genellikle debuf deyimi için aşağıdaki yöntemi kullanın, ancak bunu yapmanın en iyi yolu olup olmadığını bilmiyorum
private static String digits = "0123456789abcdef";
public static String toHex(byte[] data){
StringBuffer buf = new StringBuffer();
for (int i = 0; i != data.length; i++)
{
int v = data[i] & 0xff;
buf.append(digits.charAt(v >> 4));
buf.append(digits.charAt(v & 0xf));
}
return buf.toString();
}
StringBuilder buf = new StringBuilder(data.length * 2);
.
Tamam, bunu yapmanın bir sürü yolu var, ancak bir kütüphane kullanmaya karar verirseniz, yeni bir kütüphane eklemeden önce projenizin bir parçası olan bir kütüphaneye bir şey uygulanıp uygulanmadığını görmek için projenizde konuşmayı öneririm. sadece bunu yapmak için. Örneğin, henüz sahip değilseniz
org.apache.commons.codec.binary.Hex
belki sende var ...
org.apache.xerces.impl.dv.util.HexBin
Spring Security çerçevesini kullanıyorsanız şunları kullanabilirsiniz:
import org.springframework.security.crypto.codec.Hex
final String testString = "Test String";
final byte[] byteArray = testString.getBytes();
System.out.println(Hex.encode(byteArray));
Basit işlev için bir yarar kavanozu eklemek iyi bir seçenek değildir. Bunun yerine kendi yardımcı sınıflarınızı birleştirin. daha hızlı uygulama mümkündür.
public class ByteHex {
public static int hexToByte(char ch) {
if ('0' <= ch && ch <= '9') return ch - '0';
if ('A' <= ch && ch <= 'F') return ch - 'A' + 10;
if ('a' <= ch && ch <= 'f') return ch - 'a' + 10;
return -1;
}
private static final String[] byteToHexTable = new String[]
{
"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F",
"10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F",
"20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F",
"30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F",
"40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4A", "4B", "4C", "4D", "4E", "4F",
"50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F",
"60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B", "6C", "6D", "6E", "6F",
"70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E", "7F",
"80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F",
"90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F",
"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF",
"B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF",
"C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF",
"D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF",
"E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF",
"F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF"
};
private static final String[] byteToHexTableLowerCase = new String[]
{
"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f",
"10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f",
"20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f",
"30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f",
"40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4a", "4b", "4c", "4d", "4e", "4f",
"50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f",
"60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6a", "6b", "6c", "6d", "6e", "6f",
"70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c", "7d", "7e", "7f",
"80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f",
"90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b", "9c", "9d", "9e", "9f",
"a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af",
"b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf",
"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf",
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df",
"e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef",
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff"
};
public static String byteToHex(byte b){
return byteToHexTable[b & 0xFF];
}
public static String byteToHex(byte[] bytes){
if(bytes == null) return null;
StringBuilder sb = new StringBuilder(bytes.length*2);
for(byte b : bytes) sb.append(byteToHexTable[b & 0xFF]);
return sb.toString();
}
public static String byteToHex(short[] bytes){
StringBuilder sb = new StringBuilder(bytes.length*2);
for(short b : bytes) sb.append(byteToHexTable[((byte)b) & 0xFF]);
return sb.toString();
}
public static String byteToHexLowerCase(byte[] bytes){
StringBuilder sb = new StringBuilder(bytes.length*2);
for(byte b : bytes) sb.append(byteToHexTableLowerCase[b & 0xFF]);
return sb.toString();
}
public static byte[] hexToByte(String hexString) {
if(hexString == null) return null;
byte[] byteArray = new byte[hexString.length() / 2];
for (int i = 0; i < hexString.length(); i += 2) {
byteArray[i / 2] = (byte) (hexToByte(hexString.charAt(i)) * 16 + hexToByte(hexString.charAt(i+1)));
}
return byteArray;
}
public static byte hexPairToByte(char ch1, char ch2) {
return (byte) (hexToByte(ch1) * 16 + hexToByte(ch2));
}
}
@Maybewecouldstealavan tarafından önerilen, N baytlarını çıktı hex dizesinde görsel olarak bir araya getirmenize olanak tanıyan küçük bir çözüm çeşidi:
final static char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
final static char BUNDLE_SEP = ' ';
public static String bytesToHexString(byte[] bytes, int bundleSize /*[bytes]*/]) {
char[] hexChars = new char[(bytes.length * 2) + (bytes.length / bundleSize)];
for (int j = 0, k = 1; j < bytes.length; j++, k++) {
int v = bytes[j] & 0xFF;
int start = (j * 2) + j/bundleSize;
hexChars[start] = HEX_ARRAY[v >>> 4];
hexChars[start + 1] = HEX_ARRAY[v & 0x0F];
if ((k % bundleSize) == 0) {
hexChars[start + 2] = BUNDLE_SEP;
}
}
return new String(hexChars).trim();
}
Yani:
bytesToHexString("..DOOM..".toCharArray().getBytes(), 2);
2E2E 444F 4F4D 2E2E
bytesToHexString("..DOOM..".toCharArray().getBytes(), 4);
2E2E444F 4F4D2E2E
Bu sayfada bulunmayan bir çözüm bulunamıyor
İşte yukarıdaki kusurları olmayan bir çözüm (benimkinin başka kusurları olmadığına dair hiçbir söz yok)
import java.math.BigInteger;
import static java.lang.System.out;
public final class App2 {
// | proposed solution.
public static String encode(byte[] bytes) {
final int length = bytes.length;
// | BigInteger constructor throws if it is given an empty array.
if (length == 0) {
return "00";
}
final int evenLength = (int)(2 * Math.ceil(length / 2.0));
final String format = "%0" + evenLength + "x";
final String result = String.format (format, new BigInteger(bytes));
return result;
}
public static void main(String[] args) throws Exception {
// 00
out.println(encode(new byte[] {}));
// 01
out.println(encode(new byte[] {1}));
//203040
out.println(encode(new byte[] {0x20, 0x30, 0x40}));
// 416c6c20796f75722062617365206172652062656c6f6e6720746f2075732e
out.println(encode("All your base are belong to us.".getBytes()));
}
}
Bunu 62 opcode altında alamadım, ancak ilk baytın 0x10'dan küçük olması durumunda 0 dolgu olmadan yaşayabiliyorsanız, aşağıdaki çözüm sadece 23 opcodes kullanır. Gerçekten yerel bir uygulama mevcut değilse (veya bu durumda, BigInteger içinde sıfırlarla ön ek yapma seçeneği varsa, "kendiniz uygulamak kolay" gibi bir çözüm "dize uzunluğu tek ise sıfırla ped" oldukça pahalı olabilir gösterir. toString).
public static String encode(byte[] bytes) {
final int length = bytes.length;
// | BigInteger constructor throws if it is given an empty array.
if (length == 0) {
return "00";
}
return new BigInteger(bytes).toString(16);
}
Benim çözümüm belkiWeCouldStealAVan'ın çözümüne dayanır, ancak ek olarak ayrılmış arama tablolarına dayanmaz. 'Char-to-char' hileleri kullanmaz (aslında, Character.forDigit()
rakamın gerçekte ne olduğunu kontrol etmek için biraz karşılaştırma yapar) ve bu nedenle biraz daha yavaş olabilir. Lütfen istediğiniz yerde kullanmaktan çekinmeyin. Şerefe.
public static String bytesToHex(final byte[] bytes)
{
final int numBytes = bytes.length;
final char[] container = new char[numBytes * 2];
for (int i = 0; i < numBytes; i++)
{
final int b = bytes[i] & 0xFF;
container[i * 2] = Character.forDigit(b >>> 4, 0x10);
container[i * 2 + 1] = Character.forDigit(b & 0xF, 0x10);
}
return new String(container);
}
Python için tam olarak böyle bir bayt dizisi arıyorsanız, bu Java uygulamasını python'a dönüştürdüm.
class ByteArray:
@classmethod
def char(cls, args=[]):
cls.hexArray = "0123456789ABCDEF".encode('utf-16')
j = 0
length = (cls.hexArray)
if j < length:
v = j & 0xFF
hexChars = [None, None]
hexChars[j * 2] = str( cls.hexArray) + str(v)
hexChars[j * 2 + 1] = str(cls.hexArray) + str(v) + str(0x0F)
# Use if you want...
#hexChars.pop()
return str(hexChars)
array = ByteArray()
print array.char(args=[])
İşte benzer bir java.util.Base64
uygulama (kısmi), güzel değil mi?
public class Base16/*a.k.a. Hex*/ {
public static class Encoder{
private static char[] toLowerHex={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
private static char[] toUpperHex={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
private boolean upper;
public Encoder(boolean upper) {
this.upper=upper;
}
public String encode(byte[] data){
char[] value=new char[data.length*2];
char[] toHex=upper?toUpperHex:toLowerHex;
for(int i=0,j=0;i<data.length;i++){
int octet=data[i]&0xFF;
value[j++]=toHex[octet>>4];
value[j++]=toHex[octet&0xF];
}
return new String(value);
}
static final Encoder LOWER=new Encoder(false);
static final Encoder UPPER=new Encoder(true);
}
public static Encoder getEncoder(){
return Encoder.LOWER;
}
public static Encoder getUpperEncoder(){
return Encoder.UPPER;
}
//...
}
private static String bytesToHexString(byte[] bytes, int length) {
if (bytes == null || length == 0) return null;
StringBuilder ret = new StringBuilder(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();
}
Converts bytes data to hex characters
@param bytes byte array to be converted to hex string
@return byte String in hex format
private static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
int v;
for (int j = 0; j < bytes.length; j++) {
v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars);
}
toHexString(...)
aradığınız şey buysa yardımcı olabilecek bir yöntemi vardır. Ayrıca kod dizesiniString.format(...)
kullanarak bazı düzgün biçimlendirme hileleri yapabilirsiniz%2x
.