पूर्णांक को बाइट सरणी (जावा) में बदलें


137

एक Integerमें बदलने के लिए एक तेज तरीका क्या है Byte Array?

जैसे 0xAABBCCDD => {AA, BB, CC, DD}


1
क्या इससे कोई फर्क नहीं पड़ता कि परिणामी बाइट सरणी क्या स्वरूप है? आप इसके साथ क्या करेंगे?
स्केफमैन

जवाबों:


237

बाइटबफ़र वर्ग पर एक नज़र ।

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();

बाइट क्रम सुनिश्चित की स्थापना कि result[0] == 0xAA, result[1] == 0xBB, result[2] == 0xCCऔर result[3] == 0xDD

या वैकल्पिक रूप से, आप इसे मैन्युअल रूप से कर सकते हैं:

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;
}

ByteBufferवर्ग हालांकि इस तरह के गंदे हाथों कार्यों के लिए डिजाइन किया गया था। वास्तव में निजी java.nio.Bitsइन सहायक विधियों को परिभाषित करता है जिनका उपयोग किया जाता है 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
यह अच्छी तरह से काम करेगा यदि बाइटबफ़र पहले से ही है ... अन्यथा ऐसा लगता है कि आवंटन को करने में अधिक समय लगेगा, केवल 4 की बाइट सरणी आवंटित करने और मैन्युअल रूप से शिफ्टिंग करने की तुलना में ... लेकिन हम शायद बात कर रहे हैं छोटे अंतर के बारे में।
जेसन एस

बाइटबफ़र उदाहरण को कैश किया जा सकता है; और आंतरिक रूप से यह निश्चित रूप से वैसे भी स्थानांतरण और मास्किंग के साथ लागू किया गया है।
ग्रेगरी पकोस

4
यह पूरी तरह से ठीक जवाब है। ध्यान दें कि बड़ा-एंडियन निर्दिष्ट डिफ़ॉल्ट है, और विधियां "चेनेबल" हैं, और स्थिति तर्क वैकल्पिक है, इसलिए यह सभी को कम कर देता है: बाइट [] परिणाम = बाइटबफ़र.लोकेट (4) .putInt (0xAABBCCDD) .array (। ); बेशक, अगर आप ऐसा बार-बार कर रहे हैं और सभी परिणामों को एक साथ जोड़ रहे हैं (जो कि इस तरह के काम करते समय आम है), तो एक ही बफर आवंटित करें और बार-बार putFoo () उसमें सभी चीजें डालें जिनकी आपको आवश्यकता है - जैसे ही आप जाते हैं, यह ऑफसेट का ट्रैक रखेगा। यह वास्तव में एक जबरदस्त उपयोगी वर्ग है।
केविन बोर्रिलियन

यह हस्ताक्षरित प्रकारों पर क्या लाता है?
ग्रेगरी पॉक्सोज

3
जो नहीं जानता। PutInt हमेशा 4 बाइट्स लिखेगा, कोई फर्क नहीं पड़ता कि इनपुट पूर्णांक क्या आकार है। यदि आप केवल 2 बाइट्स चाहते हैं, तो putShort आदि का उपयोग करें ...
bvdb

36

का उपयोग कर BigInteger:

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

का उपयोग कर 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();
}

का उपयोग कर ByteBuffer:

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

5
हालांकि बाइट ऑर्डर पर ध्यान दें
ग्रेगोरी पकोस

1
क्या ByteBuffer एक अहस्ताक्षरित int देता है?
अरुण जॉर्ज

@ पास्कल बाईट बफ़र का उपयोग करके मैंने बाइटबफ़र बी बी के साथ कोशिश की = बाइटबफ़र.आलोकेट (3); इसके लिए यह java.nio.BufferOverflowException दे रहा है, मुझे नहीं मिल रहा है कि यह 4 से कम मूल्य के लिए काम क्यों नहीं कर रहा है? क्या आप समझा सकते हैं?
संजय जैन

@SanjayJain आपको एक बफर अतिप्रवाह अपवाद मिलता है क्योंकि जावा में ints 32-बिट या 4 बाइट आकार में होते हैं, और इसलिए आपको अपने बाइटबफ़र में कम से कम 4 बाइट्स मेमोरी आवंटित करने की आवश्यकता होती है।
चौंकाने वाला

@GregoryPakosz बाइट ऑर्डर के बारे में सही है। उनका जवाब का उपयोग कर ByteBufferअधिक सहज ज्ञान युक्त है अगर आप की तुलना में 2 ^ 31 को पूर्णांक में अधिक से अधिक के साथ काम कर रहे हैं - 1.
ordonezalex

31

इस फ़ंक्शन का उपयोग करें यह मेरे लिए काम करता है

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

यह int को बाइट मान में अनुवादित करता है


यह भी उल्लेखनीय है कि यह अन्य उत्तरों की तुलना में सबसे महत्वपूर्ण बिट और अधिक कुशल की परवाह किए बिना काम करेगा। भी '>>' का उपयोग कर सकता है।
१०:२० पर algolicious

1
इस तरह का एक सीधा समाधान किसी भी पुस्तकालय पद्धति को कॉल करने की तुलना में निश्चित रूप से तेज है। कभी-कभी आपको बस लाइब्रेरी पद्धति कॉल के सभी अतिरिक्त ओवरहेड के बजाय कोड की कुछ पंक्तियों के साथ सीधे बिट्स के साथ फिडेल करना पड़ता है।
डेविड आर ट्रिबल

और यह भाषाओं के बीच अच्छी तरह से परिवर्तित होता है इसलिए बहु भाषा सॉफ्टवेयर विकास के लिए अच्छा है।
समन्वयक

15

यदि आप अमरूद पसंद करते हैं , तो आप इसके Intsवर्ग का उपयोग कर सकते हैं :


के लिए intbyte[], उपयोग toByteArray():

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

परिणाम है {0xAA, 0xBB, 0xCC, 0xDD}


इसका उल्टा है fromByteArray()या 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);

परिणाम है 0xAABBCCDD


8

आप उपयोग कर सकते हैं BigInteger:

इंटेगर से:

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

लौटाया गया सरणी आकार का है जो संख्या का प्रतिनिधित्व करने के लिए आवश्यक है, इसलिए यह आकार 1 का हो सकता है, उदाहरण के लिए 1 का प्रतिनिधित्व करने के लिए। हालाँकि, यदि कोई इंट पास है, तो आकार चार बाइट्स से अधिक नहीं हो सकता है।

स्ट्रिंग्स से:

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

हालांकि, आपको यह देखने की आवश्यकता होगी, यदि पहला बाइट अधिक है 0x7F(जैसा कि इस मामले में है), जहां BigInteger सरणी की शुरुआत में 0x00 बाइट सम्मिलित करेगा। सकारात्मक और नकारात्मक मूल्यों के बीच अंतर करने के लिए यह आवश्यक है।


धन्यवाद! लेकिन चूंकि यह BigInteger है, क्या चींटियाँ सही ढंग से घूमेंगी? वह पूर्णांक है जो Integer.MAX_VALUE से बाहर है, लेकिन फिर भी केवल 4 बाइट्स के साथ प्रतिनिधित्व किया जा सकता है?
बटरकप

1
यह निश्चित रूप से निष्पादित करने के लिए तेज़ नहीं है। ;)
पीटर लॉरी

यह एक अच्छा विकल्प नहीं है। इतना ही नहीं यह 0x00 बाइट जोड़ सकता है, यह भी अग्रणी शून्य पट्टी कर सकता है।
जेडजेड कोडर

1

सरल समाधान जो बाइटऑर्डर को ठीक से संभालता है:

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



1

इससे आपको मदद मिलेगी।

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

शिफ्ट भी कर सकते हैं -

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

यहां एक तरीका है जो काम को सही तरीके से करना चाहिए।

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

यह मेरा समाधान है:

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);
    }
}

इसके अलावा Stringy विधि:

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;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.