একটি বাইট অ্যারেকে জাভাতে এবং এর বিপরীতে পূর্ণসংখ্যায় রূপান্তর করুন


139

আমি জাভাতে বাইট অ্যারেতে কিছু ডেটা সঞ্চয় করতে চাই। মূলত কেবল সংখ্যা যা প্রতি সংখ্যা 2 বাইট পর্যন্ত নিতে পারে।

আমি জানতে চাই যে কীভাবে আমি একটি পূর্ণসংখ্যা 2 বাইট লম্বা বাইট অ্যারে এবং বিপরীতে রূপান্তর করতে পারি। আমি প্রচুর সমাধান googling পেয়েছি কিন্তু তাদের বেশিরভাগ কোডে কী ঘটে তা ব্যাখ্যা করে না। এমন অনেকগুলি স্থানান্তর রয়েছে যা আমি সত্যিই বুঝতে পারি না তাই আমি একটি মৌলিক ব্যাখ্যাটির প্রশংসা করব।


4
কত না আপনি একটু নাড়াচাড়া সম্পর্কে বুঝতে পেরেছ? দেখে মনে হচ্ছে প্রশ্নটি বাইট অ্যারেতে রূপান্তরকরণের চেয়ে "বিট শিফটিং কী করে" আসলে - আপনি যদি বাস্তবে বুঝতে চান যে রূপান্তরটি কীভাবে কাজ করবে।
জন স্কিটি

1
(জাস্ট নির্মল, আমি হয় প্রশ্নের সঙ্গে ভালো আছি, কিন্তু এটা স্পষ্ট এটা মূল্য যা প্রশ্ন আপনি কি সত্যিই কোন উত্তর চাই উত্তর যা তোমাদের কাছে যে ভাবে আরো উপযোগী পেতে করার সম্ভাবনা বেশি করছি।।)
জন স্কিট

ঠিক আছে আমি আপনার পয়েন্ট পেয়েছি! মন্তব্যের জন্য ধন্যবাদ। আমি জানি কি বিট শিফটিং আমি বাইট অ্যারে রূপান্তর করতে এর জন্য কী ব্যবহৃত তা কেবল বুঝতে পারি নি।
ক্রিস

3
@ প্রেপেগেজো এবং জেফ মার্কাডো আপনার দুটি উত্তরের জন্য ধন্যবাদ। প্রেকাগেও কীভাবে এটি করা যায় তার একটি ভাল ব্যাখ্যা দিয়েছিল, দুর্দান্ত লিঙ্ক! এটি আমার কাছে এটি আরও পরিষ্কার করে তোলে। এবং জেফ মার্কাডোস সমাধান আমার সমস্যাটি সমাধান করেছে।
ক্রিস

উত্তর:


230

java.nioনেমস্পেসে পাওয়া ক্লাসগুলি , বিশেষত, ব্যবহার করুন ByteBuffer। এটি আপনার জন্য সমস্ত কাজ করতে পারে।

byte[] arr = { 0x00, 0x01 };
ByteBuffer wrapped = ByteBuffer.wrap(arr); // big-endian by default
short num = wrapped.getShort(); // 1

ByteBuffer dbuf = ByteBuffer.allocate(2);
dbuf.putShort(num);
byte[] bytes = dbuf.array(); // { 0, 1 }

2
বাইট অ্যারেতে কেবল 1 বা 2 পূর্ণসংখ্যা থাকলে এটি খুব ব্যয়বহুল? একটি নির্মাণের ব্যয় সম্পর্কে নিশ্চিত নয় ByteBuffer
মেও বিড়াল 2012

2-4 বাইট খণ্ডে আপনি বাইনারি ডেটা নিয়ে কতবার কাজ করছেন? সত্যি? একটি বুদ্ধিমান বাস্তবায়ন হয় এটির সাথে বুউএসআইজেড খণ্ডগুলিতে (সাধারণত 4 কেবি) কাজ করবে বা অন্যান্য আইও লাইব্রেরি ব্যবহার করবে যা এই বিবরণটি গোপন করে। কাঠামোর মধ্যে একটি সম্পূর্ণ লাইব্রেরি রয়েছে যা আপনাকে ডেটা বাফারগুলিতে কাজ করতে সহায়তা করার জন্য উত্সর্গীকৃত। আপনি কোনও কারণ ছাড়াই সাধারণ ক্রিয়াকলাপগুলি বাস্তবায়িত করার সময় আপনি নিজের এবং আপনার কোডের অন্যান্য রক্ষণাবেক্ষণকারীদের প্রতি বিরক্তি প্রকাশ করেন (তা পারফেক্ট বা অন্য কোনও গুরুত্বপূর্ণ সমালোচনা)। এই বাফারগুলি কেবল রেপে যা অ্যারেতে চালিত হয়, এর চেয়ে বেশি কিছুই নয়।
জেফ

আপনি কীভাবে একটি বিমূর্ত ক্লাস ইনস্ট্যান্ট করতে পারেন?

1
@ জাভিনিসিপিপিএমসি গোয়ান এই উত্তরে সরাসরি কোনও ইনস্ট্যান্টেশন নেই। আপনি যদি কারখানার পদ্ধতিগুলি বোঝাতে চান wrapএবং allocate, তারা বিমূর্ত শ্রেণীর উদাহরণ ফেরৎ দেয় না ByteBuffer
মার্কো টপলনিক

3 বাইট স্ট্রাইডের জন্য কোনও সমাধান নয়। আমরা পেতে পারেন Char, Short, Int। আমি মনে করি আমি 4 বাইটে প্যাড করতে পারি এবং প্রতিবার 4 তম ছাড়তে পারি তবে আমি তা না করে চাই।
জন

128
byte[] toByteArray(int value) {
     return  ByteBuffer.allocate(4).putInt(value).array();
}

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

int fromByteArray(byte[] bytes) {
     return ByteBuffer.wrap(bytes).getInt();
}
// packing an array of 4 bytes to an int, big endian, minimal parentheses
// operator precedence: <<, &, | 
// when operators of equal precedence (here bitwise OR) appear in the same expression, they are evaluated from left to right
int fromByteArray(byte[] bytes) {
     return bytes[0] << 24 | (bytes[1] & 0xFF) << 16 | (bytes[2] & 0xFF) << 8 | (bytes[3] & 0xFF);
}

// packing an array of 4 bytes to an int, big endian, clean code
int fromByteArray(byte[] bytes) {
     return ((bytes[0] & 0xFF) << 24) | 
            ((bytes[1] & 0xFF) << 16) | 
            ((bytes[2] & 0xFF) << 8 ) | 
            ((bytes[3] & 0xFF) << 0 );
}

স্বাক্ষরিত বাইটগুলিকে কোনও ইনটে প্যাকিং করার সময়, প্রতিটি বাইটকে মুখোশ দেওয়া দরকার কারণ পাটিগণিত প্রচারের নিয়মের (জেএলএস, রূপান্তর এবং প্রচারে বর্ণিত) কারণে এটি 32 বিট (শূন্য-প্রসারিতের পরিবর্তে) থেকে সাইন-প্রসারিত হয়।

জোশুয়া ব্লাচ এবং নীল গিটোয়ারের জাভা পাজলারের ("বিগ ডিলাইট ইন প্রতিটি বাইট") এ সম্পর্কিত একটি আকর্ষণীয় ধাঁধা আছে। কোনও বাইট মানকে কোন মানের সাথে তুলনা করার সময়, বাইটটি একটি প্রান্তে সাইন-প্রসারিত হয় এবং তারপরে এই মানটিকে অন্য মানের সাথে তুলনা করা হয়

byte[] bytes = (…)
if (bytes[0] == 0xFF) {
   // dead code, bytes[0] is in the range [-128,127] and thus never equal to 255
}

নোট করুন যে সমস্ত সংখ্যার প্রকারভেদ 16-বিট স্বাক্ষরবিহীন পূর্ণসংখ্যার প্রকারের বাদে জাভাতে স্বাক্ষরিত।


আমি মনে করি & 0xFFএসগুলি অপ্রয়োজনীয়।
ওরি পপোভস্কি

11
@ লিফেরিক্সন, আমি বিশ্বাস করি যে & 0xFFএটি প্রয়োজনীয়, কারণ এটি জেভিএমকে স্বাক্ষরিত বাইটকে কেবলমাত্র সেই বিট সেট দিয়ে পূর্ণসংখ্যায় রূপান্তর করতে বলে। অন্যথায় বাইট -1 (0xFF) ইন -1 (0xFFFFFFFF) এ পরিণত হবে। আমি ভুল হতে পারি এবং আমি হলেও তা ক্ষতি করে না এবং বিষয়গুলি আরও পরিষ্কার করে দেয়।
কোডারফোরাফুলি

4
& 0xFF আসলেই বাধ্যতামূলক। byte b = 0; b |= 0x88; System.out.println(Integer.toString(b, 16)); //Output: -78 System.out.println(Integer.toString(b & 0xFF, 16)); //Output: 88
এইচবিএন

1
পুনঃটুইট আপনি করণ আগে & ক্রিয়াকলাপের byte0xFF (সঙ্গে int), জেভিএম নিক্ষেপ করা হবে byteথেকে intসঙ্গে 1 বাড়ানো বা 0 বর্ধিত বিট প্রথম নেতৃস্থানীয় অনুযায়ী। জাভাতে কোনও স্বাক্ষরবিহীন বাইট নেই , byteগুলি সর্বদা স্বাক্ষরিত হয়।
নাইয়ার

2
যখন বাইট এরে, বাইট অ্যারের আকার বেতন মনোযোগ থেকে পার্স int- এ, যদি 4 বাইট চেয়ে অনেক বেশী, এর ডক অনুযায়ী ByteBuffer.getInt(): Reads the next four bytes at this buffer's current position, কেবলমাত্র প্রথম 4 বাইট বিশ্লেষণ করা হবে, আপনারা কী চান করা উচিত হবে না পারে।
বিন

56

পরিবর্তনশীল দৈর্ঘ্যের বাইটগুলির জন্য আপনি বিগইন্টিজারও ব্যবহার করতে পারেন। আপনি এটি আপনার প্রয়োজন অনুসারে দীর্ঘ, অন্তর্ বা সংক্ষিপ্ত রূপান্তর করতে পারেন your

new BigInteger(bytes).intValue();

বা পোলারিটি বোঝাতে:

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

বাইটগুলি ফিরে পেতে:

new BigInteger(bytes).toByteArray()

1
দ্রষ্টব্য যে ১.৮ থেকে, এটি intValueExactনয়intValue
অভিজিৎ সরকার ২

5

একটি প্রাথমিক বাস্তবায়ন এই জাতীয় কিছু হবে:

public class Test {
    public static void main(String[] args) {
        int[] input = new int[] { 0x1234, 0x5678, 0x9abc };
        byte[] output = new byte[input.length * 2];

        for (int i = 0, j = 0; i < input.length; i++, j+=2) {
            output[j] = (byte)(input[i] & 0xff);
            output[j+1] = (byte)((input[i] >> 8) & 0xff);
        }

        for (int i = 0; i < output.length; i++)
            System.out.format("%02x\n",output[i]);
    }
}

জিনিসগুলি বোঝার জন্য আপনি এই ডাব্লুপি নিবন্ধটি পড়তে পারেন: http://en.wikedia.org/wiki/Endianness

উপরের উত্স কোড আউটপুট হবে 34 12 78 56 bc 9a। প্রথম 2 বাইট ( 34 12) প্রথম পূর্ণসংখ্যা ইত্যাদি উপস্থাপন করে etc. উপরের উত্স কোডটি সামান্য এন্ডিয়ান ফর্ম্যাটে পূর্ণসংখ্যাকে এনকোড করে।


2
/** length should be less than 4 (for int) **/
public long byteToInt(byte[] bytes, int length) {
        int val = 0;
        if(length>4) throw new RuntimeException("Too big to fit in int");
        for (int i = 0; i < length; i++) {
            val=val<<8;
            val=val|(bytes[i] & 0xFF);
        }
        return val;
    }

0

বিট থেকে পড়তে হবে এমন প্রয়োজনের সাথে কারও কথা বলতে দেয়, আপনাকে কেবল ৩ টি বিট থেকে পড়তে হবে তবে আপনার স্বাক্ষরিত পূর্ণসংখ্যার দরকার পরে নিম্নলিখিতটি ব্যবহার করুন:

data is of type: java.util.BitSet

new BigInteger(data.toByteArray).intValue() << 32 - 3 >> 32 - 3

আপনি ব্যবহার করছেন বিট3 সংখ্যা (বাইট নয়) দিয়ে ম্যাজিক নম্বরটি প্রতিস্থাপন করা যেতে পারে ।


0

হিসাবে প্রায়ই, পেয়ারা আপনার যা প্রয়োজন তা থাকে।

বাইট অ্যারে থেকে int Ints.fromBytesArray:, ডক এখানে যান

ইনট থেকে বাইট অ্যারে যেতে Ints.toByteArray:, ডক এখানে


-7

আমি মনে করি এটি আন্তঃ কাস্ট করার জন্য সেরা মোড

   public int ByteToint(Byte B){
        String comb;
        int out=0;
        comb=B+"";
        salida= Integer.parseInt(comb);
        out=out+128;
        return out;
    }

প্রথমে স্ট্রিং এ বায়োভার্ট করুন

comb=B+"";

পরের ধাপটি একটি int এ রূপান্তরিত হয়

out= Integer.parseInt(comb);

তবে এই রিসোনটির জন্য বাইট -128 থেকে 127 এর ক্রোধে রয়েছে, আমি মনে করি 0 থেকে 255 পর্যন্ত রেগ ব্যবহার করা ভাল এবং আপনার কেবল এটি করতে হবে:

out=out+256;

এটা ভুল. বাইট 0x01 বিবেচনা করুন। আপনার পদ্ধতিটি 129 আউটপুট দেবে যা ভুল। 0x01 এর পূর্ণসংখ্যা আউটপুট করা উচিত 1 আপনি পার্সইন্ট থেকে প্রাপ্ত পূর্ণসংখ্যাটি নেতিবাচক হলেই আপনার 128 যোগ করা উচিত।
ডিস্ক্লোসার

আমি বোঝাতে চাইছি আপনি 126 নয় 256 যোগ করুন after পরে এটি সম্পাদনা করতে পারেনি।
ডিস্ক্লোসার

256 যোগ করার জন্য পোস্টটি অন্যের পক্ষে উপকারী হতে পারে!
apmartin1991

এটি প্রচুর কাস্টিং করে এবং নতুন অবজেক্ট তৈরি করে (লুপগুলির জন্য এটি করার চিন্তা করুন) যা কার্যকারিতা হ্রাস করতে পারে, দয়া করে সংখ্যাকে পার্স করার বিষয়ে ইঙ্গিতের জন্য দয়া করে Integer.toString () পদ্ধতিটি পরীক্ষা করুন।
মার্কোস ভাসকনস্লোস

এছাড়াও, স্ট্যাকওভারফ্লোতে কোড পোস্ট করার সময় পয়েন্টটি এমন কোড পোস্ট করা হয় যা সহজে বোঝায়। যে কোডটি সহজেই বোঝায় সেগুলির অবশ্যই বোধগম্য শনাক্তকারী থাকতে হবে। আর Stackoverflow উপর, বোধগম্য অগত্যা মানে ইংরেজিতে
মাইক নাকিস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.