Tamsayıyı bayt dizisine dönüştürme (Java)


137

Bir dönüştürmek için hızlı yolu nedir Integerbir içine Byte Array?

Örneğin 0xAABBCCDD => {AA, BB, CC, DD}


1
Ortaya çıkan bayt dizisinin biçimi nedir? Onunla ne yapacaksın?
skaffman

Yanıtlar:


237

ByteBuffer sınıfına bir göz atın .

ByteBuffer b = ByteBuffer.allocate(4);
//b.order(ByteOrder.BIG_ENDIAN); // optional, the initial order of a byte buffer is always BIG_ENDIAN.
b.putInt(0xAABBCCDD);

byte[] result = b.array();

O bayt sırası sağlar ayarlanması result[0] == 0xAA, result[1] == 0xBB, result[2] == 0xCCve result[3] == 0xDD.

Alternatif olarak, manuel olarak da yapabilirsiniz:

byte[] toBytes(int i)
{
  byte[] result = new byte[4];

  result[0] = (byte) (i >> 24);
  result[1] = (byte) (i >> 16);
  result[2] = (byte) (i >> 8);
  result[3] = (byte) (i /*>> 0*/);

  return result;
}

ByteBufferSınıf olsa böyle kirli eller görevler için tasarlanmıştır. Aslında özel java.nio.Bits, aşağıdakiler tarafından kullanılan bu yardımcı yöntemleri tanımlar ByteBuffer.putInt():

private static byte int3(int x) { return (byte)(x >> 24); }
private static byte int2(int x) { return (byte)(x >> 16); }
private static byte int1(int x) { return (byte)(x >>  8); }
private static byte int0(int x) { return (byte)(x >>  0); }

3
bytebuffer zaten oradaysa bu işe yarayacaktır ... aksi takdirde, sadece 4 uzunluklu bir bayt dizisi tahsis etmek ve manuel olarak vites değiştirmek ... küçük farklar hakkında.
Jason S

ByteBuffer örneği önbelleğe alınabilir; ve dahili olarak, yine de kaydırma ve maskeleme ile uygulanır.
Gregory Pakosz

4
Bu gayet iyi bir cevap. Big-endian değerinin belirtilen varsayılan değer olduğunu ve yöntemlerin "zincirlenebilir" olduğunu ve konum bağımsız değişkeninin isteğe bağlı olduğunu unutmayın. ); Tabii ki, bunu tekrar tekrar yapıyorsanız ve tüm sonuçları bir araya getiriyorsanız (bu tür bir şey yaparken yaygındır), tek bir tampon tahsis edin ve ihtiyacınız olan tüm şeyleri tekrar tekrar putFoo () - gittikçe ofseti takip edecektir. Gerçekten çok faydalı bir sınıf.
Kevin Bourrillion

imzalı türler ne getiriyor?
Gregory Pakosz

3
Kim bilmiyor. PutInt, girdi tamsayısının boyutu ne olursa olsun her zaman 4 bayt yazacaktır. Sadece 2 bayt istiyorsanız, putShort vb.
Kullanın

36

Kullanma BigInteger:

private byte[] bigIntToByteArray( final int i ) {
    BigInteger bigInt = BigInteger.valueOf(i);      
    return bigInt.toByteArray();
}

Kullanma DataOutputStream:

private byte[] intToByteArray ( final int i ) throws IOException {      
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    DataOutputStream dos = new DataOutputStream(bos);
    dos.writeInt(i);
    dos.flush();
    return bos.toByteArray();
}

Kullanma ByteBuffer:

public byte[] intToBytes( final int i ) {
    ByteBuffer bb = ByteBuffer.allocate(4); 
    bb.putInt(i); 
    return bb.array();
}

5
bayt sırasına dikkat edin
Gregory Pakosz

1
ByteBuffer imzasız bir int veriyor mu?
Arun George

@Pascal ByteBuffer kullanarak ByteBuffer ile denedim bb = ByteBuffer.allocate (3); Bunun için java.nio.BufferOverflowException veriyor, neden 4'ten daha az değer için çalışmıyor? Açıklayabilir misin?
Sanjay Jain

@SanjayJain Java'daki ints 32 bit veya 4 bayt boyutunda olduğundan ve ByteBuffer'ınızda en az 4 bayt bellek ayırmanızı gerektirdiğinden bir arabellek taşması istisnası alırsınız.
şok edici

@GregoryPakosz bayt sırası konusunda haklı. ByteBufferEğer 2 ^ 31 - 1'den büyük bir int ile uğraşıyorsanız onun cevabı kullanmak daha sezgiseldir.
ordonezalex

31

benim için çalışan bu işlevi kullan

public byte[] toByteArray(int value) {
    return new byte[] {
            (byte)(value >> 24),
            (byte)(value >> 16),
            (byte)(value >> 8),
            (byte)value};
}

int değerini bayt değerine çevirir


Bunun, diğer cevaplara kıyasla en önemli bit ve daha verimli olmasına bakılmaksızın çalışacağı hiçbir şeye değmez. Ayrıca '>>' kullanabilirsiniz.
algolicious

1
Bunun gibi doğrudan bir çözüm kesinlikle herhangi bir kütüphane yöntemini çağırmaktan daha hızlıdır. Bazen, kütüphane yöntemi çağrılarının tüm ek yükü ile uğraşmak yerine, bitlerle doğrudan birkaç satır kodla uğraşmanız gerekir.
David R Tribble

Ve bu diller arasında iyi dönüşüm sağlar, bu nedenle çok dilli yazılım geliştirme için iyidir.
Koordinatör

15

İsterseniz Guava , onun kullanabilir Intssınıfını:


For intbyte[], kullanım toByteArray():

byte[] byteArray = Ints.toByteArray(0xAABBCCDD);

Sonuç {0xAA, 0xBB, 0xCC, 0xDD}.


Tersi fromByteArray()veya fromBytes():

int intValue = Ints.fromByteArray(new byte[]{(byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD});
int intValue = Ints.fromBytes((byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD);

Sonuç 0xAABBCCDD.


8

Şunları kullanabilirsiniz BigInteger:

Tamsayılardan:

byte[] array = BigInteger.valueOf(0xAABBCCDD).toByteArray();
System.out.println(Arrays.toString(array))
// --> {-86, -69, -52, -35 }

Döndürülen dizi, sayıyı temsil etmek için gereken boyuttadır, bu nedenle örneğin 1'i temsil etmek için 1 boyutunda olabilir. Ancak, int iletilirse, boyut dört bayttan fazla olamaz.

Dizelerden:

BigInteger v = new BigInteger("AABBCCDD", 16);
byte[] array = v.toByteArray();

Bununla birlikte, ilk bayt daha yüksekse 0x7F(bu durumda olduğu gibi), BigInteger'in dizinin başına 0x00 bayt ekleyeceğini gözlemlemeniz gerekir . Pozitif ve negatif değerleri ayırt etmek için buna ihtiyaç vardır.


Teşekkürler! Ama bu BigInteger olduğundan, ints doğru bir şekilde dolacak mı? Bu, Integer.MAX_VALUE dışında olan ancak yine de yalnızca 4 baytla temsil edilebilen tamsayılar mı?
Buttercup

1
Bunu yürütmek kesinlikle hızlı değil. ;)
Peter Lawrey

Bu iyi bir seçenek değil. Sadece 0x00 bayt ekleyemez, aynı zamanda baştaki sıfırları da silebilir.
ZZ Coder

1

ByteOrder'ı düzgün şekilde işleyen basit bir çözüm:

ByteBuffer.allocate(4).order(ByteOrder.nativeOrder()).putInt(yourInt).array();


1

android ile çok kolay

int i=10000;
byte b1=(byte)Color.alpha(i);
byte b2=(byte)Color.red(i);
byte b3=(byte)Color.green(i);
byte b4=(byte)Color.blue(i);

1

Bu sana yardım edecek.

import java.nio.ByteBuffer;
import java.util.Arrays;

public class MyClass
{
    public static void main(String args[]) {
        byte [] hbhbytes = ByteBuffer.allocate(4).putInt(16666666).array();

        System.out.println(Arrays.toString(hbhbytes));
    }
}

0

Ayrıca kayabilir -

byte[] ba = new byte[4];
int val = Integer.MAX_VALUE;

for(byte i=0;i<4;i++)
    ba[i] = (byte)(val >> i*8);
    //ba[3-i] = (byte)(val >> i*8); //Big-endian

0

İşte işi doğru yapması gereken bir yöntem.

public byte[] toByteArray(int value)
{
    final byte[] destination = new byte[Integer.BYTES];
    for(int index = Integer.BYTES - 1; index >= 0; index--)
    {
        destination[i] = (byte) value;
        value = value >> 8;
    };
    return destination;
};

0

Benim çözümüm:

public void getBytes(int val) {
    byte[] bytes = new byte[Integer.BYTES];
    for (int i = 0;i < bytes.length; i ++) {
        int j = val % Byte.MAX_VALUE;
        bytes[i] = (j == 0 ? Byte.MAX_VALUE : j);
    }
}

Ayrıca Stringy yöntemi:

public void getBytes(int val) {
    String hex = Integer.toHexString(val);
    byte[] val = new byte[hex.length()/2]; // because byte is 2 hex chars
    for (int i = 0; i < hex.length(); i+=2)
        val[i] = Byte.parseByte("0x" + hex.substring(i, i+2), 16);
    return val;
}
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.