मैं जावा में बाइट सरणी कैसे शुरू करूं?


138

मुझे जावा में बाइट सरणी रूप में कुछ निरंतर मूल्यों (यूयूआईडी) को स्टोर करना है, और मैं सोच रहा हूं कि उन स्थिर सरणियों को शुरू करने का सबसे अच्छा तरीका क्या होगा। यह है कि मैं वर्तमान में यह कैसे कर रहा हूं, लेकिन मुझे लगता है कि एक बेहतर तरीका होना चाहिए।

private static final byte[] CDRIVES = new byte[] { (byte)0xe0, 0x4f, (byte)0xd0,
    0x20, (byte)0xea, 0x3a, 0x69, 0x10, (byte)0xa2, (byte)0xd8, 0x08, 0x00, 0x2b,
    0x30, 0x30, (byte)0x9d };
private static final byte[] CMYDOCS = new byte[] { (byte)0xba, (byte)0x8a, 0x0d,
    0x45, 0x25, (byte)0xad, (byte)0xd0, 0x11, (byte)0x98, (byte)0xa8, 0x08, 0x00,
    0x36, 0x1b, 0x11, 0x03 };
private static final byte[] IEFRAME = new byte[] { (byte)0x80, 0x53, 0x1c,
    (byte)0x87, (byte)0xa0, 0x42, 0x69, 0x10, (byte)0xa2, (byte)0xea, 0x08,
    0x00, 0x2b, 0x30, 0x30, (byte)0x9d };
...
and so on

क्या ऐसा कुछ है जिसका मैं उपयोग कर सकता हूं जो कम कुशल हो सकता है, लेकिन क्लीनर दिखेगा? उदाहरण के लिए:

private static final byte[] CDRIVES =
    new byte[] { "0xe04fd020ea3a6910a2d808002b30309d" };

जवाबों:


111

एक हेक्सा स्ट्रिंग को परिवर्तित करने वाले फ़ंक्शन का उपयोग करना byte[], आप कर सकते थे

byte[] CDRIVES = hexStringToByteArray("e04fd020ea3a6910a2d808002b30309d");

मेरा सुझाव है कि आप डेव एल द्वारा परिभाषित फ़ंक्शन को जावा का उपयोग करके हेक्स डंप के स्ट्रिंग प्रतिनिधित्व को बाइट सरणी में बदलें।

मैं इसे अधिकतम पठनीयता के लिए यहाँ सम्मिलित करता हूँ:

public static byte[] hexStringToByteArray(String s) {
    int len = s.length();
    byte[] data = new byte[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;
}

यदि आप CDRIVES staticऔर final, प्रदर्शन ड्रॉप अप्रासंगिक है।


78
byte[] myvar = "Any String you want".getBytes();

किसी भी चरित्र को प्रदान करने के लिए स्ट्रिंग शाब्दिक भाग निकले जा सकते हैं:

byte[] CDRIVES = "\u00e0\u004f\u00d0\u0020\u00ea\u003a\u0069\u0010\u00a2\u00d8\u0008\u0000\u002b\u0030\u0030\u009d".getBytes();

50
क्या पोस्टर द्वारा वांछित (बाइनरी) के बजाय स्ट्रिंग (एएससीआईआई) "0000"को चालू नहीं किया जाता है? {0x30,0x30,0x30,0x30}{0x00,0x00,0x00,0x00}
15

5
प्रश्न के शीर्षक को देखें। फिर इस उत्तर को देखें। अब आप ही बताइए, इसमें गलत क्या है? यह पोस्टर के विशेष मुद्दे को हल नहीं कर सकता है, लेकिन यह निश्चित रूप से मेरा हल है। मुझे एक स्ट्रिंग को बाइट सरणी में बदलने की ज़रूरत थी, जो कि एक छद्म आयामी जनरेटर के लिए एक बीज के रूप में उपयोग करने के लिए और यह एक आकर्षण की तरह काम करता था।
e18r

@ e18r यह बाइट्स उत्पन्न कर रहा है, हाँ, लेकिन आपको यह नहीं पता है कि इस चूक के बाद से डिफ़ॉल्ट चार्टसेट पर क्या है। कम से कम .getBytes (वांछितइन्कोडिंग) का उपयोग करें।
मात्रा

@petmez गूंगा सवाल: जावा में, ".getBytes (UTF_8)" जैसा कुछ है; (getBytes एक खाली स्ट्रिंग पर) एक सुरक्षित बात करने के लिए? क्या यह 'कानूनी' है? या मैं बस कर सकता हूं: = नई बाइट [0]; ?
रॉबर्ट अचमन

1
@RobertAchmann "" .getbytes ("UTF-8") को खाली सरणी वापस करनी चाहिए और पूरी तरह से कानूनी है।
जैजैपी

33

जावा 6 में, एक तरीका है जो आप चाहते हैं:

private static final byte[] CDRIVES = javax.xml.bind.DatatypeConverter.parseHexBinary("e04fd020ea3a6910a2d808002b30309d")

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

import com.google.common.io.BaseEncoding;
private static final byte[] CDRIVES = BaseEncoding.base16().lowerCase().decode("E04FD020ea3a6910a2d808002b30309d".toLowerCase());

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


अमरूद उदाहरण लिखित रूप में काफी काम नहीं करता है - base16().lowerCase().decode(...)यदि आपके पास कम हेक्स अंक हैं तो यह होना चाहिए । docs.guava-lbooks.googlecode.com/git/javadoc/com/google/…
पीटर

@PeterDeGlopper अच्छी खोज, मैंने उत्तर अपडेट किया है इसलिए कोड अब निचले और ऊपरी दोनों प्रकार के वर्णों के साथ तार को संभालता है।
stefan.schwetschke 7

1
javax.xml.bindजावा 9 में उदास रूप से हटा दिया गया था
randomdude999

7

आप बाइट सरणियों के बजाय, इन मूल्यों को संग्रहीत करने के लिए जावा यूयूआईडी वर्ग का उपयोग कर सकते हैं:

UUID

public UUID(long mostSigBits,
            long leastSigBits)

निर्दिष्ट डेटा का उपयोग करके एक नया UUID का निर्माण करता है। mostSigBits का उपयोग UUID के सबसे महत्वपूर्ण 64 बिट्स के लिए किया जाता है और सबसेSigBits UUID के सबसे कम महत्वपूर्ण 64 बिट्स बन जाते हैं।


2

जहाँ तक एक साफ प्रक्रिया का संबंध है आप ByteArrayOutputStream ऑब्जेक्ट का उपयोग कर सकते हैं ...

ByteArrayOutputStream bObj = new ByteArrayOutputStream();
bObj.reset();

// सभी मूल्यों का उपयोग करके एक-एक करके bObj लिखें

bObj.write(byte value)

// जब आप बाइट प्राप्त कर सकते हैं [] का उपयोग कर

CDRIVES = bObj.toByteArray();

// आप CMYDOCS और IEFRAME की समान प्रक्रिया दोहरा सकते हैं,

नोट यदि आपके पास वास्तव में छोटा सरणी है, तो यह एक कुशल समाधान नहीं है।


2

बिना पुस्तकालयों के साथ एक समाधान, गतिशील लंबाई लौटी, अहस्ताक्षरित पूर्णांक व्याख्या (दो के पूरक नहीं)

    public static byte[] numToBytes(int num){
    if(num == 0){
        return new byte[]{};
    }else if(num < 256){
        return new byte[]{ (byte)(num) };
    }else if(num < 65536){
        return new byte[]{ (byte)(num >>> 8),(byte)num };
    }else if(num < 16777216){
        return new byte[]{ (byte)(num >>> 16),(byte)(num >>> 8),(byte)num };
    }else{ // up to 2,147,483,647
        return new byte[]{ (byte)(num >>> 24),(byte)(num >>> 16),(byte)(num >>> 8),(byte)num };
    }
}

1

इस परिस्थिति में मेरा पसंदीदा विकल्प का उपयोग करना है org.apache.commons.codec.binary.Hexजिसमें Stringy हेक्स और बाइनरी के बीच कनवर्ट करने के लिए उपयोगी एपीआई हैं । उदाहरण के लिए:

  1. Hex.decodeHex(char[] data)DecoderExceptionयदि कोई सरणी में गैर-हेक्स वर्ण हैं, या यदि विषम संख्या में वर्ण हैं, तो फेंकता है ।

  2. Hex.encodeHex(byte[] data)ऊपर डिकोड विधि का समकक्ष है, और बाहर थूकता है char[]

  3. Hex.encodeHexString(byte[] data)जो एक byteसरणी से a में वापस परिवर्तित हो जाता है String

उपयोग: Hex.decodeHex("dd645a2564cbe648c8336d2be5eafaa6".toCharArray())


1

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

public static byte[] fromHexString(String src) {
    byte[] biBytes = new BigInteger("10" + src.replaceAll("\\s", ""), 16).toByteArray();
    return Arrays.copyOfRange(biBytes, 1, biBytes.length);
}

Denys Séguret और stefan.schwetschke के वेरिएंट के विपरीत, यह विभाजक प्रतीकों (रिक्त स्थान, टैब आदि) को इनपुट स्ट्रिंग में डालने की अनुमति देता है, जिससे यह अधिक पठनीय बन जाता है।

उपयोग का उदाहरण:

private static final byte[] CDRIVES
    = fromHexString("e0 4f d0 20 ea 3a 69 10 a2 d8 08 00 2b 30 30 9d");
private static final byte[] CMYDOCS
    = fromHexString("BA8A0D4525ADD01198A80800361B1103");
private static final byte[] IEFRAME
    = fromHexString("80531c87 a0426910 a2ea0800 2b30309d");

1

सबसे छोटा आंतरिक प्रकार है, जो संकलन समय पर हेक्स संख्या द्वारा आवंटित किया जा सकता है चार , के रूप में

private static final char[] CDRIVES_char = new char[] {0xe0, 0xf4, ...};

समतुल्य बाइट सरणी रखने के लिए, एक के रूप में रूपांतरणों को तैनात किया जा सकता है

public static byte[] charToByteArray(char[] x)
{
    final byte[] res = new byte[x.length];
    for (int i = 0; i < x.length; i++)
    {
        res[i] = (byte) x[i];
    }
    return res;
}

public static byte[][] charToByteArray(char[][] x)
{
    final byte[][] res = new byte[x.length][];
    for (int i = 0; i < x.length; i++)
    {
        res[i] = charToByteArray(x[i]);
    }
    return res;
}

-2
private static final int[] CDRIVES = new int[] {0xe0, 0xf4, ...};

और एक्सेस बाइट में कन्वर्ट होने के बाद।

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