জাভাতে বাইট অ্যারে হেক্স স্ট্রিংয়ে কীভাবে রূপান্তর করবেন?


649

আমার কাছে একটি বাইট অ্যারে হেক্স নম্বর দিয়ে পূর্ণ এবং সহজেই মুদ্রণ করা বেশ অর্থহীন কারণ এখানে অনেকগুলি ছাপছাড়া উপাদান রয়েছে। আমার যা দরকার তা হ'ল হেক্সকোড আকারে:3a5f771c


12
কেন প্রথমে এটি চেষ্টা করে দেখবেন না এবং কী কী পেয়েছেন তা আমাদের দেখান। আপনার কাছে হারাতে হবে এবং অর্জন করার মতো কিছুই নেই। পূর্ণসংখ্যার একটি toHexString(...)পদ্ধতি রয়েছে যা এটি যদি আপনি সন্ধান করেন তবে তা সহায়তা করতে পারে। এছাড়াও String.format(...)কিছু ঝরঝরে ফর্ম্যাটিং ব্যবহার করে ঠাট কি করতে পারেন %2xকোড পংক্তি।
ইওলস


"আমার যা দরকার তা হ'ল হেক্সকোড আকারে: 3a5f771c ..." - আপনি একটি সঠিক ফর্ম চেয়েছিলেন, তবে আপনি একটি সঠিক উদাহরণ সরবরাহ করেন নি। আপনি যা সরবরাহ করেছেন তা চালিয়ে প্রথম চারটি বাইটকে স্ট্রিংয়ে রূপান্তর করুন , তারপরে উপবৃত্তগুলিকে স্ট্রিংয়ের সাথে যুক্ত করুন।
jww

1
জাভা 8-এ স্ট্রিমের সাহায্যে এটিকে কেবল এ হিসাবে প্রয়োগ করা যেতে পারে: স্ট্যাটিক স্ট্রিং বাইটআরাইটোহেক্স (বাইট [] ক) {রিটার্ন ইন্টারস্ট্রিম.রং ", এ [i])) .ড্রেস ((acc, v) -> acc +" "+ ভি) .টি (); }
তিব্বতি

উত্তর:


900

এখানে আলোচনা থেকে এবং বিশেষত এই উত্তরটি থেকে, আমি বর্তমানে এটি ব্যবহার করছি এটিই:

private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(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] = HEX_ARRAY[v >>> 4];
        hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
    }
    return new String(hexChars);
}

আমার নিজস্ব ক্ষুদ্রতর মানদণ্ড (এক মিলিয়ন বাইট এক হাজার বার, 256 বাইট 10 মিলিয়ন বার) এটিকে অন্য যে কোনও বিকল্পের চেয়ে দীর্ঘতর অ্যারেতে প্রায় অর্ধেক সময় দেখায়। আলোচনার প্রস্তাব অনুযায়ী --- বিটওয়াইস অপস-এ স্যুইচ করা উত্তরটি থেকে আমি যে উত্তরটি নিয়েছি তা তুলনায় --- দীর্ঘ অ্যারের জন্য প্রায় 20% সময় কেটে ফেলুন। (সম্পাদনা: আমি যখন বলি এটি বিকল্পগুলির চেয়ে দ্রুততর হয়, তখন আমি অর্থাত্ আলোচনায় প্রদত্ত বিকল্প কোডটি বোঝায় Per পারফরম্যান্স কমন্স কোডেকের সমতুল্য, যা খুব অনুরূপ কোড ব্যবহার করে))

জাভা 9 কমপ্যাক্ট স্ট্রিংগুলির সাথে সম্মতি সহ 2 কে ২০ সংস্করণ:

private static final byte[] HEX_ARRAY = "0123456789ABCDEF".toByteArray();
public static String bytesToHex(byte[] bytes) {
    byte[] hexChars = new byte[bytes.length * 2];
    for (int j = 0; j < bytes.length; j++) {
        int v = bytes[j] & 0xFF;
        hexChars[j * 2] = HEX_ARRAY[v >>> 4];
        hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
    }
    return new String(hexChars, StandardCharsets.UTF_8);
}

266
আমি সবেমাত্র javax.xML.bind.DataTypeConverter , স্ট্যান্ডার্ড বিতরণের অংশ। আপনি যখন এই ধরণের সমস্যা গুগল করেন তখন এটি কেন আসে না? String printHexBinary(byte[])এবং সহ প্রচুর সহায়ক সরঞ্জাম byte[] parseHexBinary(String)printHexBinaryতবে, এই উত্তরের ক্রিয়াকলাপের তুলনায় অনেক (2x) ধীর গতির। (আমি উৎস চেক করা; এটি একটি ব্যবহার stringBuilderparseHexBinaryএকটি অ্যারের ব্যবহার করে।) সত্যিই, যদিও, অধিকাংশ কাজের জন্য এটি দ্রুত যথেষ্ট এবং আপনি সম্ভবত ইতিমধ্যে এটা আছে।
ওয়েলকোল্ডসটেলআভান

75
অ্যান্ড্রয়েড থেকে উত্তর DataTypeConverter নেই জন্য +1
Vaiden স্বাগতম

7
@ মাইবে ওয়েলকোল্ডস্টিল আভান: জেডি কে 7 এখন উন্মুক্ত উত্স। পারফরম্যান্স উন্নত করার জন্য আমাদের printHexBinaryকী কোনও প্যাচ জমা দেওয়া উচিত ?
কেভিনার্পে

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

24
javax.xml.bind.DataTypeConverterজাভা ১১ থেকে সরানো হচ্ছে
ইম্পাইলার

421

এ্যাপাচি কমন্স কোডেক গ্রন্থাগার টি হেক্স শুধু কাজের এই ধরনের কাজ করার জন্য বর্গ।

import org.apache.commons.codec.binary.Hex;

String foo = "I am a string";
byte[] bytes = foo.getBytes();
System.out.println( Hex.encodeHexString( bytes ) );

12
@ স্যাকটিনাস - আমার ডাউনটি 4 মাস আগে ঘটেছিল তাই আমি কী ভাবছিলাম তা আমি পুরোপুরি নিশ্চিত নই, তবে সম্ভবত আমি গ্রন্থাগারের আকারটি নিয়ে আপত্তি জানছিলাম। এটি প্রোগ্রামের মধ্যে একটি ছোট ফাংশন; প্রকল্পটি সম্পাদন করার জন্য এ জাতীয় একটি বিশাল গ্রন্থাগার যুক্ত করার দরকার নেই।
আর্টঅফ ওয়ারফেয়ার

6
@ আর্টঅফওয়ারফেয়ার আমি সম্মত, তাই আপনার পরিবর্তে import org.apache.commons.codec.*;আপনি করতে পারতেনimport org.apache.commons.codec.binary.Hex;
সাইটিইনস

12
@ আর্টঅফ ওয়ারফেয়ারে আমার একমত হতে হবে না। একমাত্র ভয়ঙ্কর বিষয়টি হ'ল এপাচি কমন্স লাইব্রেরিগুলি জেআরই এবং জেডিকে দিয়ে ডিফল্টরূপে অন্তর্ভুক্ত করা হয় না। কিছু লাইব্রেরি রয়েছে যা এত কার্যকর যে সেগুলি ডিফল্টরূপে আপনার শ্রেণির পথে হওয়া উচিত এবং এটি তাদের মধ্যে একটি।
কর্সিকা

29
আমি উচ্চতর উত্তর হিসাবে অদলবদল এই উত্তরটি সুপারিশ করছি। সর্বদা কাস্টম কোডের চেয়ে ভাল পরীক্ষিত, পারফরম্যান্ট, ওপেন সোর্স লাইব্রেরি ব্যবহার করার জন্য ভোট দিন যা এতে উন্নতি হয় না।
দিমিত্রি লিখটেন

6
অথবা যদি আপনি BouncyCastle ব্যবহার করুন ( org.bouncycastle: bcprov-jdk15on :), আপনি এই শ্রেণীর ব্যবহার করতে পারেন org.bouncycastle.util.encoders.Hexএই পদ্ধতিতে:String toHexString(byte[] data)
Guillaume, Husta

320

এক্সএমএল বাইন্ডিং (জেএক্সবি)javax.xml.bind.DatatypeConverter.printHexBinary() এর জাভা আর্কিটেকচারের অংশটি, পদ্ধতিটি হ্যাক্সbyte[] স্ট্রিংয়ে রূপান্তর করার সুবিধাজনক উপায় ছিল । DatatypeConverterশ্রেণী অন্যান্য অনেক দরকারী ডেটা-ম্যানিপুলেশন পদ্ধতি অন্তর্ভুক্ত করা হয়েছে।

জাভা 8 এবং এর আগে, জেএক্সবি জাভা স্ট্যান্ডার্ড লাইব্রেরির অংশ ছিল। এটা তোলে ছিল অবচিত জাভা 9 এবং মুছে জাভা 11 তাদের নিজস্ব লাইব্রেরি সব জাভা EE প্যাকেজ সরাতে একটি প্রচেষ্টা অংশ হিসেবে। এটি একটি দীর্ঘ গল্প । এখন, javax.xml.bindবিদ্যমান নেই, এবং আপনি যদি জ্যাকএক্সবি ব্যবহার করতে চান, যার মধ্যে রয়েছে DatatypeConverter, আপনাকে জেএক্সবি এপিআই এবং জ্যাকএক্সবি রানটাইম ম্যাভেন থেকে ইনস্টল করতে হবে ।

ব্যবহারের উদাহরণ:

byte bytes[] = {(byte)0, (byte)0, (byte)134, (byte)0, (byte)61};
String hex = javax.xml.bind.DatatypeConverter.printHexBinary(bytes);

ফলাফল হবে:

000086003D

এটি এই হিসাবে একই উত্তর ।


13
একটি ভাল সমাধান, যদিও দুঃখের সাথে অ্যান্ড্রয়েডে বৈধ নয়।
কাজরিকো

@ কাজরিকো সম্ভবত আপনি কোড . google.com/p/dalvik/wiki/JavaxPackages পড়তে চান । অ্যান্ড্রয়েডে জাভ্যাক্স ক্লাসগুলি পাওয়ার একটি উপায়। তবে আপনি যদি কেবলমাত্র হেক্সে রূপান্তর করতে চান তবে এটি সমস্যার জন্য উপযুক্ত নয়।
ফোনিক্স


3
@ ফোনিক্স এটি এখনও আছে, তবে ডিফল্ট রানটাইমের অংশ নয় (জাভা 9 মডিউলগুলির কারণে)।
স্পটলাইট

2
javax.xML.bind এর উপর নির্ভর করবেন না, এটি জরিমানা সংকলন করে তবে রানটাইম পাওয়া যায় না। যদি আপনি করেন তবে java.lang.NoClassDefFoundError
Dmitry

227

সর্বাধিক সমাধান, কোনও বাহ্যিক libs, কোনও সংখ্যার ধ্রুবক:

public static String byteArrayToHex(byte[] a) {
   StringBuilder sb = new StringBuilder(a.length * 2);
   for(byte b: a)
      sb.append(String.format("%02x", b));
   return sb.toString();
}

14
এটি শীর্ষ ধরণের প্রতিক্রিয়ার চেয়ে 1000 গতি বেশি ধীর (162 বাইট দীর্ঘ) স্ট্রিং ব্যবহার করা থেকে বিরত থাকুন For
pt123

8
ধীর হতে পারে। লগইন বা অনুরূপ মতো মাঝে মধ্যে ঘটে যাওয়া জিনিসগুলির জন্য এটি ভাল।
পয়েন্টার নুল

29
যদি এটি ধীর হয়, তাহলে কি? আমার ব্যবহারের ক্ষেত্রে এটি কেবল একটি ডিবাগ স্টেটমেন্টের জন্য, সুতরাং এই কোড খণ্ডের জন্য ধন্যবাদ।
ভাইকিংস্টিভ

8
বেশ কয়েকটি ডজন কেবি অতিরিক্ত জেআর ফাইল অন্তর্ভুক্ত করে একটি লাইব্রেরি পুনরায় ব্যবহার করা ঠিক কার্যকর হবে না যদি আপনার প্রয়োজনীয় সমস্ত হ'ল এই ফাংশনটি (অ্যান্ড্রয়েডের মতো কিছু প্ল্যাটফর্মে, পুরো জারটি শেষ অ্যাপ্লিকেশনটিতে অন্তর্ভুক্ত হয়ে যায়)। এবং কখনও কখনও সংক্ষিপ্ত এবং আরও পরিষ্কার কোড ভাল হয় যখন পারফরম্যান্সের প্রয়োজন হয় না।
personne3000

2
@ personne3000 হতে পারে, তবে সেক্ষেত্রে আপনার একক কল বৈশিষ্ট্য নয়, স্ট্রিম সমর্থন প্রয়োজন। এটি এক বোঝা এবং মনে রাখা সহজ, এবং তাই বজায় রাখা।
মার্টেন বোদেউয়েস

59

সম্পূর্ণতার জন্য একটি পেয়ারা সমাধান:

import com.google.common.io.BaseEncoding;
...
byte[] bytes = "Hello world".getBytes(StandardCharsets.UTF_8);
final String hex = BaseEncoding.base16().lowerCase().encode(bytes);

এখন hexহয় "48656c6c6f20776f726c64"


পেয়ারাতেও আপনি এটি ব্যবহার করতে পারেন new HashCode(bytes).toString()
mfulton26

1
পেয়ারা 22.0 হিসাবে এটি হলHashCode.fromBytes(checksum).toString()
ডেভস্ট্র্ট

43

এই অনুলিপিটি অনুলিপি আমার জন্য
String result = new BigInteger(1, inputBytes).toString(16);
সম্পাদনা করে - এটি ব্যবহার করা নেতৃস্থানীয় শূন্যগুলি সরিয়ে ফেলবে, কিন্তু হেই আমার ব্যবহারের ক্ষেত্রে কাজ করেছে। এটি নির্দেশ করার জন্য @ ভাইকুকে ধন্যবাদ


56
এই অনেলাইনার শূন্য বাইটের শীর্ষে নেমেছে
ভোকু

@ ভাইকু ... এবং এটি সময়ের শূন্য 50% যোগ করবে।
মার্টেন বোদেউয়েস

27

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

বিকল্প 1: কোড স্নিপেট - সাধারণ

একটি খুব সহজ সমাধান হ'ল BigIntegerএর হেক্স উপস্থাপনা ব্যবহার করা :

new BigInteger(1, someByteArray).toString(16)

নোট করুন যেহেতু এই সংখ্যাগুলিকে বিনা মূল্যে বাইট-স্ট্রিং না করে হ্যান্ডলগুলি নেতৃস্থানীয় শূন্যগুলি বাদ দেবে - এটি আপনি যা চান তা হতে পারে বা নাও পারে (উদাহরণস্বরূপ 3 বাইট 000AE3ইনপুটটির 0AE3জন্য বনাম )। এটি পরবর্তী ধাপের তুলনায় প্রায় 100x ধীর গতিতেও খুব ধীর ।

বিকল্প 2: কোড স্নিপেট - উন্নত

এখানে একটি পূর্ণ বৈশিষ্ট্যযুক্ত, কপি & pasteable কোড সমর্থনকারী স্নিপেট উপরের / ছোট হাতের এবং endianness । এটি মেমরির জটিলতা হ্রাস করতে এবং কার্যকারিতা সর্বাধিকীকরণ করতে অনুকূলিত এবং সমস্ত আধুনিক জাভা সংস্করণ (5+) এর সাথে সামঞ্জস্যপূর্ণ হওয়া উচিত।

private static final char[] LOOKUP_TABLE_LOWER = new char[]{0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
private static final char[] LOOKUP_TABLE_UPPER = new char[]{0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46};

public static String encode(byte[] byteArray, boolean upperCase, ByteOrder byteOrder) {

    // our output size will be exactly 2x byte-array length
    final char[] buffer = new char[byteArray.length * 2];

    // choose lower or uppercase lookup table
    final char[] lookup = upperCase ? LOOKUP_TABLE_UPPER : LOOKUP_TABLE_LOWER;

    int index;
    for (int i = 0; i < byteArray.length; i++) {
        // for little endian we count from last to first
        index = (byteOrder == ByteOrder.BIG_ENDIAN) ? i : byteArray.length - i - 1;

        // extract the upper 4 bit and look up char (0-A)
        buffer[i << 1] = lookup[(byteArray[index] >> 4) & 0xF];
        // extract the lower 4 bit and look up char (0-A)
        buffer[(i << 1) + 1] = lookup[(byteArray[index] & 0xF)];
    }
    return new String(buffer);
}

public static String encode(byte[] byteArray) {
    return encode(byteArray, false, ByteOrder.BIG_ENDIAN);
}

অ্যাপাচি ভি 2 লাইসেন্স এবং ডিকোডার সহ সম্পূর্ণ উত্স কোডটি এখানে পাওয়া যাবে

বিকল্প 3: একটি ছোট্ট অপ্টিমাইজড লাইব্রেরি ব্যবহার: বাইটস-জাভা

আমার আগের প্রকল্পে কাজ করার সময়, আমি জাভাতে বাইটস নিয়ে কাজ করার জন্য এই ছোট্ট টুলকিটটি তৈরি করেছি। এটির কোনও বাহ্যিক নির্ভরতা নেই এবং এটি জাভা 7+ এর সাথে সামঞ্জস্যপূর্ণ। এটিতে অন্যদের মধ্যে খুব দ্রুত এবং পরীক্ষিত এইচএক্স এন / ডিকোডার অন্তর্ভুক্ত রয়েছে:

import at.favre.lib.bytes.Bytes;
...
Bytes.wrap(someByteArray).encodeHex()

আপনি এটি গিথুব: বাইটস-জাভাতে পরীক্ষা করে দেখতে পারেন ।

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

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

import org.apache.commons.codec.binary.Hex;
...
Hex.encodeHexString(someByteArray));

বিকল্প 5: গুগল পেয়ারা

প্রায়শই না আপনার ইতিমধ্যে নির্ভরতা হিসাবে পেয়ারা রয়েছে । যদি তাই হয় তবে ব্যবহার করুন:

import com.google.common.io.BaseEncoding;
...
BaseEncoding.base16().lowerCase().encode(someByteArray);

বিকল্প 6: বসন্ত সুরক্ষা

আপনি যদি বসন্ত সুরক্ষা সহ স্প্রিং ফ্রেমওয়ার্ক ব্যবহার করেন তবে আপনি নিম্নলিখিতটি ব্যবহার করতে পারেন:

import org.springframework.security.crypto.codec.Hex
...
new String(Hex.encode(someByteArray));

বিকল্প 7: বাউন্সি ক্যাসল

আপনি যদি ইতিমধ্যে সুরক্ষা কাঠামো বাউন্সি ক্যাসল ব্যবহার করেন তবে আপনি এর ব্যবহারটি ব্যবহার করতে পারেন Hex:

import org.bouncycastle.util.encoders.Hex;
...
Hex.toHexString(someByteArray);

সত্যিকারের বিকল্প নয় 8: জাভা 9+ সামঞ্জস্যতা বা 'জ্যাকএক্সবি জাভ্যাক্স / এক্সএমএল / বাইন্ড / ডেটাটাইপ কনভার্টার ব্যবহার করবেন না'

পূর্ববর্তী জাভা (8 এবং নীচে) সংস্করণগুলিতে জএএক্সবি-র জাভা কোড রানটাইম নির্ভরতা হিসাবে অন্তর্ভুক্ত ছিল। জাভা 9 এবং জিগস মডুলারাইজেশন হওয়ার কারণে আপনার কোড সুস্পষ্ট ঘোষণা ছাড়াই এর মডিউলের বাইরে থাকা অন্য কোডগুলিতে অ্যাক্সেস করতে পারে না। আপনি যদি এর মতো ব্যতিক্রম পান তবে সচেতন হন:

java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException

জাভা 9+ দিয়ে যখন কোন JVM এ চলছে। যদি তা হয় তবে উপরের বিকল্পগুলির কোনওটিতে প্রয়োগগুলি স্যুইচ করুন। এই প্রশ্নটি দেখুন


মাইক্রো বেঞ্চমার্ক

এখানে বিভিন্ন আকারের একটি সাধারণ জেএমএইচ মাইক্রো বেঞ্চমার্ক এনকোডিং বাইট অ্যারে থেকে ফলাফল । মানগুলি প্রতি সেকেন্ডে অপারেশন হয়, তাই আরও ভাল is নোট করুন যে মাইক্রো মানদণ্ডগুলি প্রায়শই বাস্তব বিশ্বের আচরণের প্রতিনিধিত্ব করে না, সুতরাং লবণের দানা দিয়ে এই ফলাফলগুলি নিন।

| Name (ops/s)         |    16 byte |    32 byte |  128 byte | 0.95 MB |
|----------------------|-----------:|-----------:|----------:|--------:|
| Opt1: BigInteger     |  2,088,514 |  1,008,357 |   133,665 |       4 |
| Opt2/3: Bytes Lib    | 20,423,170 | 16,049,841 | 6,685,522 |     825 |
| Opt4: Apache Commons | 17,503,857 | 12,382,018 | 4,319,898 |     529 |
| Opt5: Guava          | 10,177,925 |  6,937,833 | 2,094,658 |     257 |
| Opt6: Spring         | 18,704,986 | 13,643,374 | 4,904,805 |     601 |
| Opt7: BC             |  7,501,666 |  3,674,422 | 1,077,236 |     152 |
| Opt8: JAX-B          | 13,497,736 |  8,312,834 | 2,590,940 |     346 |

স্পেস: জেডিকে 8u202, i7-7700 কে, উইন 10, 24 জিবি রাম। এখানে পূর্ণ মানদণ্ড দেখুন ।




17

আমি এখানে তিনটি ভিন্ন উপায় পেয়েছি: http://www.rgagnon.com/javadetails/java-0596.html

সর্বাধিক মার্জিত একটি, যেমনটি তিনি নোট করেছেন, আমার কাছে মনে হয় এটি একটি:

static final String HEXES = "0123456789ABCDEF";
public static String getHex( byte [] raw ) {
    if ( raw == null ) {
        return null;
    }
    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();
}

অন্যান্য পদ্ধতিগুলি আমার by৪ বাইট নমুনায় 5 এমএসে চলছিল, এটি 0 এমএসে চলে। বিন্যাসের মতো স্ট্রিংয়ের কোনও ক্রিয়াকলাপের অভাবে সম্ভবত সেরা।
জোসেফ লাস্ট

if (raw == null) return nullদ্রুত ব্যর্থ হয় না। আপনি কেন কখনও nullচাবি ব্যবহার করবেন ?
মার্টেন বোদেউয়েস

আমি মনে করি এটির বৈধতা প্রবেশের অভ্যাস। এই ক্ষেত্রে, আমরা কোনও নাল রেফারেন্স ব্যতিক্রমকে প্রতিরোধ করি এবং খারাপ ডেটা পরিচালনা করতে কলারের কাছে রেখে দিই।
মাইকেল বিসবার্গ

16

অনুসন্ধানের টেবিলটি সঞ্চয় করার সামান্য ব্যয়ে এই বাস্তবায়নটি সহজ এবং খুব দ্রুত।

 private static final char[] BYTE2HEX=(
    "000102030405060708090A0B0C0D0E0F"+
    "101112131415161718191A1B1C1D1E1F"+
    "202122232425262728292A2B2C2D2E2F"+
    "303132333435363738393A3B3C3D3E3F"+
    "404142434445464748494A4B4C4D4E4F"+
    "505152535455565758595A5B5C5D5E5F"+
    "606162636465666768696A6B6C6D6E6F"+
    "707172737475767778797A7B7C7D7E7F"+
    "808182838485868788898A8B8C8D8E8F"+
    "909192939495969798999A9B9C9D9E9F"+
    "A0A1A2A3A4A5A6A7A8A9AAABACADAEAF"+
    "B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF"+
    "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"+
    "D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF"+
    "E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF"+
    "F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF").toCharArray();
   ; 

  public static String getHexString(byte[] bytes) {
    final int len=bytes.length;
    final char[] chars=new char[len<<1];
    int hexIndex;
    int idx=0;
    int ofs=0;
    while (ofs<len) {
      hexIndex=(bytes[ofs++] & 0xFF)<<1;
      chars[idx++]=BYTE2HEX[hexIndex++];
      chars[idx++]=BYTE2HEX[hexIndex];
    }
    return new String(chars);
  }

6
BYTE2HEXসাধারণ forচক্র দিয়ে অ্যারেটি কেন আরম্ভ করবেন না ?
আইজজা

@ আইকজা কি স্ট্যাটিক ফাইনাল (ওরফে ধ্রুবক) ফিল্ডের সাথেও কি এটি সম্ভব?
নেভেলিস

1
@ নিউভেলিস এটি একটি static { }ব্লকে বরাদ্দ করা যেতে পারে ।
26 ル ち ゃ ん だ よ

1
@ আইকজা কারণ এটি দেখার চেয়ে দ্রুত অনুসন্ধানের টেবিলটিকে হার্ডকোড করা দ্রুত। এখানে মেমরি জটিলতা সময় জটিলতার সাথে লেনদেন হয়, যেমন। আরও মেমরির প্রয়োজন তবে দ্রুত (উভয় প্রান্তে প্রতিটি সামান্য)
প্যাট্রিক ফ্যাভরে

8

এ কেমন?

    String byteToHex(final byte[] hash)
    {
        Formatter formatter = new Formatter();
        for (byte b : hash)
        {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

3

আমাদের কোনও বাহ্যিক গ্রন্থাগার ব্যবহার করার বা লুপ এবং ধ্রুবকগুলির উপর ভিত্তি করে কোড লেখার দরকার নেই।
এই যথেষ্ট:

byte[] theValue = .....
String hexaString = new BigInteger(1, theValue).toString(16);

1
এটি এভারকনফিউজড গুয়ের জবাবের সাথে খুব মিল।
স্ক্র্যাটে

2

আমি এটি ব্যবহার করতে পছন্দ করি:

final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes, int offset, int count) {
    char[] hexChars = new char[count * 2];
    for ( int j = 0; j < count; j++ ) {
        int v = bytes[j+offset] & 0xFF;
        hexChars[j * 2] = hexArray[v >>> 4];
        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    return new String(hexChars);
}

এটি গ্রহণযোগ্য উত্তরের সামান্য আরও নমনীয় অভিযোজন। ব্যক্তিগতভাবে, আমি স্বীকৃত উত্তর এবং এটির ওভারলোড উভয়ই রাখি, আরও প্রসঙ্গে ব্যবহারযোগ্য able


মূল প্রশ্নটি ছিল স্ট্রিংয়ের বাইট [] এর জন্য। বাইটস থেকে হেক্স দেখুন [] বা একটি ভিন্ন প্রশ্ন জিজ্ঞাসা করুন, @ ননএক্সেস্টেন্ট।
বামাকো

2

আমি সাধারণত ডিবুফ স্টেটমেন্টের জন্য নিম্নলিখিত পদ্ধতিটি ব্যবহার করি তবে এটি জানি না যে এটি করার সর্বোত্তম উপায় কিনা i

private static String digits = "0123456789abcdef";

public static String toHex(byte[] data){
    StringBuffer buf = new StringBuffer();
    for (int i = 0; i != data.length; i++)
    {
        int v = data[i] & 0xff;
        buf.append(digits.charAt(v >> 4));
        buf.append(digits.charAt(v & 0xf));
    }
    return buf.toString();
}

2
আপনার debuffer একটি খারাপ দিন থাকে, তাহলে সমর্থন অক্ষর একটি সংখ্যা সঙ্গে StringBuilder ইনস্ট্যান্স মধ্যে cluing দেখুন: StringBuilder buf = new StringBuilder(data.length * 2);
গ্রেইবার্ড

2

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

org.apache.commons.codec.binary.Hex

হয়তো তোমার কাছে ...

org.apache.xerces.impl.dv.util.HexBin


2

আপনি যদি বসন্ত সুরক্ষা কাঠামো ব্যবহার করেন তবে আপনি ব্যবহার করতে পারেন:

import org.springframework.security.crypto.codec.Hex

final String testString = "Test String";
final byte[] byteArray = testString.getBytes();
System.out.println(Hex.encode(byteArray));

2

সাধারণ ফাংশনের জন্য ইউটিলিটি জার যুক্ত করা ভাল বিকল্প নয়। পরিবর্তে আপনার নিজস্ব ইউটিলিটি ক্লাসগুলি একত্র করুন। নিম্নলিখিত দ্রুত বাস্তবায়ন সম্ভব।

public class ByteHex {

    public static int hexToByte(char ch) {
        if ('0' <= ch && ch <= '9') return ch - '0';
        if ('A' <= ch && ch <= 'F') return ch - 'A' + 10;
        if ('a' <= ch && ch <= 'f') return ch - 'a' + 10;
        return -1;
    }

    private static final String[] byteToHexTable = 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"
    };

    private static final String[] byteToHexTableLowerCase = 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 byteToHexTable[b & 0xFF];
    }

    public static String byteToHex(byte[] bytes){
        if(bytes == null) return null;
        StringBuilder sb = new StringBuilder(bytes.length*2);
        for(byte b : bytes) sb.append(byteToHexTable[b & 0xFF]);
        return sb.toString();
    }

    public static String byteToHex(short[] bytes){
        StringBuilder sb = new StringBuilder(bytes.length*2);
        for(short b : bytes) sb.append(byteToHexTable[((byte)b) & 0xFF]);
        return sb.toString();
    }

    public static String byteToHexLowerCase(byte[] bytes){
        StringBuilder sb = new StringBuilder(bytes.length*2);
        for(byte b : bytes) sb.append(byteToHexTableLowerCase[b & 0xFF]);
        return sb.toString();
    }

    public static byte[] hexToByte(String hexString) {
        if(hexString == null) return null;
        byte[] byteArray = new byte[hexString.length() / 2];
        for (int i = 0; i < hexString.length(); i += 2) {
            byteArray[i / 2] = (byte) (hexToByte(hexString.charAt(i)) * 16 + hexToByte(hexString.charAt(i+1)));
        }
        return byteArray;
    }

    public static byte hexPairToByte(char ch1, char ch2) {
        return (byte) (hexToByte(ch1) * 16 + hexToByte(ch2));
    }


}

1

@ মাইবেউইকোল্ডস্টেলাওয়ান দ্বারা প্রস্তাবিত সমাধানটির একটি ছোট বৈকল্পিক, যা আপনাকে আউটপুট হেক্স স্ট্রিংয়ে একসাথে এন বাইটগুলি বান্ডিল করতে দেয়:

 final static char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
 final static char BUNDLE_SEP = ' ';

public static String bytesToHexString(byte[] bytes, int bundleSize /*[bytes]*/]) {
        char[] hexChars = new char[(bytes.length * 2) + (bytes.length / bundleSize)];
        for (int j = 0, k = 1; j < bytes.length; j++, k++) {
                int v = bytes[j] & 0xFF;
                int start = (j * 2) + j/bundleSize;

                hexChars[start] = HEX_ARRAY[v >>> 4];
                hexChars[start + 1] = HEX_ARRAY[v & 0x0F];

                if ((k % bundleSize) == 0) {
                        hexChars[start + 2] = BUNDLE_SEP;
                }   
        }   
        return new String(hexChars).trim();    
}

এটাই:

bytesToHexString("..DOOM..".toCharArray().getBytes(), 2);
2E2E 444F 4F4D 2E2E

bytesToHexString("..DOOM..".toCharArray().getBytes(), 4);
2E2E444F 4F4D2E2E

1

এই পৃষ্ঠায় এমন কোনও সমাধান খুঁজে পাচ্ছেন না যা না

  1. একটি লুপ ব্যবহার করুন
  2. Javax.xML.bind.DatatypeConverter ব্যবহার করুন যা সূক্ষ্ম সংকলন করে তবে প্রায়শই জাটা.আলং.নোক্লাসডেফফাউন্ডআরার রানটাইমের সময় নিক্ষেপ করে।

এখানে এমন একটি সমাধান রয়েছে যার উপরে ত্রুটিগুলি নেই (কোন প্রতিশ্রুতি আমার অন্য ত্রুটিগুলি নেই যদিও)

import java.math.BigInteger;

import static java.lang.System.out;
public final class App2 {
    // | proposed solution.
    public static String encode(byte[] bytes) {          
        final int length = bytes.length;

        // | BigInteger constructor throws if it is given an empty array.
        if (length == 0) {
            return "00";
        }

        final int evenLength = (int)(2 * Math.ceil(length / 2.0));
        final String format = "%0" + evenLength + "x";         
        final String result = String.format (format, new BigInteger(bytes));

        return result;
    }

    public static void main(String[] args) throws Exception {
        // 00
        out.println(encode(new byte[] {})); 

        // 01
        out.println(encode(new byte[] {1})); 

        //203040
        out.println(encode(new byte[] {0x20, 0x30, 0x40})); 

        // 416c6c20796f75722062617365206172652062656c6f6e6720746f2075732e
        out.println(encode("All your base are belong to us.".getBytes()));
    }
}   

আমি এটি 62 টি অপকডের আওতায় পেতে পারি না তবে প্রথম বাইট 0x10 এর চেয়ে কম ক্ষেত্রে আপনি যদি 0 প্যাডিং ছাড়া বেঁচে থাকতে পারেন তবে নীচের সমাধানটি কেবলমাত্র 23 টি অপকড ব্যবহার করে। সত্যিই দেখায় যে "স্ট্রিং দৈর্ঘ্য বিজোড় হলে শূন্যের সাথে প্যাডের মতো" নিজেকে কীভাবে কার্যকর করা যায় "সমাধানগুলি কীভাবে ব্যয়বহুল হয়ে উঠতে পারে যদি কোনও দেশীয় বাস্তবায়ন ইতিমধ্যে উপলব্ধ না হয় (বা এই ক্ষেত্রে যদি বিগইন্টেগারের জিরোসের সাথে উপসর্গের বিকল্প থাকে তবে স্ট্রিং).

public static String encode(byte[] bytes) {          
    final int length = bytes.length;

    // | BigInteger constructor throws if it is given an empty array.
    if (length == 0) {
        return "00";
    }

    return new BigInteger(bytes).toString(16);
}

1

আমার সমাধান হতে পারে ওয়েলকোল্ডস্টিল আভানের সমাধানের উপর ভিত্তি করে, তবে কোনও অতিরিক্ত বরাদ্দ হওয়া অনুসন্ধানের টেবিলগুলির উপর নির্ভর করে না। এটি কোনও 'ইন্টার-টু-চর' কাস্ট হ্যাক ব্যবহার করে না (অঙ্কটি আসলে Character.forDigit()কী তা যাচাই করার জন্য কিছু তুলনা করে আসলে তা করে) এবং এটি কিছুটা ধীর হতে পারে। আপনি যেখানে খুশি সেখানে এটি নির্দ্বিধায় অনুভব করুন। চিয়ার্স।

public static String bytesToHex(final byte[] bytes)
{
    final int numBytes = bytes.length;
    final char[] container = new char[numBytes * 2];

    for (int i = 0; i < numBytes; i++)
    {
        final int b = bytes[i] & 0xFF;

        container[i * 2] = Character.forDigit(b >>> 4, 0x10);
        container[i * 2 + 1] = Character.forDigit(b & 0xF, 0x10);
    }

    return new String(container);
}

0

// বাইটগুলি স্থানান্তর করা আরও দক্ষ // আপনি এটিকেও ব্যবহার করতে পারেন

public static String getHexString (String s) 
{
    byte[] buf = s.getBytes();

    StringBuffer sb = new StringBuffer();

    for (byte b:buf)
    {
        sb.append(String.format("%x", b));
    }


        return sb.toString();
}

0

আপনি যদি পাইথনের জন্য ঠিক এর মতো বাইট অ্যারের সন্ধান করেন তবে আমি এই জাভা প্রয়োগটি পাইথনে রূপান্তর করেছি।

class ByteArray:

@classmethod
def char(cls, args=[]):
    cls.hexArray = "0123456789ABCDEF".encode('utf-16')
    j = 0
    length = (cls.hexArray)

    if j < length:
        v = j & 0xFF
        hexChars = [None, None]
        hexChars[j * 2] = str( cls.hexArray) + str(v)
        hexChars[j * 2 + 1] = str(cls.hexArray) + str(v) + str(0x0F)
        # Use if you want...
        #hexChars.pop()

    return str(hexChars)

array = ByteArray()
print array.char(args=[])

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

0

এখানে একটি java.util.Base64সদৃশ বাস্তবায়ন (আংশিক), সুন্দর না?

public class Base16/*a.k.a. Hex*/ {
    public static class Encoder{
        private static char[] toLowerHex={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
        private static char[] toUpperHex={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
        private boolean upper;
        public Encoder(boolean upper) {
            this.upper=upper;
        }
        public String encode(byte[] data){
            char[] value=new char[data.length*2];
            char[] toHex=upper?toUpperHex:toLowerHex;
            for(int i=0,j=0;i<data.length;i++){
                int octet=data[i]&0xFF;
                value[j++]=toHex[octet>>4];
                value[j++]=toHex[octet&0xF];
            }
            return new String(value);
        }
        static final Encoder LOWER=new Encoder(false);
        static final Encoder UPPER=new Encoder(true);
    }
    public static Encoder getEncoder(){
        return Encoder.LOWER;
    }
    public static Encoder getUpperEncoder(){
        return Encoder.UPPER;
    }
    //...
}

0
private static String bytesToHexString(byte[] bytes, int length) {
        if (bytes == null || length == 0) return null;

        StringBuilder ret = new StringBuilder(2*length);

        for (int i = 0 ; i < length ; i++) {
            int b;

            b = 0x0f & (bytes[i] >> 4);
            ret.append("0123456789abcdef".charAt(b));

            b = 0x0f & bytes[i];
            ret.append("0123456789abcdef".charAt(b));
        }

        return ret.toString();
    }

0
Converts bytes data to hex characters

@param bytes byte array to be converted to hex string
@return byte String in hex format

private static String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    int v;
    for (int j = 0; j < bytes.length; j++) {
        v = bytes[j] & 0xFF;
        hexChars[j * 2] = HEX_ARRAY[v >>> 4];
        hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
    }
    return new String(hexChars);
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.