Bir bayt dizisini sayısal değerine (Java) nasıl dönüştürebilirim?


91

8 baytlık bir dizim var ve onu karşılık gelen sayısal değerine dönüştürmek istiyorum.

Örneğin

byte[] by = new byte[8];  // the byte array is stored in 'by'

// CONVERSION OPERATION
// return the numeric value

Yukarıdaki dönüştürme işlemini gerçekleştirecek bir yöntem istiyorum.


4
"Sayısal değer" ile neyi kastediyorsunuz? Baytlar ikili olarak bir tamsayıyı mı (uzun) yoksa kayan nokta sayısını (çift) mı temsil ediyor? Bir sayının dize temsili mi? Veya başka bir temsil?
— starblue


NB: TacB0sS'nin bağlantısı aslında aradığım şeydi - hem ileriye hem de geriye dönüşüm.
— Jay Taylor

new BigInteger(by).longValue()
— user207421

Yanıtlar:


108

İlk baytın en az önemli bayt olduğunu varsayarsak:

long value = 0;
for (int i = 0; i < by.length; i++)
{
   value += ((long) by[i] & 0xffL) << (8 * i);
}

İlk bayt en önemli olanıdır, o zaman biraz farklıdır:

long value = 0;
for (int i = 0; i < by.length; i++)
{
   value = (value << 8) + (by[i] & 0xff);
}

8 bayttan fazlasına sahipseniz uzun BigInteger ile değiştirin .

Hatalarımın düzeltilmesi için Aaron Digulla'ya teşekkürler.


8
-1 bayt işaretli değerlerdir! Ve pow () 'yu shift (<<) ile değiştirin! "değer = (değer << 8) + ([i] ve 0xff tarafından)"
— Aaron Digulla

Kaydırma operatörü (<<) sağdan sola önceliğe sahip mi? Yukarıdaki kod nasıl çalışır? Benim için gayet iyi çalışıyor. Sadece çalıştığını bilmek istiyorum. Thanx peşin
— suraj

@Mnementh: Kaydırma operatörü (<<) sağdan sola önceliğe sahip mi? Yukarıdaki kod nasıl çalışır? Benim için gayet iyi çalışıyor. Sadece çalıştığını bilmek istiyorum. Thanx peşin
— suraj

5
Benim yaptığımla aynı sorunu yaşayan başka biri varsa, ilk örnekte [i] ile uzun bir sayıya çevrilmelidir, aksi takdirde yalnızca 2 ^ 32'den küçük değerler için çalışır. Yani,value += ((long)by[i] & 0xffL) << (8 * i);
— Luke

115

Birinin bir Bufferparçası olarak sağlanan 'ler kullanılabilirjava.nioDönüştürmeyi gerçekleştirmek için paketin bir .

Burada kaynak byte[]dizinin uzunluğu 8'dir, bu boyut bir longdeğere karşılık gelen boyuttur .

İlk olarak, byte[]dizi bir a dizisine sarılır ByteBufferve ardından değeri ByteBuffer.getLongelde etmek için yöntem çağrılır long:

ByteBuffer bb = ByteBuffer.wrap(new byte[] {0, 0, 0, 0, 0, 0, 0, 4});
long l = bb.getLong();

System.out.println(l);

Sonuç

4

ByteBuffer.getLongYorumlarda yönteme işaret ettiği için dfa'ya teşekkür etmek istiyorum .


Bu durumda uygulanabilir olmasa da, Bufferlerin güzelliği birden çok değere sahip bir diziye bakmakla birlikte gelir.

Örneğin, eğer bir 8 bayt dizisi vardı ve biz iki gibi kullanmak istedi int, biz sarabilirdiniz değerler byte[]bir in diziyi ByteBufferbir olarak görülüyor, IntBufferve değerleri elde IntBuffer.get:

ByteBuffer bb = ByteBuffer.wrap(new byte[] {0, 0, 0, 1, 0, 0, 0, 4});
IntBuffer ib = bb.asIntBuffer();
int i0 = ib.get(0);
int i1 = ib.get(1);

System.out.println(i0);
System.out.println(i1);

Sonuç:

1
4

Peki ya ByteBuffer.wrap (yeni bayt [] {0, 0, 0, 1, 0, 0, 0, 4}). getLong ()? bu yöntem sonraki 8 baytı okumalı ve bunları uzun bir
— dfa'ya

@dfa: Bunu belirttiğiniz için teşekkürler, kesinlikle işe yarıyor gibi görünüyor - yanıtı düzenleyeceğim. :)
— coobird

16

Bu 8 baytlık bir sayısal değerse, deneyebilirsiniz:

BigInteger n = new BigInteger(byteArray);

Bu bir UTF-8 karakter arabelleğiyse, deneyebilirsiniz:

BigInteger n = new BigInteger(new String(byteArray, "UTF-8"));

İlk kod parçacığından hemen sonra biterse veya dizeyi bir "sayısal değere" dönüştürmek için bazı kodlar içeriyorsa, bu yanıta oy verirdim. Olduğu gibi, cevabınızın ikinci yarısı sonuçsuz görünüyor.
— Laurence Gonsalves

Ben ilk etapta demek değil ne cevabımı değişti
— Vincent Robert


9

BigInteger'ı değişken uzunluklu baytlar için de kullanabilirsiniz. İhtiyaçlarınıza uygun olanı Uzun, Tamsayı veya Kısa olarak dönüştürebilirsiniz.

new BigInteger(bytes).intValue();

veya polariteyi belirtmek için:

new BigInteger(1, bytes).intValue();


1

Dizideki her hücre, işaretsiz tamsayı olarak değerlendirilir:

private int unsignedIntFromByteArray(byte[] bytes) {
int res = 0;
if (bytes == null)
    return res;


for (int i=0;i<bytes.length;i++){
    res = res | ((bytes[i] & 0xff) << i*8);
}
return res;
}

Sadece 0xFFL kullanmam gerektiğine dikkat edin, aksi takdirde int 0xFF'den long'a çevirme Long.toHexString (l) yazdırdığımda çok sayıda yanlış 1 bit setine sahipti.
— Luke

0xFFL kullanmanız gerekir, aksi takdirde imza uzantısı alırsınız.
— Gray

0
public static long byteArrayToLong(byte[] bytes) {
    return ((long) (bytes[0]) << 56)
            + (((long) bytes[1] & 0xFF) << 48)
            + ((long) (bytes[2] & 0xFF) << 40)
            + ((long) (bytes[3] & 0xFF) << 32)
            + ((long) (bytes[4] & 0xFF) << 24)
            + ((bytes[5] & 0xFF) << 16)
            + ((bytes[6] & 0xFF) << 8)
            + (bytes[7] & 0xFF);
}

bayt dizisini (uzun 8 bayt) uzunluğa dönüştür

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.