জাভা কোড বাইটকে হেক্সাডেসিমালে রূপান্তর করতে


184

আমার কাছে বাইটের একটি অ্যারে আছে আমি চাই যে সেই অ্যারের প্রতিটি বাইট স্ট্রিং এর সাথে সম্পর্কিত হেক্সাডেসিমাল মানগুলিতে রূপান্তরিত হোক।

জাভাতে কোনও বাইট অ্যারে হেক্সাডেসিমালে রূপান্তর করতে কোনও ফাংশন আছে কি?


2
আপনি জাভাতে বাইট-অ্যারে যাকে বলে তাকে অন্যান্য ভাষায় বাইট স্ট্রিং বলা হয় (যেমন ডকস.রেকেট-lang.org/guide/bytestrings.html )
প্যাট্রিক

উত্তর:


311
    byte[] bytes = {-1, 0, 1, 2, 3 };
    StringBuilder sb = new StringBuilder();
    for (byte b : bytes) {
        sb.append(String.format("%02X ", b));
    }
    System.out.println(sb.toString());
    // prints "FF 00 01 02 03 "

আরো দেখুন

  • java.util.Formatter বাক্য গঠন
    • %[flags][width]conversion
      • পতাকা '0'- ফলাফলটি শূন্য প্যাডযুক্ত হবে
      • প্রস্থ 2
      • রূপান্তর 'X'- ফলাফল একটি হেক্সাডেসিমাল পূর্ণসংখ্যা, বড় হাতের আকারে ফর্ম্যাট করা হয়

প্রশ্নের লেখার দিকে তাকানো, এটিও সম্ভব যে অনুরোধটিই এটি:

    String[] arr = {"-1", "0", "10", "20" };
    for (int i = 0; i < arr.length; i++) {
        arr[i] = String.format("%02x", Byte.parseByte(arr[i]));
    }
    System.out.println(java.util.Arrays.toString(arr));
    // prints "[ff, 00, 0a, 14]"

বেশ কয়েকটি উত্তর এখানে ব্যবহার করে Integer.toHexString(int); এটি করণীয়, তবে কিছু সতর্কতার সাথে। যেহেতু প্যারামিটারটি একটি int, তাই byteআর্গুমেন্টে প্রসারিত আদিম রূপান্তর সম্পাদন করা হয় , যার মধ্যে সাইন এক্সটেনশন জড়িত।

    byte b = -1;
    System.out.println(Integer.toHexString(b));
    // prints "ffffffff"

byteজাভাতে স্বাক্ষরিত 8-বিটটি 32-বিট-এ সাইন-প্রসারিত int। কার্যকরভাবে এই সাইন এক্সটেনশানটিকে পূর্বাবস্থায় ফেলার জন্য, কেউ এটি byteদিয়ে মাস্ক করতে পারে 0xFF

    byte b = -1;
    System.out.println(Integer.toHexString(b & 0xFF));
    // prints "ff"

ব্যবহারের সাথে আর একটি সমস্যা toHexStringহ'ল এটি জিরো দিয়ে প্যাড করে না:

    byte b = 10;
    System.out.println(Integer.toHexString(b & 0xFF));
    // prints "a"

উভয় কারণ একত্রিত হওয়া উচিত String.formatসমাধানটিকে আরও বেশি পছন্দনীয় করে তুলতে ।

তথ্যসূত্র


@ বিবেক: "প্রচুর পরিমাণে মূল্য" কী? ইনপুট কি এবং আউটপুট কি?
বহুবিশ্লেষকারী

আমাকে আবার ব্যাখ্যা করতে দিন .. আমার কাছে একটি অ্যারেতে বাইট স্ট্রিংয়ের সংকলন রয়েছে। তবে আমাকে যা করতে হবে তা হ'ল প্রতিটি বাইটকে আলাদা করে বিশ্লেষণ করতে হবে .. সুতরাং, আমি পুরো অ্যারেতে কাজ করতে চাই না, তবে একক সময়ে স্বতন্ত্র বাইট স্ট্রিং, এটি সেই অ্যারের একটি উপাদান .. "শব্দটির কারণে বিভ্রান্তি দেখা দিয়েছে" অ্যারে "। এখন নীচের কোডে "বাইট বিভি = 10; স্ট্রিং হেক্সস্ট্রিং = ইন্টিজার. টোএক্সএক্স স্ট্রিং (বিভি);" সিএ 1 (বাইট রিকভারড: 68 হেক্স আউটপুট: 44) কেস: 2 (বাইট রিকভারড: -46 হেক্স আউটপুট: ffffffd2) ......... কেন আমি কিছু মূল্যবোধের জন্য এমন অপ্রত্যাশিত ফলাফল পাচ্ছি?
বিবেক

1
@ বিবেক: ব্যবহার সম্পর্কে আমার উত্তর পড়ুন toHexString। আপনি এটি দিয়ে মাস্ক করতে হবে & 0xFF, Integer.toHexString(-46 & 0xFF)হয় "d2"
বহুবিশ্লেষকারী

@ পলিজেলব্রিকেন্টস: অনেক অনেক ধন্যবাদ .. দেখে মনে হচ্ছে, শেষ অবধি কোডটি ঠিকঠাকভাবে কাজ করছে ..এখন হেক্সস্ট্রিং ফাংশনটি ব্যবহার করা কি নিরাপদ? অথবা, পদ্ধতির সাথে কিছুটা ফাঁকফোকর থাকতে পারে?
বিবেক

1
@ বিবেক: এটি "নিরাপদ", আপনাকে কেবল সতর্কতা অবলম্বন করতে হবে এবং নিশ্চিত করতে হবে যে আপনি প্রতিবারের byteসাথে মানটি মাস্ক করে রেখেছেন & 0xFFformatউপরে সমাধান এছাড়াও আপনি আসলে আর্গুমেন্ট হিসাবে ব্যবহার করছেন কি উপর নির্ভর করে মাস্কিং প্রয়োজন হতে পারে।
polygenelubricants

65

আমি পোস্ট করছি কারণ বিদ্যমান উত্তরগুলির মধ্যে কোনওটিই তাদের পদ্ধতির কেন কাজ করে তা ব্যাখ্যা করে না, যা আমি মনে করি এই সমস্যার জন্য সত্যই গুরুত্বপূর্ণ। কিছু ক্ষেত্রে, এটি প্রস্তাবিত সমাধানটিকে অহেতুক জটিল এবং সূক্ষ্ম দেখা দেয়। চিত্রিত করার জন্য আমি মোটামুটি সহজবোধ্য পদ্ধতির সরবরাহ করব তবে এটি কেন কাজ করে তা বোঝাতে আমি আরও কিছু বিশদ সরবরাহ করব ।

প্রথমে, আমরা কী করার চেষ্টা করছি? আমরা একটি বাইট মান (বা বাইটের একটি অ্যারে) একটি স্ট্রিংয়ে রূপান্তর করতে চাই যা ASCII তে একটি হেক্সাডেসিমাল মান উপস্থাপন করে। সুতরাং প্রথম ধাপটি হ'ল জাভাতে একটি বাইট হ'ল:

বাইট ডেটা টাইপ একটি 8-বিট স্বাক্ষরিত দুজনের পরিপূরক পূর্ণসংখ্যা । এটির সর্বনিম্ন মান -128 এবং সর্বাধিক 127 (সমেত) মান রয়েছে। বাইট ডেটা টাইপ বড় অ্যারেগুলিতে মেমরি সঞ্চয় করার জন্য দরকারী হতে পারে, যেখানে মেমরির সঞ্চয়টি আসলে গুরুত্বপূর্ণ। এগুলি ইন্টার্টের জায়গায় ব্যবহার করা যেতে পারে যেখানে তাদের সীমাগুলি আপনার কোড পরিষ্কার করতে সহায়তা করে; একটি ভেরিয়েবলের পরিসীমা সীমিত হ'ল এটি ডকুমেন্টেশনের ফর্ম হিসাবে পরিবেশন করতে পারে।

এটার মানে কি? কয়েকটি জিনিস: প্রথম এবং সর্বাগ্রে গুরুত্বপূর্ণ, এর অর্থ আমরা 8-বিট নিয়ে কাজ করছি । সুতরাং উদাহরণস্বরূপ আমরা সংখ্যাটি 0000 0010 হিসাবে লিখতে পারি। তবে এটি যেহেতু এটি দুটি এর পরিপূরক, আমরা এটির মতো একটি নেতিবাচক 2 লিখি: 1111 1110. এর অর্থ হ'ল হেক্সে রূপান্তর করা খুব সোজা for তা হল, আপনি কেবল প্রতিটি 4 বিট বিভাগকে সরাসরি হেক্সে রূপান্তর করেন। নোট করুন যে এই স্কিমে নেতিবাচক সংখ্যাগুলি বোঝার জন্য আপনাকে প্রথমে দুটিটির পরিপূরক বুঝতে হবে। আপনি যদি ইতিমধ্যে দুটির পরিপূরক না বুঝেন তবে আপনি এখানে একটি দুর্দান্ত ব্যাখ্যা পড়তে পারেন: http://www.cs.cornell.edu/~tomf/notes/cps104/twoscomp.html


দুইয়ের পরিপূরককে সাধারণভাবে হেক্সে রূপান্তর করা

একবার সংখ্যা দু'জনের পরিপূরক হয়ে গেলে এটিকে হেক্সে রূপান্তর করা মৃত সহজ। সাধারণভাবে, বাইনারি থেকে হেক্সে রূপান্তর করা খুব সোজা next

উদাহরণ

উদাহরণ 1: 2 থেকে হেক্সে রূপান্তর করুন।

1) প্রথমে 2 এর পরিপূরকগুলিতে 2 বাইনারি রূপান্তর করুন:

2 (base 10) = 0000 0010 (base 2)

2) এখন বাইনারি হেক্সে রূপান্তর করুন:

0000 = 0x0 in hex
0010 = 0x2 in hex

therefore 2 = 0000 0010 = 0x02. 

উদাহরণ 2: হেক্সে রূপান্তর -২ (দু'জনের পরিপূরক)।

1) প্রথমে 2 এর পরিপূরকগুলিতে বাইনারি -2 রূপান্তর করুন:

-2 (base 10) = 0000 0010 (direct conversion to binary) 
               1111 1101 (invert bits)
               1111 1110 (add 1)
therefore: -2 = 1111 1110 (in two's complement)

2) এখন হেক্সে রূপান্তর করুন:

1111 = 0xF in hex
1110 = 0xE in hex

therefore: -2 = 1111 1110 = 0xFE.


জাভা এ করছেন

এখন যেহেতু আমরা ধারণাটি কভার করেছি, আপনি আবিষ্কার করতে পারেন যে কিছু সাধারণ মাস্কিং এবং শিফটিংয়ের মাধ্যমে আমরা যা চাই তা অর্জন করতে পারি। মূল বিষয়টি বুঝতে হবে যে আপনি যে বাইটটি রূপান্তর করতে চাইছেন তা ইতিমধ্যে দু'জনের পরিপূরক। আপনি নিজেই এই রূপান্তর করবেন না। আমি মনে করি এটি এই বিষয়টি নিয়ে বিভ্রান্তির একটি প্রধান বিষয়। উদাহরণস্বরূপ অনুসরণ বাইট অ্যারে নিন:

byte[] bytes = new byte[]{-2,2};

আমরা কেবল তাদের উপরে ম্যাকুয়ালি হেক্সে রূপান্তর করেছি, কিন্তু জাভাতে কীভাবে আমরা এটি করতে পারি? এখানে কীভাবে:

পদক্ষেপ 1: আমাদের গণনা ধরে রাখতে একটি স্ট্রিংবফার তৈরি করুন।

StringBuffer buffer = new StringBuffer();

পদক্ষেপ 2: উচ্চতর অর্ডার বিটগুলি বিচ্ছিন্ন করুন, সেগুলি হেক্সে রূপান্তর করুন এবং সেগুলি বাফারে যুক্ত করুন

বাইনারি নম্বর 1111 1110 দেওয়া, আমরা প্রথমে উচ্চতর অর্ডার বিটগুলি সেগুলি 4 দ্বারা সরিয়ে, এবং তারপরে বাকী সংখ্যাটি শূন্য করে আলাদা করতে পারি। যৌক্তিকভাবে এটি সহজ, তবে, জাভাতে প্রয়োগকরণের বিবরণ (এবং অনেকগুলি ভাষা) সাইন এক্সটেনশনের কারণে একটি কুঁচকে পরিচয় করিয়ে দেয়। মূলত, আপনি যখন বাইট মানটি স্থানান্তর করেন, জাভা প্রথমে আপনার মানটিকে একটি পূর্ণসংখ্যায় রূপান্তর করে এবং তারপরে সাইন এক্সটেনশান সম্পাদন করে। সুতরাং আপনি 1111 1110 >> 4 0000 1111 হওয়ার প্রত্যাশা করবেন, বাস্তবে জাভাতে এটি দুটির পরিপূরক 0xFFFFFFF হিসাবে উপস্থাপিত হবে!

সুতরাং আমাদের উদাহরণ ফিরে:

1111 1110 >> 4 (shift right 4) = 1111 1111 1111 1111 1111 1111 1111 1111 (32 bit sign-extended number in two's complement)

এরপরে আমরা একটি মুখোশ দিয়ে বিটগুলি আলাদা করতে পারি:

1111 1111 1111 1111 1111 1111 1111 1111 & 0xF = 0000 0000 0000 0000 0000 0000 0000 1111
therefore: 1111 = 0xF in hex. 

জাভাতে আমরা এই সমস্ত কিছু এক শটে করতে পারি:

Character.forDigit((bytes[0] >> 4) & 0xF, 16);

ফরডিজিট ফাংশনটি কেবলমাত্র হেক্সাডেসিমাল সংখ্যা 0-এফের সেটটিতে আপনি যে নম্বরটি পাস করেছেন তা ম্যাপ করে।

পদক্ষেপ 3: পরবর্তী আমাদের নীচের অর্ডার বিট বিচ্ছিন্ন করা প্রয়োজন। আমরা যে বিটগুলি চাইছি তা ইতিমধ্যে সঠিক অবস্থানে রয়েছে, তাই আমরা কেবল তাদের মুখোশটি বের করতে পারি:

1111 1110 & 0xF = 0000 0000 0000 0000 0000 0000 0000 1110 (recall sign extension from before)
therefore: 1110 = 0xE in hex.  

পূর্বের মতো, জাভাতে আমরা এই সমস্ত কিছু এক শটে করতে পারি:

Character.forDigit((bytes[0] & 0xF), 16);

এগুলি একসাথে রেখে আমরা এটি লুপের জন্য এবং পুরো অ্যারে রূপান্তর করতে পারি:

for(int i=0; i < bytes.length; i++){
    buffer.append(Character.forDigit((bytes[i] >> 4) & 0xF, 16));
    buffer.append(Character.forDigit((bytes[i] & 0xF), 16));
}

আশা করি এই ব্যাখ্যাটি আপনারা তাদের জন্য বিষয়গুলিকে আরও স্পষ্ট করে তুলেছেন যে আপনি ইন্টারনেটে যে সমস্ত উদাহরণ পাবেন তার মধ্যে ঠিক কী ঘটছে তা ভাবছেন। আশা করি আমি কোনও গুরুতর ত্রুটি করিনি, তবে পরামর্শ এবং সংশোধনগুলি অত্যন্ত স্বাগত!


4
সর্বোত্তম উত্তর! হেক্স স্ট্রিং থেকে বাইটের Character.digit()(byte) ((Character.digit(str.charAt(0), 16) << 4) + Character.digit(str.charAt(1), 16))
সিমেট্রিক

21

দ্রুততম উপায় আমি এখনো এই কাজ করতে পেয়েছি নিম্নলিখিত হল:

private static final String    HEXES    = "0123456789ABCDEF";

static String getHex(byte[] raw) {
    final StringBuilder hex = new StringBuilder(2 * raw.length);
    for (final byte b : raw) {
        hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt((b & 0x0F)));
    }
    return hex.toString();
}

এটি তুলনায় x 50x দ্রুত String.format। আপনি যদি এটি পরীক্ষা করতে চান:

public class MyTest{
    private static final String    HEXES        = "0123456789ABCDEF";

    @Test
    public void test_get_hex() {
        byte[] raw = {
            (byte) 0xd0, (byte) 0x0b, (byte) 0x01, (byte) 0x2a, (byte) 0x63,
            (byte) 0x78, (byte) 0x01, (byte) 0x2e, (byte) 0xe3, (byte) 0x6c,
            (byte) 0xd2, (byte) 0xb0, (byte) 0x78, (byte) 0x51, (byte) 0x73,
            (byte) 0x34, (byte) 0xaf, (byte) 0xbb, (byte) 0xa0, (byte) 0x9f,
            (byte) 0xc3, (byte) 0xa9, (byte) 0x00, (byte) 0x1e, (byte) 0xd5,
            (byte) 0x4b, (byte) 0x89, (byte) 0xa3, (byte) 0x45, (byte) 0x35,
            (byte) 0xd6, (byte) 0x10,
        };

        int N = 77777;
        long t;

        {
            t = System.currentTimeMillis();
            for (int i = 0; i < N; i++) {
                final StringBuilder hex = new StringBuilder(2 * raw.length);
                for (final byte b : raw) {
                    hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt((b & 0x0F)));
                }
                hex.toString();
            }
            System.out.println(System.currentTimeMillis() - t); // 50
        }

        {
            t = System.currentTimeMillis();
            for (int i = 0; i < N; i++) {
                StringBuilder hex = new StringBuilder(2 * raw.length);
                for (byte b : raw) {
                    hex.append(String.format("%02X", b));
                }
                hex.toString();
            }
            System.out.println(System.currentTimeMillis() - t); // 2535
        }

    }
}

সম্পাদনা করুন : সবেমাত্র একটি লিল দ্রুত পেয়েছে এবং এটি একটি লাইনে ধারণ করে তবে জেআরই 9 এর সাথে সামঞ্জস্যপূর্ণ নয় your আপনার নিজের ঝুঁকিতে ব্যবহার করুন

import javax.xml.bind.DatatypeConverter;

DatatypeConverter.printHexBinary(raw);

2
ডেটাটাইপ কনভার্টর আর জাভা ৯ তে উপলভ্য নয় The বিপজ্জনক বিষয়টি কোডটি ব্যবহার করে জাভা ১.৮ বা তার আগের (জাভা 9 পূর্বের উত্সের সেটিংস সহ) সংকলন করবে তবে জাভা 9 এর অধীনে রানটাইম ব্যতিক্রম পাবে
স্টিফেন এম-অন স্ট্রাইক-

আমি দ্বিতীয় @ স্টেফেনএমস পয়েন্টটি: জেআর 9 এর সাথে এটি ব্যবহার করে ক্লাসনটফাউন্ড ব্যতিক্রমের সাথে ক্রাশ হবে
প্যাট্রিক

প্রকৃতপক্ষে printHexBinary jdk এর src.zip থেকে সোর্স কোড পদ্ধতিটি বের করা যায় যা প্রথম পদ্ধতির চেয়ে 1 বার দ্রুত বলে মনে হয়।
ফল

1
আপনি যদি স্টেক্স এবং চরআউট () এর পরিবর্তে HEXES ধ্রুবকটির জন্য চর অ্যারে নিয়ে কাজ করেন তবে আপনি 20% বেশি গতি অর্জন করবেন।
ডায়র্জিও

15

এইভাবে চেষ্টা করুন:

byte bv = 10;
String hexString = Integer.toHexString(bv);

অ্যারের সাথে ডিলিং (যদি আমি আপনাকে সঠিকভাবে বুঝতে পারি):

byte[] bytes = {9, 10, 11, 15, 16};
StringBuffer result = new StringBuffer();
for (byte b : bytes) {
    result.append(String.format("%02X ", b));
    result.append(" "); // delimiter
}
return result.toString();

যেমন polygenelubricants উল্লিখিত, String.format()সঠিক উত্তর তুলনা Integer.toHexString()(যেহেতু এটি একটি সঠিক উপায়ে নেতিবাচক সংখ্যা নিয়ে কাজ করে)।


2
এটি প্রসারিত সাইন ইন করবে, উদাহরণস্বরূপ -1
বহুবিশ্লেষকরা

বাইট বিভি = 10; স্ট্রিং হেক্সস্ট্রিং = Integer.toHexString (বিভি); এটি দৃ work়ভাবে কাজ করে বলে মনে হচ্ছে .. আমি এটিকে প্রতিটি উপাদানগুলিতে পৃথকভাবে প্রয়োগ করতে পারি .. অন্য কোড (অ্যারের সাথে ডিলিং) খুব বড় একটি মান দেয়। এর জন্য কি কারণকে ডাবলু করতে পারে?
বিবেক

@ ভিভেক, কারণ bvএটির ক্ষেত্রে একটি একক হেক্সাডেসিমাল চরিত্র ফিরে আসে । বাকি কোডগুলি হেক্সাডেসিমাল অক্ষরের একটি স্ট্রিং প্রদান করে । আমি ডিলিমেটার দিয়ে কোডটি পরিবর্তন করেছি যাতে আপনি এটি এখন বুঝতে পারেন understand
0x2D9A3

@Bar: আপনি এখনও ব্যবহার করতে পারেন Integer.toHexStringযদি আপনি মাস্ক byteসঙ্গে 0xFFপূর্বাবস্থা চিহ্ন এক্সটেনশন করা।
বহুবৃত্তীয় পদার্থগুলি

সিএ 1 (বাইট রেকর্ড: 68 হেক্স আউটপুট: 44) কেস: 2 (বাইট রিকভারড: -46 হেক্স আউটপুট:: ffffffd2) নেতিবাচক বাইট অ্যারের ক্ষেত্রে আমি অপ্রত্যাশিত আউটপুট মান পাচ্ছি ... কীভাবে এটি পরিচালনা করবেন?
বিবেক

13

সর্বোত্তম সমাধান হ'ল এই ব্যাডাস ওয়ান-লাইনার:

String hex=DatatypeConverter.printHexBinary(byte[] b);

এখানে উল্লিখিত হিসাবে


4
ডেটাটাইপ কনভার্টর আর জাভা ৯ তে উপলভ্য নয় The বিপজ্জনক বিষয়টি হল কোডটি এটি জাভা ১.৮ বা তার আগের (জাভা 9 পূর্বের উত্সের সেটিংস সহ)
সংকলিত হবে তবে

দুঃখ যখন আপনি এটি jdk9 এ না বলে থাকেন। new BigInteger(byteArray).toString(16)তখন যাওয়ার উপায় is এর সাথে পারফেক্ট সমস্যা আছে কি ??
প্রার্থনা করা

পারফ ইস্যু নাও হতে পারে, তবে এটি নেতৃস্থানীয় শূন্যগুলি মিস করবে (তারা বিগইন্টিজারের মতো সংখ্যার কাছে অর্থহীন)
ফ্রিসো

দেখে মনে হচ্ছে এটি এখনও জাভা 9 ডক্সে রয়েছে , তাই আমি যা বলতে পারি তা থেকে এটি এখনও ব্যবহার করা ঠিক আছে বলে মনে হচ্ছে
ব্র্যাড পার্কস

আমি মনে করি এখানে বর্ণিত হিসাবে এটি java9 এর জন্য ব্যবহার করা এখনও ঠিক আছে, তবে ভবিষ্যতে জাভা রিলিজগুলিতে সরানো হবে । আপনি এখনও এটি 2.3.0 সংস্করণ হিসাবে 'নতুন' স্ট্যান্ডেলোন জ্যাক্সবি মডিউল দিয়ে ব্যবহার করতে সক্ষম হবেন ।
লিনাক্স

11

আপনি যদি স্থির-প্রস্থের হেক্স উপস্থাপনা চান, 0Aতার পরিবর্তে A, যাতে আপনি নির্বিঘ্নে বাইটগুলি পুনরুদ্ধার করতে পারেন, চেষ্টা করুন format():

StringBuilder result = new StringBuilder();
for (byte bb : byteArray) {
    result.append(String.format("%02X", bb));
}
return result.toString();

11

byte[]হেক্স স্ট্রিংয়ে রূপান্তর করার একটি ছোট এবং সহজ উপায় BigInteger:

import java.math.BigInteger;

byte[] bytes = new byte[] {(byte)255, 10, 20, 30};
String hex = new BigInteger(1, bytes).toString(16);
System.out.println(hex); // ff0a141e

কিভাবে এটা কাজ করে?

বিল্ট-ইন সিস্টেম ক্লাস java.math.BigIntegerশ্রেণি ( java.math.BigInteger ) বাইনারি এবং হেক্স ডেটার সাথে সামঞ্জস্যপূর্ণ:

  • এর BigInteger(signum=1, byte[])দ্বারা একটি বড় পূর্ণসংখ্যা তৈরির জন্য একজন কনস্ট্রাক্টর রয়েছে byte[]( theণাত্মক বাইটগুলি সঠিকভাবে পরিচালনা করতে তার প্রথম পরামিতি signum= সেট করুন 1)
  • BigInteger.toString(16)বড় পূর্ণসংখ্যাটিকে হেক্স স্ট্রিংয়ে রূপান্তর করতে ব্যবহার করুন
  • একটি হেক্স নম্বর ব্যবহার বিশ্লেষণ করতে new BigInteger("ffa74b", 16)- নেতৃত্বের শূন্যটি সঠিকভাবে পরিচালনা করে না

আপনি যদি হেক্সের ফলাফলের শীর্ষস্থানীয় শূন্য পেতে চান তবে এর আকারটি পরীক্ষা করুন এবং প্রয়োজনে অনুপস্থিত শূন্য যুক্ত করুন:

if (hex.length() % 2 == 1)
    hex = "0" + hex;

মন্তব্য

new BigInteger(1, bytes)পরিবর্তে, ব্যবহার করুন , new BigInteger(bytes)কারণ জাভা " ডিজাইন দ্বারা ভাঙ্গা " এবং byteডেটা টাইপটি বাইট ধারণ করে না তবে স্বাক্ষরিত ক্ষুদ্র পূর্ণসংখ্যার [-128 ... 127]। যদি প্রথম বাইটটি নেতিবাচক হয় তবে BigIntegerধরে নেওয়া হয় যে আপনি একটি negativeণাত্মক বড় পূর্ণসংখ্যাটি পাস করেছেন। 1প্রথম প্যারামিটার হিসাবে পাস ( signum=1)।

হেক্স থেকেbyte[] ফিরে রূপান্তরটি জটিল: কখনও কখনও উত্পাদিত আউটপুটে একটি শীর্ষস্থানীয় শূন্য প্রবেশ করে এবং এটি এইভাবে পরিষ্কার করা উচিত:

byte[] bytes = new BigInteger("ffa74b", 16).toByteArray();
if (bytes[0] == 0) {
    byte[] newBytes = new byte[bytes.length - 1];
    System.arraycopy(bytes, 1, newBytes, 0, newBytes.length);
    bytes = newBytes;
}

সর্বশেষ নোটটি হ'ল যদি এর মধ্যে byte[]বেশ কয়েকটি নেতৃস্থানীয় শূন্য থাকে তবে তারা হারিয়ে যাবে।


1
যদি শীর্ষস্থানীয় বাইটের দশমিক মান 16 এর কম হয় তবে আপনি একটি বিজোড় সংখ্যক হেক্স অক্ষরের স্ট্রিংও পাবেন।
অ্যালেক্স জর্জনসন

8

আপনি যদি বাহ্যিক লাইব্রেরি ব্যবহার করে খুশি হন তবে org.apache.commons.codec.binary.Hexশ্রেণিতে একটি encodeHexপদ্ধতি রয়েছে যা গ্রহণ করে byte[]এবং একটি প্রদান করে char[]। এই পদ্ধতিগুলি বিন্যাস বিকল্পের চেয়ে অনেক বেশি দ্রুত এবং রূপান্তরটির বিশদটি আবদ্ধ করে। decodeHexবিপরীত রূপান্তর জন্য একটি পদ্ধতিও আসে ।


4
একটি আরও সহজ উপায় অন্তর্নির্মিত ফাংশন javax.xML.bind.DatatypeConverter / parseHexBinary এবং মুদ্রণহেক্সবাইনারি ব্যবহার করা। স্ট্যাকওভারফ্লো.com
অ্যালান থম্পসন

2
এই বিকল্পটিতে +1 করুন। হেক্সের একটি পদ্ধতি এনকোডহেক্সস্ট্রিংও রয়েছে, যা একটি বাইট নেয় [] এবং একটি স্ট্রিং প্রদান করে।
মিংজিয়াং শি

ভুলবেন না যে javaxনামস্থানটি সর্বদা উপলব্ধ থাকে না।
31'১১

7

আপনি বাউন্সি ক্যাসল সরবরাহকারী লাইব্রেরি থেকে পদ্ধতিটি ব্যবহার করতে পারেন :

org.bouncycastle.util.encoders.Hex.toHexString(byteArray);

বাউন্সি ক্যাসেল ক্রিপ্টো প্যাকেজটি ক্রিপ্টোগ্রাফিক অ্যালগরিদমের জাভা বাস্তবায়ন। এই জারে জেডিই 1.5 এবং জেডি কে 1.8 এর বাউন্সি ক্যাসল ক্রিপ্টোগ্রাফি এপিআইগুলির জন্য জেসিই সরবরাহকারী এবং লাইটওয়েট এপিআই রয়েছে।

মাভেন নির্ভরতা:

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.60</version>
</dependency>

বা অ্যাপাচি কমন্স কোডেক থেকে :

org.apache.commons.codec.binary.Hex.encodeHexString(byteArray);

অ্যাপাচি কমন্স কোডেক প্যাকেজে সাধারণ এনকোডার এবং বিভিন্ন ফরম্যাটের যেমন ডেস্ক 64 এবং হেক্সাডেসিমালের ডিকোডার রয়েছে। এই ব্যাপকভাবে ব্যবহৃত এনকোডার এবং ডিকোডার ছাড়াও কোডেক প্যাকেজ ফোনেটিক এনকোডিং ইউটিলিটিগুলির সংগ্রহও বজায় রাখে।

মাভেন নির্ভরতা:

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.11</version>
</dependency>

হ্যাঁ, এটি সর্বোত্তম সমাধান তবে এর জন্য একটি বাহ্যিক গ্রন্থাগার দরকার: অ্যাপাচি কমন্স কোডেক ( এমভিএনরেপোসিটরি.com / artifact / commons-codec/commons- codec/ 1.11 ) বা বাউন্সিস্টেল সরবরাহকারী ( mvnrepository.com/artifact/org.bouncycastle/bcprov- jdk15on / 1.60 )
স্বেটলিন নাকভ 25'19

5

এটি এখন পর্যন্ত দ্রুততম চালানোর জন্য কোডটি পেয়েছি। আমি এটি 23 মিমিতে 3290 দৈর্ঘ্যের বেটে অ্যারে চালিয়েছি। আমি এটি একটি ভিএম-তে চালাচ্ছিলাম সুতরাং এটি সম্ভবত খালি ধাতব উপর দ্রুত চালানো হবে।

public static final char[] HEX_DIGITS =         {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

public static char[] encodeHex( final byte[] data ){
    final int l = data.length;
    final char[] out = new char[l<<1];
    for( int i=0,j=0; i<l; i++ ){
        out[j++] = HEX_DIGITS[(0xF0 & data[i]) >>> 4];
        out[j++] = HEX_DIGITS[0x0F & data[i]];
    }
    return out;
}

তাহলে আপনি ঠিক করতে পারেন

String s = new String( encodeHex(myByteArray) );

3
BigInteger n = new BigInteger(byteArray);
String hexa = n.toString(16));

কাজ করে না: BigInteger(byteArrayOf(-1, 2, 3, 4, 5)).toString(16)রিটার্ন"-fdfcfbfb"
মার্টিন ভিসনি

এটি একটি সঠিক ফলাফল। আপনি বাইট '-1', '2' ... '5' দিয়ে কাজ করছেন। বাইটগুলির কোনও ভিজ্যুয়ালাইজেশন ( ইউনিকোড.org ) নেই যদি আপনি ইচ্ছা করেন যে আক্ষরিক '-1', '2' ... '5' দিয়ে কাজ করা উচিত আপনার স্ট্রিংয়ের মানগুলি নিয়ে কাজ করা উচিত।
Wender

এটি ভুল ফলাফল। জাভা বাইট -1 এর মান 0xFF (এটি একইরকম (int) 255) যেহেতু জাভা বাইটগুলি স্বাক্ষরিত, তাই ফলাফলটি হওয়া উচিত FF02030405। যদি আপনি উপরে জেরিনা সমাধান সমাধান চেষ্টা করেন তবে দেখতে পাবেন এটি সঠিক আউটপুট প্রিন্ট করবে। নীচে স্ব্বেলিন নাকভের সমাধানটি দেখুন।
মার্টিন ভিসনি

2

বাইটকে হেক্সাডেসিমালে রূপান্তর করার জন্য এখানে একটি সাধারণ ফাংশন

   private static String convertToHex(byte[] data) {
    StringBuffer buf = new StringBuffer();
    for (int i = 0; i < data.length; i++) {
        int halfbyte = (data[i] >>> 4) & 0x0F;
        int two_halfs = 0;
        do {
            if ((0 <= halfbyte) && (halfbyte <= 9))
                buf.append((char) ('0' + halfbyte));
            else
                buf.append((char) ('a' + (halfbyte - 10)));
            halfbyte = data[i] & 0x0F;
        } while(two_halfs++ < 1);
    }
    return buf.toString();
}

2

অন্যরা সাধারণ মামলার বিষয়টি জানিয়েছেন। তবে আপনার যদি কোনও পরিচিত ফর্মের বাইট অ্যারে থাকে, উদাহরণস্বরূপ কোনও ম্যাক ঠিকানা থাকে তবে আপনি এটি করতে পারেন:

byte[] mac = { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 };

String str = String.format("%02X:%02X:%02X:%02X:%02X:%02X",
                           mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 

1

Stringকর্মক্ষমতা যদি কোনও সমস্যা হয়ে থাকে তবে একগুচ্ছ উদাহরণ তৈরি করা (এবং ধ্বংস করা) ভাল উপায় নয়।

দয়া করে বিবৃতি ( ifগুলি) যাচাই করে সেই শব্দচক্র (নকল) আর্গুমেন্ট উপেক্ষা করুন । এটি (অন্য) শিক্ষামূলক উদ্দেশ্যে।

সম্পূর্ণ মভেন প্রকল্প: http://jinahya.googlecode.com/svn/trunk/com.googlecode.jinahya/hex-codec/

এনকোডিং ...

/**
 * Encodes a single nibble.
 *
 * @param decoded the nibble to encode.
 *
 * @return the encoded half octet.
 */
protected static int encodeHalf(final int decoded) {

    switch (decoded) {
        case 0x00:
        case 0x01:
        case 0x02:
        case 0x03:
        case 0x04:
        case 0x05:
        case 0x06:
        case 0x07:
        case 0x08:
        case 0x09:
            return decoded + 0x30; // 0x30('0') - 0x39('9')
        case 0x0A:
        case 0x0B:
        case 0x0C:
        case 0x0D:
        case 0x0E:
        case 0x0F:
            return decoded + 0x57; // 0x41('a') - 0x46('f')
        default:
            throw new IllegalArgumentException("illegal half: " + decoded);
    }
}


/**
 * Encodes a single octet into two nibbles.
 *
 * @param decoded the octet to encode.
 * @param encoded the array to which each encoded nibbles are written.
 * @param offset the offset in the array.
 */
protected static void encodeSingle(final int decoded, final byte[] encoded,
                                   final int offset) {

    if (encoded == null) {
        throw new IllegalArgumentException("null encoded");
    }

    if (encoded.length < 2) {
        // not required
        throw new IllegalArgumentException(
            "encoded.length(" + encoded.length + ") < 2");
    }

    if (offset < 0) {
        throw new IllegalArgumentException("offset(" + offset + ") < 0");
    }

    if (offset >= encoded.length - 1) {
        throw new IllegalArgumentException(
            "offset(" + offset + ") >= encoded.length(" + encoded.length
            + ") - 1");
    }

    encoded[offset] = (byte) encodeHalf((decoded >> 4) & 0x0F);
    encoded[offset + 1] = (byte) encodeHalf(decoded & 0x0F);
}


/**
 * Decodes given sequence of octets into a sequence of nibbles.
 *
 * @param decoded the octets to encode
 *
 * @return the encoded nibbles.
 */
protected static byte[] encodeMultiple(final byte[] decoded) {

    if (decoded == null) {
        throw new IllegalArgumentException("null decoded");
    }

    final byte[] encoded = new byte[decoded.length << 1];

    int offset = 0;
    for (int i = 0; i < decoded.length; i++) {
        encodeSingle(decoded[i], encoded, offset);
        offset += 2;
    }

    return encoded;
}


/**
 * Encodes given sequence of octets into a sequence of nibbles.
 *
 * @param decoded the octets to encode.
 *
 * @return the encoded nibbles.
 */
public byte[] encode(final byte[] decoded) {

    return encodeMultiple(decoded);
}

গঠনের কথা মাথায় রেখে ...

/**
 * Decodes a single nibble.
 *
 * @param encoded the nibble to decode.
 *
 * @return the decoded half octet.
 */
protected static int decodeHalf(final int encoded) {

    switch (encoded) {
        case 0x30: // '0'
        case 0x31: // '1'
        case 0x32: // '2'
        case 0x33: // '3'
        case 0x34: // '4'
        case 0x35: // '5'
        case 0x36: // '6'
        case 0x37: // '7'
        case 0x38: // '8'
        case 0x39: // '9'
            return encoded - 0x30;
        case 0x41: // 'A'
        case 0x42: // 'B'
        case 0x43: // 'C'
        case 0x44: // 'D'
        case 0x45: // 'E'
        case 0x46: // 'F'
            return encoded - 0x37;
        case 0x61: // 'a'
        case 0x62: // 'b'
        case 0x63: // 'c'
        case 0x64: // 'd'
        case 0x65: // 'e'
        case 0x66: // 'f'
            return encoded - 0x57;
        default:
            throw new IllegalArgumentException("illegal half: " + encoded);
    }
}


/**
 * Decodes two nibbles into a single octet.
 *
 * @param encoded the nibble array.
 * @param offset the offset in the array.
 *
 * @return decoded octet.
 */
protected static int decodeSingle(final byte[] encoded, final int offset) {

    if (encoded == null) {
        throw new IllegalArgumentException("null encoded");
    }

    if (encoded.length < 2) {
        // not required
        throw new IllegalArgumentException(
            "encoded.length(" + encoded.length + ") < 2");
    }

    if (offset < 0) {
        throw new IllegalArgumentException("offset(" + offset + ") < 0");
    }

    if (offset >= encoded.length - 1) {
        throw new IllegalArgumentException(
            "offset(" + offset + ") >= encoded.length(" + encoded.length
            + ") - 1");
    }

    return (decodeHalf(encoded[offset]) << 4)
           | decodeHalf(encoded[offset + 1]);
}


/**
 * Encodes given sequence of nibbles into a sequence of octets.
 *
 * @param encoded the nibbles to decode.
 *
 * @return the encoded octets.
 */
protected static byte[] decodeMultiple(final byte[] encoded) {

    if (encoded == null) {
        throw new IllegalArgumentException("null encoded");
    }

    if ((encoded.length & 0x01) == 0x01) {
        throw new IllegalArgumentException(
            "encoded.length(" + encoded.length + ") is not even");
    }

    final byte[] decoded = new byte[encoded.length >> 1];

    int offset = 0;
    for (int i = 0; i < decoded.length; i++) {
        decoded[i] = (byte) decodeSingle(encoded, offset);
        offset += 2;
    }

    return decoded;
}


/**
 * Decodes given sequence of nibbles into a sequence of octets.
 *
 * @param encoded the nibbles to decode.
 *
 * @return the decoded octets.
 */
public byte[] decode(final byte[] encoded) {

    return decodeMultiple(encoded);
}

1

এটি একটি খুব দ্রুত উপায়। কোন বাহ্যিক libaries প্রয়োজন।

final protected static char[] HEXARRAY = "0123456789abcdef".toCharArray();

    public static String encodeHexString( byte[] bytes ) {

        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = HEXARRAY[v >>> 4];
            hexChars[j * 2 + 1] = HEXARRAY[v & 0x0F];
        }
        return new String(hexChars);
    }

1

বাইট স্ট্রিং বলতে আপনি কী বুঝিয়েছেন তা আমি বুঝতে পারি না, তবে এখানে বাইট থেকে স্ট্রিং এবং তার বিপরীতে কিছু রূপান্তর রয়েছে অবশ্যই অফিশিয়াল ডকুমেন্টেশনে আরও অনেক কিছু রয়েছে

Integer intValue = 149;

সংশ্লিষ্ট বাইট মানটি হ'ল:

Byte byteValue = intValue.byteValue(); // this will convert the rightmost byte of the intValue to byte, because Byte is an 8 bit object and Integer is at least 16 bit, and it will give you a signed number in this case -107

একটি বাইট ভেরিয়েবল থেকে পূর্ণসংখ্যার মানটি ফিরে পান:

Integer anInt = byteValue.intValue(); // This will convert the byteValue variable to a signed Integer

বাইট এবং পূর্ণসংখ্যা থেকে হেক্স স্ট্রিংয়ে:
আমি এটি এইভাবে করি:

Integer anInt = 149
Byte aByte = anInt.byteValue();

String hexFromInt = "".format("0x%x", anInt); // This will output 0x95
String hexFromByte = "".format("0x%x", aByte); // This will output 0x95

একটি হেক্স স্ট্রিং বাইটের একটি অ্যারের রূপান্তর:
আমি জানি যতদূর কোন সহজ ফাংশন কিছু একটি অ্যারের ভিতরে সব উপাদান রূপান্তর করতে নেই Objectঅন্যের উপাদান Object, তাই আপনি এটি নিজের করতে হবে। আপনি নিম্নলিখিত ফাংশন ব্যবহার করতে পারেন:

বাইট [] থেকে স্ট্রিং পর্যন্ত:

    public static String byteArrayToHexString(byte[] byteArray){
        String hexString = "";

        for(int i = 0; i < byteArray.length; i++){
            String thisByte = "".format("%x", byteArray[i]);
            hexString += thisByte;
        }

        return hexString;
    }

এবং হেক্স স্ট্রিং থেকে বাইট পর্যন্ত []:

public static byte[] hexStringToByteArray(String hexString){
    byte[] bytes = new byte[hexString.length() / 2];

    for(int i = 0; i < hexString.length(); i += 2){
        String sub = hexString.substring(i, i + 2);
        Integer intVal = Integer.parseInt(sub, 16);
        bytes[i / 2] = intVal.byteValue();
        String hex = "".format("0x%x", bytes[i / 2]);
    }

    return bytes;
}  

এটি অনেক দেরি হয়ে গেছে তবে আমি আশা করি এটি অন্য কিছুকে সহায়তা করতে পারে;)


1

আপনার দ্রুত পদ্ধতিটি এখানে রয়েছে:

    private static final String[] hexes = new String[]{
        "00","01","02","03","04","05","06","07","08","09","0A","0B","0C","0D","0E","0F",
        "10","11","12","13","14","15","16","17","18","19","1A","1B","1C","1D","1E","1F",
        "20","21","22","23","24","25","26","27","28","29","2A","2B","2C","2D","2E","2F",
        "30","31","32","33","34","35","36","37","38","39","3A","3B","3C","3D","3E","3F",
        "40","41","42","43","44","45","46","47","48","49","4A","4B","4C","4D","4E","4F",
        "50","51","52","53","54","55","56","57","58","59","5A","5B","5C","5D","5E","5F",
        "60","61","62","63","64","65","66","67","68","69","6A","6B","6C","6D","6E","6F",
        "70","71","72","73","74","75","76","77","78","79","7A","7B","7C","7D","7E","7F",
        "80","81","82","83","84","85","86","87","88","89","8A","8B","8C","8D","8E","8F",
        "90","91","92","93","94","95","96","97","98","99","9A","9B","9C","9D","9E","9F",
        "A0","A1","A2","A3","A4","A5","A6","A7","A8","A9","AA","AB","AC","AD","AE","AF",
        "B0","B1","B2","B3","B4","B5","B6","B7","B8","B9","BA","BB","BC","BD","BE","BF",
        "C0","C1","C2","C3","C4","C5","C6","C7","C8","C9","CA","CB","CC","CD","CE","CF",
        "D0","D1","D2","D3","D4","D5","D6","D7","D8","D9","DA","DB","DC","DD","DE","DF",
        "E0","E1","E2","E3","E4","E5","E6","E7","E8","E9","EA","EB","EC","ED","EE","EF",
        "F0","F1","F2","F3","F4","F5","F6","F7","F8","F9","FA","FB","FC","FD","FE","FF"
    };

    public static String byteToHex(byte b) {
        return hexes[b&0xFF];
    }

1
কুরুচিপূর্ণ, তবে সম্ভবত খুব দক্ষ। :-)
সমৃদ্ধ এস

1

শুধু কিছু অন্যান্য উত্তর মতো আমি ব্যবহার সুপারিশ String.format()এবং BigInteger। তবে বাইট অ্যারেটিকে বিগ-এন্ডিয়ান বাইনারি উপস্থাপনার পরিবর্তে দুটি-এর পরিপূরক বাইনারি উপস্থাপনার পরিবর্তে (সম্ভাব্য হেক্স মানের পরিসীমাটির সাইনাম এবং অসম্পূর্ণ ব্যবহার সহ) বিগইন্টেগার (ইন্ট সাইনাম, বাইট [] প্রস্থ) ব্যবহার করুন , বিগইন্টেগার (বাইট [] ভাল ) না )

উদাহরণস্বরূপ, 8 টি দৈর্ঘ্যের বাইট অ্যারের জন্য:

String.format("%016X", new BigInteger(1,bytes))

সুবিধাদি:

  • নেতৃস্থানীয় শূন্য
  • কোন সাইনাম
  • কেবল অন্তর্নির্মিত কার্যাদি
  • কোডের কেবল একটি লাইন

অসুবিধা:

  • এটি করার আরও কার্যকর উপায় থাকতে পারে

উদাহরণ:

byte[] bytes = new byte[8];
Random r = new Random();
System.out.println("big-endian       | two's-complement");
System.out.println("-----------------|-----------------");
for (int i = 0; i < 10; i++) {
    r.nextBytes(bytes);
    System.out.print(String.format("%016X", new BigInteger(1,bytes)));
    System.out.print(" | ");
    System.out.print(String.format("%016X", new BigInteger(bytes)));
    System.out.println();
}

উদাহরণ আউটপুট:

big-endian       | two's-complement
-----------------|-----------------
3971B56BC7C80590 | 3971B56BC7C80590
64D3C133C86CCBDC | 64D3C133C86CCBDC
B232EFD5BC40FA61 | -4DCD102A43BF059F
CD350CC7DF7C9731 | -32CAF338208368CF
82CDC9ECC1BC8EED | -7D3236133E437113
F438C8C34911A7F5 | -BC7373CB6EE580B
5E99738BE6ACE798 | 5E99738BE6ACE798
A565FE5CE43AA8DD | -5A9A01A31BC55723
032EBA783D2E9A9F | 032EBA783D2E9A9F
8FDAA07263217ABA | -70255F8D9CDE8546

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.