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


1371

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


8
নীচে গৃহীত উত্তরগুলি বাইট রূপান্তর করতে স্ট্রিংয়ের একটি ভয়ঙ্কর পরিমাণের স্ট্রিং বরাদ্দ করে appear আমি ভাবছি কীভাবে এটি পারফরম্যান্সকে প্রভাবিত করে
উইম কয়েনেন

9
সোপহেক্সাইনারি ক্লাসটি আপনি যা ভাবেন ঠিক তেমন করে exactly
মাইক্রফ্ট

আমার কাছে মনে হয় যে 1 টি পোস্টে 2 টি প্রশ্ন জিজ্ঞাসা করা যথেষ্ট মানসম্পন্ন নয়।
স্যান্ডরক

উত্তর:


1353

উভয় ক্ষেত্রেই:

public static string ByteArrayToString(byte[] ba)
{
  StringBuilder hex = new StringBuilder(ba.Length * 2);
  foreach (byte b in ba)
    hex.AppendFormat("{0:x2}", b);
  return hex.ToString();
}

বা:

public static string ByteArrayToString(byte[] ba)
{
  return BitConverter.ToString(ba).Replace("-","");
}

এটি করার আরও আরও বিভিন্ন রূপ রয়েছে, উদাহরণস্বরূপ এখানে

বিপরীত রূপান্তরটি এরকম হবে:

public static byte[] StringToByteArray(String hex)
{
  int NumberChars = hex.Length;
  byte[] bytes = new byte[NumberChars / 2];
  for (int i = 0; i < NumberChars; i += 2)
    bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
  return bytes;
}

এর Substringসাথে মিলিয়ে সেরা বিকল্পটি ব্যবহার করা Convert.ToByte। আরও তথ্যের জন্য এই উত্তর দেখুন । আপনার যদি আরও ভাল পারফরম্যান্সের প্রয়োজন হয় তবে Convert.ToByteড্রপ দেওয়ার আগে আপনাকে অবশ্যই এড়ানো উচিত SubString


24
আপনি সাবস্ট্রিং ব্যবহার করছেন। এই লুপটি ভয়াবহ পরিমাণ স্ট্রিং অবজেক্টগুলিকে বরাদ্দ করে না?
উইম কয়েনেন

30
সত্যিই - যতক্ষণ না এটি নাটকীয়ভাবে পারফরম্যান্সকে নাড়িয়ে দেয় আমি এটিকে উপেক্ষা করে রানটাইম এবং জিসিকে এটির যত্ন নেওয়ার জন্য বিশ্বাস করি।
তোমালাক

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

7
@ 00jt আপনার অবশ্যই একটি অনুমান করতে হবে যে এফ == 0 এফ। হয় এটি 0F এর সমান, অথবা ইনপুটটি ক্লিপ করা হয়েছিল এবং এফ আসলে আপনি যে কোনও কিছু পাননি সেটির শুরু। এই অনুমানগুলি করা আপনার প্রসঙ্গের উপর নির্ভর করে তবে আমি বিশ্বাস করি যে কোনও সাধারণ উদ্দেশ্যমূলক ক্রিয়াকলাপটি কলিং কোডের জন্য অনুমানের পরিবর্তে বিজোড় অক্ষরগুলিকে অবৈধ হিসাবে প্রত্যাখ্যান করে।
ডেভিড বোইকে

11
@ ডেভিডবাইক প্রশ্নটিতে "সম্ভবত ক্লিপড স্ট্রিমের মানগুলি কীভাবে পরিচালনা করতে হবে" এর সাথে স্ট্রিং সম্পর্কে কথা বলার কিছুই ছিল না। স্ট্রিং মাইভ্যালু = ১০ টিস্ট্রিং ("এক্স"); মাইভ্যালু হ'ল "এ" "0 এ" নয়। এবার সেই স্ট্রিংটি আবার বাইটে পড়ুন, উফ আপনি এটি ভেঙে দিয়েছেন।
00jt

488

কর্মক্ষমতা বিশ্লেষণ

দ্রষ্টব্য: 2015-08-22 হিসাবে নতুন নেতা।

আমি কিছু ক্রুড Stopwatchপারফরম্যান্স পরীক্ষার মাধ্যমে বিভিন্ন রূপান্তর পদ্ধতির প্রত্যেকটি দৌড়েছিলাম , একটি র্যান্ডম বাক্য (এন = 61, 1000 পুনরাবৃত্তি) সহ একটি রান এবং একটি প্রকল্প গুটেনবার্গ পাঠ্য সহ একটি রান (এন = 1,238,957, 150 পুনরাবৃত্তি)। মোটামুটি দ্রুত থেকে ধীরে ধীরে ফলাফলগুলি এখানে। সমস্ত পরিমাপ টিক্সে রয়েছে ( 10,000 টিক্স = 1 এমএস ) এবং সমস্ত আপেক্ষিক নোটগুলি [ধীরতম] StringBuilderবাস্তবায়নের সাথে তুলনা করা হয় । ব্যবহৃত কোডের জন্য, নীচে দেখুন বা টেস্ট ফ্রেমওয়ার্ক রেপো যেখানে এখন আমি এটি চালানোর জন্য কোড বজায় রেখেছি।

দাবি পরিত্যাগী

সতর্কতা: কোন কিছু কংক্রিটের জন্য এই পরিসংখ্যানগুলির উপর নির্ভর করবেন না; এগুলি কেবল নমুনা ডেটার একটি নমুনা রান। আপনার যদি সত্যই শীর্ষস্থানীয় পারফরম্যান্সের প্রয়োজন হয় তবে দয়া করে আপনি কী ব্যবহার করবেন তার ডেটা প্রতিনিধির সাথে আপনার উত্পাদন প্রয়োজনের পরিবেশের প্রতিনিধি হিসাবে এই পদ্ধতিগুলি পরীক্ষা করুন।

ফলাফল

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

আপনার সেরা বাজিটি এখনও কিছু প্রতিনিধি ডেটা সন্ধান করতে এবং উত্পাদন-মতো পরিবেশে এটি চেষ্টা করে চলেছে। আপনার যদি মেমরির বিভিন্ন বাধা থাকে তবে আপনি কম বরাদ্দের একটি পদ্ধতি পছন্দ করতে পারেন যা দ্রুত হবে তবে আরও মেমরি গ্রাস করবে।

পরীক্ষার কোড

আমি ব্যবহার করা টেস্টিং কোডটি নির্দ্বিধায় খেলুন। একটি সংস্করণ এখানে অন্তর্ভুক্ত করা হয়েছে তবে রেপো ক্লোন করতে এবং আপনার নিজস্ব পদ্ধতি যুক্ত করতে নির্দ্বিধায় । আপনি আকর্ষণীয় কিছু খুঁজে পেতে বা এটি ব্যবহার করে পরীক্ষার কাঠামো উন্নত করতে সহায়তা করতে চান দয়া করে একটি টান অনুরোধ জমা দিন।

  1. / Func<byte[], string>টেস্টস / কনভার্টবাইটআরেট্যোহেক্সস্ট্রিং / টেস্ট.সি-তে নতুন স্ট্যাটিক পদ্ধতি ( ) যুক্ত করুন।
  2. TestCandidatesএকই শ্রেণিতে রিটার্ন মানটিতে সেই পদ্ধতির নাম যুক্ত করুন ।
  3. GenerateTestInputএকই শ্রেণিতে মন্তব্যগুলিতে টগল করে আপনি যে ইনপুট সংস্করণটি চান তা বাক্য বা পাঠ্য চালিয়ে যাচ্ছেন তা নিশ্চিত করুন ।
  4. হিট F5এবং আউটপুটটির জন্য অপেক্ষা করুন (একটি HTML ডাম্প / বিন ফোল্ডারেও উত্পন্ন হয়)।
static string ByteArrayToHexStringViaStringJoinArrayConvertAll(byte[] bytes) {
    return string.Join(string.Empty, Array.ConvertAll(bytes, b => b.ToString("X2")));
}
static string ByteArrayToHexStringViaStringConcatArrayConvertAll(byte[] bytes) {
    return string.Concat(Array.ConvertAll(bytes, b => b.ToString("X2")));
}
static string ByteArrayToHexStringViaBitConverter(byte[] bytes) {
    string hex = BitConverter.ToString(bytes);
    return hex.Replace("-", "");
}
static string ByteArrayToHexStringViaStringBuilderAggregateByteToString(byte[] bytes) {
    return bytes.Aggregate(new StringBuilder(bytes.Length * 2), (sb, b) => sb.Append(b.ToString("X2"))).ToString();
}
static string ByteArrayToHexStringViaStringBuilderForEachByteToString(byte[] bytes) {
    StringBuilder hex = new StringBuilder(bytes.Length * 2);
    foreach (byte b in bytes)
        hex.Append(b.ToString("X2"));
    return hex.ToString();
}
static string ByteArrayToHexStringViaStringBuilderAggregateAppendFormat(byte[] bytes) {
    return bytes.Aggregate(new StringBuilder(bytes.Length * 2), (sb, b) => sb.AppendFormat("{0:X2}", b)).ToString();
}
static string ByteArrayToHexStringViaStringBuilderForEachAppendFormat(byte[] bytes) {
    StringBuilder hex = new StringBuilder(bytes.Length * 2);
    foreach (byte b in bytes)
        hex.AppendFormat("{0:X2}", b);
    return hex.ToString();
}
static string ByteArrayToHexViaByteManipulation(byte[] bytes) {
    char[] c = new char[bytes.Length * 2];
    byte b;
    for (int i = 0; i < bytes.Length; i++) {
        b = ((byte)(bytes[i] >> 4));
        c[i * 2] = (char)(b > 9 ? b + 0x37 : b + 0x30);
        b = ((byte)(bytes[i] & 0xF));
        c[i * 2 + 1] = (char)(b > 9 ? b + 0x37 : b + 0x30);
    }
    return new string(c);
}
static string ByteArrayToHexViaByteManipulation2(byte[] bytes) {
    char[] c = new char[bytes.Length * 2];
    int b;
    for (int i = 0; i < bytes.Length; i++) {
        b = bytes[i] >> 4;
        c[i * 2] = (char)(55 + b + (((b - 10) >> 31) & -7));
        b = bytes[i] & 0xF;
        c[i * 2 + 1] = (char)(55 + b + (((b - 10) >> 31) & -7));
    }
    return new string(c);
}
static string ByteArrayToHexViaSoapHexBinary(byte[] bytes) {
    SoapHexBinary soapHexBinary = new SoapHexBinary(bytes);
    return soapHexBinary.ToString();
}
static string ByteArrayToHexViaLookupAndShift(byte[] bytes) {
    StringBuilder result = new StringBuilder(bytes.Length * 2);
    string hexAlphabet = "0123456789ABCDEF";
    foreach (byte b in bytes) {
        result.Append(hexAlphabet[(int)(b >> 4)]);
        result.Append(hexAlphabet[(int)(b & 0xF)]);
    }
    return result.ToString();
}
static readonly uint* _lookup32UnsafeP = (uint*)GCHandle.Alloc(_Lookup32, GCHandleType.Pinned).AddrOfPinnedObject();
static string ByteArrayToHexViaLookup32UnsafeDirect(byte[] bytes) {
    var lookupP = _lookup32UnsafeP;
    var result = new string((char)0, bytes.Length * 2);
    fixed (byte* bytesP = bytes)
    fixed (char* resultP = result) {
        uint* resultP2 = (uint*)resultP;
        for (int i = 0; i < bytes.Length; i++) {
            resultP2[i] = lookupP[bytesP[i]];
        }
    }
    return result;
}
static uint[] _Lookup32 = Enumerable.Range(0, 255).Select(i => {
    string s = i.ToString("X2");
    return ((uint)s[0]) + ((uint)s[1] << 16);
}).ToArray();
static string ByteArrayToHexViaLookupPerByte(byte[] bytes) {
    var result = new char[bytes.Length * 2];
    for (int i = 0; i < bytes.Length; i++)
    {
        var val = _Lookup32[bytes[i]];
        result[2*i] = (char)val;
        result[2*i + 1] = (char) (val >> 16);
    }
    return new string(result);
}
static string ByteArrayToHexViaLookup(byte[] bytes) {
    string[] hexStringTable = 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",
    };
    StringBuilder result = new StringBuilder(bytes.Length * 2);
    foreach (byte b in bytes) {
        result.Append(hexStringTable[b]);
    }
    return result.ToString();
}

আপডেট (2010-01-13)

বিশ্লেষণে ওয়ালিদের উত্তর যুক্ত হয়েছে। দ্রুত শেষ কর.

আপডেট (2011-10-05)

যোগ করা হয়েছে string.Concat Array.ConvertAllসম্পূর্ণতার জন্য বৈকল্পিক (.NET 4.0 আবশ্যক)। string.Joinসংস্করণ সমান ।

আপডেট (2012-02-05)

টেস্ট রেপোতে আরও রূপগুলি অন্তর্ভুক্ত করে StringBuilder.Append(b.ToString("X2"))। কেউ ফলাফল খারাপ করে না। উদাহরণস্বরূপ foreachতুলনায় দ্রুত {IEnumerable}.Aggregate, কিন্তু BitConverterএখনও জিতেছে।

আপডেট (2012-04-03)

মাইক্রফ্টের SoapHexBinaryবিশ্লেষণের উত্তর যুক্ত করা হয়েছে, যা তৃতীয় স্থান অধিকার করেছে।

আপডেট (2013-01-15)

যুক্ত হয়েছে কোডসায়োস-এর বাইট ম্যানিপুলেশন উত্তর, যা প্রথম স্থান অধিকার করেছে (পাঠ্যের বৃহত ব্লকের উপর বৃহত্তর ব্যবধানে)।

আপডেট (2013-05-23)

নাথন মoinনভাজিরীর লুক উত্তর এবং ব্রায়ান ল্যামবার্টের ব্লগ থেকে বৈকল্পিক যুক্ত করা হয়েছে। উভয়ই বরং দ্রুত, তবে আমি যে পরীক্ষামূলক মেশিনটি ব্যবহার করেছি তার নেতৃত্ব নিচ্ছেন না (এএমডি ফেনোম 9750)।

আপডেট (2014-07-31)

যোগ করেছেন @ কোডসইনচাওসের নতুন বাইট-ভিত্তিক অনুসন্ধান উত্তর। এটি বাক্য পরীক্ষা এবং পূর্ণ-পাঠ্য পরীক্ষার উভয় ক্ষেত্রেই নেতৃত্ব নিয়েছে বলে মনে হয়।

আপডেট (2015-08-20)

যোগ করা হয়েছে airbreather এর অপ্টিমাইজেশন এবং unsafeবৈকল্পিক এই উত্তর এর রেপো । যদি আপনি অনিরাপদ খেলায় খেলতে চান তবে আপনি সংক্ষিপ্ত স্ট্রিং এবং বৃহত পাঠ্য উভয় ক্ষেত্রে পূর্বের শীর্ষ বিজয়ীদের যেকোনটির থেকে কিছু বিশাল পারফরম্যান্স লাভ করতে পারেন।


আপনি কি ওয়ালিদের উত্তর থেকে কোডটি পরীক্ষা করতে যত্নবান হবেন? এটি খুব দ্রুত বলে মনে হচ্ছে। stackoverflow.com/questions/311165/…
ক্রিশ্চিয়ান ডায়াকোনস্কু

5
আপনি নিজেরাই অনুরোধ করেছেন এমন কাজটি করার জন্য কোডটি আপনার কাছে উপলব্ধ করা সত্ত্বেও, ওয়ালিদ উত্তর অন্তর্ভুক্ত করার জন্য আমি পরীক্ষার কোডটি আপডেট করেছি। সমস্ত উদাসীনতা একপাশে, এটি অনেক দ্রুত।
পৃষ্ঠপোষক

2
পুনঃটুইট করেছেন এবং এটি আমার পরীক্ষাগুলিতেও বেশ খানিকটা জিতেছে। আমি এখনও শীর্ষ পদ্ধতির কোনওটি সম্পূর্ণরূপে বোঝার ভান করি না, তবে এগুলি সরাসরি সরাসরি মিথস্ক্রিয়া থেকে গোপন থাকে।
পৃষ্ঠপোষক

6
"প্রাকৃতিক" বা সাধারণ কোনটি এই প্রশ্নের উত্তর দেওয়ার কোনও উত্তর নেই এই উত্তরের। লক্ষ্যটি হ'ল মানুষকে কিছু প্রাথমিক পারফরম্যান্স মানদণ্ড দেওয়া, যেহেতু আপনাকে যখন এই রূপান্তরটি করা দরকার তখন আপনি তাদের অনেক কিছু করার প্রবণতা পান। কারও যদি কাঁচা গতির প্রয়োজন হয় তবে তারা কেবল তাদের কাঙ্ক্ষিত কম্পিউটিং পরিবেশে কিছু উপযুক্ত টেস্ট ডেটা দিয়ে মাপদণ্ড চালান। তারপরে, সেই পদ্ধতিটিকে কোনও এক্সটেনশন পদ্ধতিতে টেক করুন যেখানে আপনি এর প্রয়োগটি আর কখনও দেখতে পাবেন না (যেমন, bytes.ToHexStringAtLudicrousSpeed())।
পৃষ্ঠপোষক

2
সবেমাত্র একটি উচ্চ পারফরম্যান্স দেখার সারণী ভিত্তিক বাস্তবায়ন উত্পাদিত। এটির নিরাপদ রূপটি আমার সিপিইউতে থাকা বর্তমান নেতার চেয়ে প্রায় 30% দ্রুত faster অনিরাপদ রূপগুলি আরও দ্রুত faster stackoverflow.com/a/24343727/445517
CodesInChaos

244

সোপহেক্সবাইনারি নামে একটি বর্গ রয়েছে যা আপনি যা চান ঠিক তা করে।

using System.Runtime.Remoting.Metadata.W3cXsd2001;

public static byte[] GetStringToBytes(string value)
{
    SoapHexBinary shb = SoapHexBinary.Parse(value);
    return shb.Value;
}

public static string GetBytesToString(byte[] value)
{
    SoapHexBinary shb = new SoapHexBinary(value);
    return shb.ToString();
}

35
সোপহেক্সবাইনারি .NET 1.0 থেকে পাওয়া যায় এবং এটি এমএসসিআরলিবিতে থাকে। এটি মজার নাম সত্ত্বেও, প্রশ্নটি যা জিজ্ঞাসা করেছিল ঠিক তাই করে।
স্লি গ্রিফন

4
দুর্দান্ত খুঁজে! মনে রাখবেন যে অন্যান্য সমাধানের মতোই আপনাকে getStringToBytes এর জন্য শীর্ষস্থানীয় 0 দিয়ে বিজোড় স্ট্রিং প্যাড করতে হবে।
কার্টার মেডলিন

বাস্তবায়নের চিন্তাভাবনা দেখেছেন? গৃহীত উত্তরের একটি ভাল একটি আইএমএইচও রয়েছে।
mfloryan

6
এখানে মনো বাস্তবায়ন দেখতে আকর্ষণীয়: github.com/mono/mono/blob/master/mcs/class/corlib/…
জেরেমি

1
সোপহেক্সবাইনারি .NET কোর /। নেট স্ট্যান্ডার্ড ...
জুন ফায়ো 11:12

141

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

এটিও বেশ দ্রুত।

static string ByteToHexBitFiddle(byte[] bytes)
{
    char[] c = new char[bytes.Length * 2];
    int b;
    for (int i = 0; i < bytes.Length; i++) {
        b = bytes[i] >> 4;
        c[i * 2] = (char)(55 + b + (((b-10)>>31)&-7));
        b = bytes[i] & 0xF;
        c[i * 2 + 1] = (char)(55 + b + (((b-10)>>31)&-7));
    }
    return new string(c);
}

ফাংলুই মিলিগ্রা'নাফ চথুলহু রুলিহ ওয়াগাহ'নাগল ফাটাগন


তোমরা যারা এখানে প্রবেশ কর, সমস্ত আশা ত্যাগ কর

অদ্ভুত বিট ফিডিংয়ের ব্যাখ্যা:

  1. bytes[i] >> 4একটি বাইটের উচ্চ স্তনবৃন্ত নিষ্কাশন করে একটি বাইটের
    bytes[i] & 0xFনীচু স্তবক নিষ্কাশন করে
  2. b - 10
    হয় < 0মানের জন্য b < 10, যা পরিণত হবে একটি দশমিক অঙ্ক
    হয় >= 0মানের জন্য b > 10, যা থেকে একটি চিঠি হয়ে যাবে Aথেকে F
  3. i >> 31একটি স্বাক্ষরিত 32 বিট পূর্ণসংখ্যার ব্যবহার করে সাইনটি এক্সট্রেনশনের জন্য ধন্যবাদ racts এটা -1জন্য i < 0এবং 0জন্য হবে i >= 0
  4. 2) এবং 3 এর সংমিশ্রণ, শোগুলি অক্ষরের জন্য এবং অঙ্কগুলির জন্য (b-10)>>31হবে ।0-1
  5. চিঠির জন্য কেসটি দেখে, শেষ সমান হয়ে যায় 0এবং bএটি 10 ​​থেকে 15 এর মধ্যে থাকে We আমরা এটি A(65) থেকে F(70) এ মানচিত্র করতে চাই , যা 55 ( 'A'-10) যুক্ত করে বোঝায় ।
  6. অঙ্কগুলির ক্ষেত্রে কেসটি দেখে, আমরা সর্বশেষ সমষ্টিটি মানিয়ে নিতে চাই যাতে এটি b0 থেকে 9 পরিসীমা 0(48) থেকে 9(57) পর্যন্ত মানচিত্র করে । এর অর্থ এটি -7 ( '0' - 55) হওয়া দরকার।
    এখন আমরা কেবল with এর সাথে গুণ করতে পারি But তবে -1 যেহেতু সমস্ত বিট 1 এর প্রতিনিধিত্ব করে তাই আমরা এর পরিবর্তে এবং & -7পরে ব্যবহার করতে পারি ।(0 & -7) == 0(-1 & -7) == -7

আরও কিছু বিবেচনা:

  • আমি সূচকটিতে দ্বিতীয় লুপ ভেরিয়েবল ব্যবহার করিনি c, যেহেতু পরিমাপ দেখায় যে এ থেকে গণনা iকরা সস্তা।
  • i < bytes.Lengthলুপের ঠিক উপরের সীমানা হিসাবে ব্যবহার করা জিটটারকে সীমাবদ্ধ চেকগুলি অপসারণ করতে দেয় bytes[i], সুতরাং আমি সেই বৈকল্পিকটি বেছে নিয়েছি।
  • bকোন int তৈরি করা বাইট থেকে এবং অপ্রয়োজনীয় রূপান্তরগুলির অনুমতি দেয়।

10
আর hex stringকরার byte[] array?
এএএ

15
কালো জাদুতে এই বিট করার পরে আপনার উত্সটিকে সঠিকভাবে উদ্ধৃত করার জন্য +1। সব শিল চথুলহু।
এডওয়ার্ড

4
বাইট স্ট্রিং সম্পর্কে কি []?
সায়ফুল নিজাম ইয়াহইয়া

9
নিস! যাদের ছোট আউটপুট প্রয়োজন, তাদের স্পষ্টভাবে অভিব্যক্তিটি পরিবর্তিত হয়87 + b + (((b-10)>>31)&-39)
এক্সএভিয়ার

2
@ এএএ আপনি বলেছেন " byte[] array", যার আক্ষরিক অর্থ বাইট অ্যারে বা একটি অ্যারে byte[][]। আমি মজা করছি।
কুলঅপ্পো

97

আপনি যদি এর চেয়ে আরও নমনীয়তা BitConverterচান তবে সেই 1990-এর দশকের স্টাইলের স্পষ্ট লুপগুলি না চান তবে আপনি এটি করতে পারেন:

String.Join(String.Empty, Array.ConvertAll(bytes, x => x.ToString("X2")));

অথবা, আপনি। নেট 4.0 ব্যবহার করছেন:

String.Concat(Array.ConvertAll(bytes, x => x.ToString("X2")));

(মূল পোস্টে একটি মন্তব্য থেকে পরবর্তী।)


21
এমনকি আরও খাটো: স্ট্রিং.কনকাট (অ্যারে.কনভার্টএল (বাইটস, এক্স => এক্স.টোস্ট্রিং ("এক্স 2")))
নেস্টর

14
এমনকি সংক্ষিপ্ত: স্ট্রিং.কনকাট (বাইটস.সিলিট (বি => বি। টোস্ট্রিং ("এক্স 2"))) [। নেট 4]
অ্যালন গুরালেনেক

14
শুধু অর্ধেক প্রশ্নের উত্তর।
স্লি গ্রিফন

1
দ্বিতীয়টির কেন দরকার? নেট 4? স্ট্রিং.কনক্যাট। নেট 2.0 এ আছে।
পলিফুন

2
এই "90 এর স্টাইল" লুপগুলি সাধারণত দ্রুত হয় তবে একটি নগণ্য পর্যাপ্ত পরিমাণের দ্বারা এটি বেশিরভাগ প্রসঙ্গে বিবেচনা করে না। এখনও উল্লেখ করার মতো বিষয়
অস্টিন_অ্যান্ডারসন

69

অন্য দেখার টেবিল ভিত্তিক পদ্ধতির। এটি প্রতিটি বাইটের জন্য কেবলমাত্র এক টুকরো টেবিলের পরিবর্তে প্রতি বাইটের জন্য ব্যবহার করে।

private static readonly uint[] _lookup32 = CreateLookup32();

private static uint[] CreateLookup32()
{
    var result = new uint[256];
    for (int i = 0; i < 256; i++)
    {
        string s=i.ToString("X2");
        result[i] = ((uint)s[0]) + ((uint)s[1] << 16);
    }
    return result;
}

private static string ByteArrayToHexViaLookup32(byte[] bytes)
{
    var lookup32 = _lookup32;
    var result = new char[bytes.Length * 2];
    for (int i = 0; i < bytes.Length; i++)
    {
        var val = lookup32[bytes[i]];
        result[2*i] = (char)val;
        result[2*i + 1] = (char) (val >> 16);
    }
    return new string(result);
}

আমিও ব্যবহার করে এই এর রূপগুলো পরীক্ষিত ushort, struct{char X1, X2}, struct{byte X1, X2}লুকআপ টেবিলে।

সংকলন লক্ষ্য (x86, X64) উপর নির্ভর করে যাদের হয় প্রায় একই কর্মক্ষমতা ছিল বা এই বৈকল্পিকের তুলনায় কিছুটা ধীর ছিল।


এবং আরও উচ্চতর পারফরম্যান্সের জন্য, এর unsafeসহোদর:

private static readonly uint[] _lookup32Unsafe = CreateLookup32Unsafe();
private static readonly uint* _lookup32UnsafeP = (uint*)GCHandle.Alloc(_lookup32Unsafe,GCHandleType.Pinned).AddrOfPinnedObject();

private static uint[] CreateLookup32Unsafe()
{
    var result = new uint[256];
    for (int i = 0; i < 256; i++)
    {
        string s=i.ToString("X2");
        if(BitConverter.IsLittleEndian)
            result[i] = ((uint)s[0]) + ((uint)s[1] << 16);
        else
            result[i] = ((uint)s[1]) + ((uint)s[0] << 16);
    }
    return result;
}

public static string ByteArrayToHexViaLookup32Unsafe(byte[] bytes)
{
    var lookupP = _lookup32UnsafeP;
    var result = new char[bytes.Length * 2];
    fixed(byte* bytesP = bytes)
    fixed (char* resultP = result)
    {
        uint* resultP2 = (uint*)resultP;
        for (int i = 0; i < bytes.Length; i++)
        {
            resultP2[i] = lookupP[bytesP[i]];
        }
    }
    return new string(result);
}

অথবা আপনি যদি স্ট্রিংয়ে সরাসরি লিখতে গ্রহণযোগ্য মনে করেন:

public static string ByteArrayToHexViaLookup32UnsafeDirect(byte[] bytes)
{
    var lookupP = _lookup32UnsafeP;
    var result = new string((char)0, bytes.Length * 2);
    fixed (byte* bytesP = bytes)
    fixed (char* resultP = result)
    {
        uint* resultP2 = (uint*)resultP;
        for (int i = 0; i < bytes.Length; i++)
        {
            resultP2[i] = lookupP[bytesP[i]];
        }
    }
    return result;
}

অনিরাপদ সংস্করণে অনুসন্ধানের টেবিলটি তৈরি করা পূর্বরূপিত বাইটের নিবলগুলিও অদলবদল করে? আমি ভেবেছিলাম এডিয়েননেস কেবলমাত্র একাধিক বাইট দ্বারা গঠিত সত্তাগুলির ক্রম পরিবর্তন করেছে।
রাইফ আতেফ

@ রাইফএফফ এখানে গুরুত্বপূর্ণ বিষয়গুলি নীবলের ক্রম নয়। তবে 32 বিট পূর্ণসংখ্যায় 16 বিট শব্দের ক্রম। তবে আমি এটি পুনরায় লেখার বিষয়ে বিবেচনা করছি যাতে একই কোডটি শেষের দিক বিবেচনা না করে চলতে পারে।
কোডসইনচাউস

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

4
এটি প্রশ্নের অর্ধেক উত্তর দেয় ... হেক্স স্ট্রিং থেকে বাইট পর্যন্ত কীভাবে?
নার্ভালেক্স

3
@ কোডসআইএনচওস আমি ভাবছি যে Spanএখনকার পরিবর্তে এখন ব্যবহার করা যায় কিনা unsafe??
Konrad

64

আপনি BitConverter.ToString পদ্ধতি ব্যবহার করতে পারেন:

byte[] bytes = {0, 1, 2, 4, 8, 16, 32, 64, 128, 256}
Console.WriteLine( BitConverter.ToString(bytes));

আউটপুট:

00-01-02-04-08-10-20-40-80-মুক্তিযোদ্ধা

আরও তথ্য: বিটকনভার্টার.টস্ট্রিং পদ্ধতি (বাইট []]


14
শুধু অর্ধেক প্রশ্নের উত্তর।
স্লি গ্রিফন

3
উত্তরের দ্বিতীয় অংশটি কোথায়?
সাওয়ান

56

আমি আজ খুব একই সমস্যার মুখোমুখি হয়েছি এবং আমি এই কোডটি পেয়েছি:

private static string ByteArrayToHex(byte[] barray)
{
    char[] c = new char[barray.Length * 2];
    byte b;
    for (int i = 0; i < barray.Length; ++i)
    {
        b = ((byte)(barray[i] >> 4));
        c[i * 2] = (char)(b > 9 ? b + 0x37 : b + 0x30);
        b = ((byte)(barray[i] & 0xF));
        c[i * 2 + 1] = (char)(b > 9 ? b + 0x37 : b + 0x30);
    }
    return new string(c);
}

উত্স: ফোরামের পোস্ট বাইট [] অ্যারে টু হেক্স স্ট্রিং (পিজেহরার পোস্টটি দেখুন)। 0x উপসর্গটি সরাতে আমি কোডটি কিছুটা পরিবর্তন করেছি।

আমি কোডটিতে কিছু পারফরম্যান্স টেস্টিং করেছি এবং এটি বিটকনভার্টার.টস্ট্রিং () (প্যাট্রিজের পোস্ট অনুসারে দ্রুততম) ব্যবহার করার চেয়ে প্রায় আট গুণ বেশি দ্রুত ছিল।


এটি স্বল্পতম স্মৃতি ব্যবহার করে তা উল্লেখ করার দরকার নেই। কোনও মধ্যবর্তী স্ট্রিং যা তৈরি হয়নি।
চৌচোস

8
শুধু অর্ধেক প্রশ্নের উত্তর।
স্লি গ্রিফন

এটি দুর্দান্ত কারণ এটি NETMF সহ মূলত NET এর যে কোনও সংস্করণে কাজ করে। একটি বিজয়ী!
জোনসোম পুনরায় ইনস্টল করুন মনিকা

1
গৃহীত উত্তরটি 2 টি দুর্দান্ত হেক্সটোবাইটআরয়ের পদ্ধতি সরবরাহ করে, যা প্রশ্নের অন্য অর্ধেককে উপস্থাপন করে। ওয়ালিদের সমাধান প্রক্রিয়াটিতে বিশাল সংখ্যক স্ট্রিং তৈরি না করে এটি কীভাবে করা যায় তার চলমান প্রশ্নের উত্তর দেয়।
ব্রেন্ডেন একস্টেড্ট

নতুন স্ট্রিং (গ) অনুলিপি করে পুনরায় বরাদ্দ দেয় বা এটি কেবল চরটি মোড়ক করতে পারে যখন তা জানার পক্ষে যথেষ্ট স্মার্ট []?
jjxtra

19

এই একটি উত্তর সংস্করণ 4 এর Tomalak এর অত্যন্ত জনপ্রিয় উত্তর (এবং পরবর্তী সম্পাদনাগুলি)।

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

tl; dr: কেবলমাত্র ব্যবহার করুন Convert.ToByteএবং String.Substringআপনি যদি তাড়াহুড়োয় হন (নীচে "মূল কোড"), আপনি যদি পুনরায় প্রয়োগ করতে না চান তবে এটি সেরা সমন্বয় Convert.ToByte। আরও উন্নত কিছু ব্যবহার করুন (অন্যান্য উত্তর দেখুন) যা Convert.ToByteআপনার কর্মক্ষমতা প্রয়োজন হলে ব্যবহার করে না । এই উত্তরের মন্তব্যে কারও কাছে এটি সম্পর্কে আগ্রহী কিছু বলার অপেক্ষা রাখে না , তবে সম্মিলন ব্যতীত অন্য কিছু ব্যবহার করবেন নাString.SubstringConvert.ToByte

সতর্কতা: যদি কোনও Convert.ToByte(char[], Int32)ফ্রেমওয়ার্কে ওভারলোড প্রয়োগ করা হয় তবে এই উত্তরটি অপ্রচলিত হতে পারে । এটি শীঘ্রই হওয়ার সম্ভাবনা নেই।

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

আসল কোড:

    public static byte[] HexadecimalStringToByteArray_Original(string input)
    {
        var outputLength = input.Length / 2;
        var output = new byte[outputLength];
        for (var i = 0; i < outputLength; i++)
            output[i] = Convert.ToByte(input.Substring(i * 2, 2), 16);
        return output;
    }

রিভিশন 4:

    public static byte[] HexadecimalStringToByteArray_Rev4(string input)
    {
        var outputLength = input.Length / 2;
        var output = new byte[outputLength];
        using (var sr = new StringReader(input))
        {
            for (var i = 0; i < outputLength; i++)
                output[i] = Convert.ToByte(new string(new char[2] { (char)sr.Read(), (char)sr.Read() }), 16);
        }
        return output;
    }

রিভিশন এড়াতে String.Substringএবং StringReaderপরিবর্তে ব্যবহার করে। প্রদত্ত কারণ:

সম্পাদনা করুন: আপনি একক পাস পার্সার ব্যবহার করে দীর্ঘ স্ট্রিংগুলির জন্য পারফরম্যান্স উন্নত করতে পারেন:

ভাল, এর জন্য রেফারেন্স কোডটিরString.Substring দিকে তাকানো , এটি ইতিমধ্যে পরিষ্কারভাবে "সিঙ্গল-পাস"; এবং কেন এটি করা উচিত নয়? এটি সারোগেট জোড়িতে নয়, বাইট-লেভেলতে পরিচালনা করে।

এটি তবে একটি নতুন স্ট্রিং বরাদ্দ করে না, তবে তার পরে আপনাকে যে Convert.ToByteকোনও উপায়ে যেতে বরাদ্দ দেওয়া দরকার । তদুপরি, সংশোধনীতে প্রদত্ত সমাধানটি প্রতিটি পুনরাবৃত্তির (দ্বি-চর অ্যারে) আরও একটি বস্তু বরাদ্দ করে; আপনি নিরাপদে সেই বরাদ্দটি লুপের বাইরে রাখতে পারেন এবং এড়াতে অ্যারেটিকে পুনরায় ব্যবহার করতে পারেন।

    public static byte[] HexadecimalStringToByteArray(string input)
    {
        var outputLength = input.Length / 2;
        var output = new byte[outputLength];
        var numeral = new char[2];
        using (var sr = new StringReader(input))
        {
            for (var i = 0; i < outputLength; i++)
            {
                numeral[0] = (char)sr.Read();
                numeral[1] = (char)sr.Read();
                output[i] = Convert.ToByte(new string(numeral), 16);
            }
        }
        return output;
    }

প্রতিটি হেক্সাডেসিমাল numeralদুটি অঙ্ক (প্রতীক) ব্যবহার করে একটি একক অক্টেট উপস্থাপন করে।

তবে, কেন StringReader.Readদুবার ফোন করবেন ? কেবল এটির দ্বিতীয় ওভারলোডটি কল করুন এবং একবারে দুটি-চর অ্যারেতে দুটি অক্ষর পড়তে বলুন; এবং কলগুলির পরিমাণ দুই দ্বারা হ্রাস করুন।

    public static byte[] HexadecimalStringToByteArray(string input)
    {
        var outputLength = input.Length / 2;
        var output = new byte[outputLength];
        var numeral = new char[2];
        using (var sr = new StringReader(input))
        {
            for (var i = 0; i < outputLength; i++)
            {
                var read = sr.Read(numeral, 0, 2);
                Debug.Assert(read == 2);
                output[i] = Convert.ToByte(new string(numeral), 16);
            }
        }
        return output;
    }

আপনি যা রেখে গেছেন তা হ'ল একটি স্ট্রিং রিডার যা কেবলমাত্র যুক্ত হওয়া "মান" একটি সমান্তরাল সূচক (অভ্যন্তরীণ _pos) যা আপনি নিজেকে ঘোষণা করতে পারতেন ( jউদাহরণস্বরূপ), একটি অতিরিক্ত রিয়েলান্টেন্ট দৈর্ঘ্যের পরিবর্তনশীল (অভ্যন্তরীণ _length) এবং ইনপুটটির অপ্রয়োজনীয় উল্লেখ স্ট্রিং (অভ্যন্তরীণ _s)। অন্য কথায়, এটি অকেজো।

যদি আপনি কীভাবে Read"পড়েন" অবাক হন, কেবল কোডটি দেখুন , এটির সমস্তই String.CopyToইনপুট স্ট্রিংটিতে কল করা। বাকিটি কেবল আমাদের প্রয়োজনীয় মূল্যবোধ বজায় রাখতে বইয়ের উপরের হেডহেড।

সুতরাং, স্ট্রিং রিডারটি ইতিমধ্যে মুছে ফেলুন এবং CopyToনিজেকে কল করুন; এটি সহজ, পরিষ্কার এবং আরও দক্ষ।

    public static byte[] HexadecimalStringToByteArray(string input)
    {
        var outputLength = input.Length / 2;
        var output = new byte[outputLength];
        var numeral = new char[2];
        for (int i = 0, j = 0; i < outputLength; i++, j += 2)
        {
            input.CopyTo(j, numeral, 0, 2);
            output[i] = Convert.ToByte(new string(numeral), 16);
        }
        return output;
    }

আপনার কি সত্যিই jএমন একটি সূচি প্রয়োজন যা দুটি সমান্তরাল ধাপে বৃদ্ধি পায় i? অবশ্যই তা নয়, কেবল iদুটি দ্বারা গুণ করুন (যা সংকলক একটি সংযোজনকে অনুকূল করতে সক্ষম হবে)।

    public static byte[] HexadecimalStringToByteArray_BestEffort(string input)
    {
        var outputLength = input.Length / 2;
        var output = new byte[outputLength];
        var numeral = new char[2];
        for (int i = 0; i < outputLength; i++)
        {
            input.CopyTo(i * 2, numeral, 0, 2);
            output[i] = Convert.ToByte(new string(numeral), 16);
        }
        return output;
    }

সমাধানটি এখন দেখতে কেমন? ঠিক যেমন এটি শুরুতে ছিল ঠিক তেমন String.Substringস্ট্রিং বরাদ্দ করার জন্য এবং এতে ডেটা অনুলিপি করার পরিবর্তে , আপনি একটি মধ্যস্থ অ্যারে ব্যবহার করছেন যেখানে আপনি হেক্সাডেসিমাল সংখ্যাগুলি অনুলিপি করেছেন, তারপরে নিজেই স্ট্রিং বরাদ্দ করুন এবং এ থেকে আবার ডেটা অনুলিপি করুন অ্যারে এবং স্ট্রিংয়ের মধ্যে (যখন আপনি স্ট্রিং কনস্ট্রাক্টারে পাস করবেন)। দ্বিতীয় কপিটি ইতিমধ্যে উপযুক্ত হতে পারে যদি স্ট্রিং ইতিমধ্যে ইন্টার্ন পুলে থাকে তবে তবে String.Substringএই ক্ষেত্রে এটি এড়াতে সক্ষম হবে।

প্রকৃতপক্ষে, আপনি যদি String.Substringআবার তাকান , আপনি দেখতে পাবেন যে এটি স্ট্রিংগুলি সাধারণভাবে সম্পাদন করার চেয়ে দ্রুততরভাবে বরাদ্দ করতে কীভাবে স্ট্রিংগুলি তৈরি করা হয় তার কিছু অভ্যন্তরীণ জ্ঞান ব্যবহার করে এবং এটি CopyToএড়াতে সরাসরি সেখানে ব্যবহৃত একই কোডটিকে ইনলাইন করে lines কল ওভারহেড

String.Substring

  • সবচেয়ে খারাপ ক্ষেত্রে: একটি দ্রুত বরাদ্দ, একটি দ্রুত অনুলিপি।
  • সেরা ক্ষেত্রে: কোন বরাদ্দ, কোন অনুলিপি।

ম্যানুয়াল পদ্ধতি

  • সবচেয়ে খারাপ ক্ষেত্রে: দুটি সাধারণ বরাদ্দ, একটি সাধারণ অনুলিপি, একটি দ্রুত অনুলিপি।
  • সেরা ক্ষেত্রে: একটি সাধারণ বরাদ্দ, একটি সাধারণ অনুলিপি।

উপসংহার? আপনি যদি ব্যবহার করতে চানConvert.ToByte(String, Int32) (কারণ আপনি নিজেই সেই কার্যকারিতাটি পুনরায় বাস্তবায়ন করতে চান না), মারার উপায় নেই বলে মনে হয় String.Substring; আপনার যা কিছু করা হয় তা চেনাশোনাগুলিতে চালিত হয়, চাকাটি পুনরায় উদ্ভাবন করা হয় (কেবল উপ-অনুকূল উপকরণ সহ)।

মনে রাখবেন যে আপনার চূড়ান্ত পারফরম্যান্সের প্রয়োজন না হলে ব্যবহার করা Convert.ToByteএবং String.Substringএটি পুরোপুরি বৈধ পছন্দ। মনে রাখবেন: কেবলমাত্র কোনও বিকল্পের বিকল্প বেছে নিন যদি আপনার কাছে কীভাবে এটি সঠিকভাবে কাজ করে তা খতিয়ে দেখার সময় এবং সংস্থান রয়েছে।

যদি একটি থাকে Convert.ToByte(char[], Int32), তবে অবশ্যই জিনিসগুলি আলাদা হবে (আমি উপরে বর্ণিত যা করা সম্ভব এবং সম্পূর্ণভাবে এড়ানো সম্ভব হবে String)।

আমার সন্দেহ হয় যে "এড়ানো String.Substring" দ্বারা আরও ভাল পারফরম্যান্সের প্রতিবেদন করা লোকেরাও এড়ানো যায় Convert.ToByte(String, Int32), যা আপনার যেভাবেই পারফরম্যান্সের প্রয়োজন হলে আপনার করা উচিত। এটি করতে সমস্ত বিভিন্ন পদ্ধতির আবিষ্কার করতে অগণিত অন্যান্য উত্তরগুলি দেখুন।

দাবি অস্বীকার: রেফারেন্স উত্সটি আপ-টু-ডেট রয়েছে তা যাচাই করার জন্য আমি ফ্রেমওয়ার্কের সর্বশেষ সংস্করণটি ছিন্ন করে নিই না, আমি ধরে নিই।

এখন, এগুলি সমস্ত ভাল এবং যৌক্তিক শোনায়, আশা করা যায় এমনকি আপনি যদি এখনও পর্যন্ত পরিচালনা করতে সক্ষম হন তবে সুস্পষ্টও। তবে এটা কি সত্য?

Intel(R) Core(TM) i7-3720QM CPU @ 2.60GHz
    Cores: 8
    Current Clock Speed: 2600
    Max Clock Speed: 2600
--------------------
Parsing hexadecimal string into an array of bytes
--------------------
HexadecimalStringToByteArray_Original: 7,777.09 average ticks (over 10000 runs), 1.2X
HexadecimalStringToByteArray_BestEffort: 8,550.82 average ticks (over 10000 runs), 1.1X
HexadecimalStringToByteArray_Rev4: 9,218.03 average ticks (over 10000 runs), 1.0X

হ্যাঁ!

বেঞ্চ কাঠামোর জন্য পার্ট্রিজের প্রপস, এটি হ্যাক করা সহজ। ব্যবহৃত ইনপুটটি হ'ল 100,000 বাইট দীর্ঘ স্ট্রিং তৈরি করতে নিম্নলিখিত SHA-1 হ্যাশটি 5000 বার পুনরাবৃত্তি করা হয়েছে।

209113288F93A9AB8E474EA78D899AFDBB874355

আনন্দ কর! (তবে সংযম সহ অপ্টিমাইজ করুন))


ত্রুটি: {"কোনও সনাক্তযোগ্য অঙ্ক খুঁজে পাওয়া যায়নি" "}
প্রিয়া জগতাপ

17

@ কোডসআইএনচাউস (বিপরীত পদ্ধতি) দ্বারা উত্তর দেওয়ার পরিপূরক

public static byte[] HexToByteUsingByteManipulation(string s)
{
    byte[] bytes = new byte[s.Length / 2];
    for (int i = 0; i < bytes.Length; i++)
    {
        int hi = s[i*2] - 65;
        hi = hi + 10 + ((hi >> 31) & 7);

        int lo = s[i*2 + 1] - 65;
        lo = lo + 10 + ((lo >> 31) & 7) & 0x0f;

        bytes[i] = (byte) (lo | hi << 4);
    }
    return bytes;
}

ব্যাখ্যা:

& 0x0f ছোট হাতের অক্ষরকে সমর্থন করা support

hi = hi + 10 + ((hi >> 31) & 7); হিসাবে একই:

hi = ch-65 + 10 + (((ch-65) >> 31) & 7);

'0' .. '9' এর জন্য এটি hi = ch - 65 + 10 + 7;যা একই রকম hi = ch - 48(এটি এর কারণে 0xffffffff & 7)।

'এ' এর জন্য .. 'এফ' এটি hi = ch - 65 + 10;(এটি এর কারণে 0x00000000 & 7)।

'একটি' .. 'চ' এর জন্য আমরা বড় সংখ্যা আছে তাই আমরা কিছু বিট করে ডিফল্ট সংস্করণ থেকে 32 বিয়োগ আবশ্যক 0ব্যবহার করে & 0x0f

65 কোড জন্য 'A'

48 এর জন্য কোড '0'

7 হ'ল ASCII সারণীতে ( ) এর মধ্যে '9'এবং এর 'A'মধ্যে থাকা বর্ণগুলির সংখ্যা ...456789:;<=>?@ABCD...


16

এই চেহারাটি লুকে আপ টেবিল ব্যবহার করেও সমাধান করা যেতে পারে। এটির জন্য এনকোডার এবং ডিকোডার উভয়ের জন্য অল্প পরিমাণে স্থির মেমরির প্রয়োজন হবে। এই পদ্ধতিটি তবে দ্রুত হবে:

  • এনকোডার সারণী 512 বাইট বা 1024 বাইট (উচ্চ এবং নিম্ন উভয় ক্ষেত্রে প্রয়োজন হলে আকারের দ্বিগুণ)
  • ডিকোডার সারণী 256 বাইট বা 64 কিবি (হয় একক চর চেহারা বা দ্বৈত চর চেহারা)

আমার দ্রবণটি এনকোডিং টেবিলের জন্য 1024 বাইট এবং ডিকোডিংয়ের জন্য 256 বাইট ব্যবহার করে।

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

private static readonly byte[] LookupTable = new byte[] {
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};

private static byte Lookup(char c)
{
  var b = LookupTable[c];
  if (b == 255)
    throw new IOException("Expected a hex character, got " + c);
  return b;
}

public static byte ToByte(char[] chars, int offset)
{
  return (byte)(Lookup(chars[offset]) << 4 | Lookup(chars[offset + 1]));
}

এনকোডিং

private static readonly char[][] LookupTableUpper;
private static readonly char[][] LookupTableLower;

static Hex()
{
  LookupTableLower = new char[256][];
  LookupTableUpper = new char[256][];
  for (var i = 0; i < 256; i++)
  {
    LookupTableLower[i] = i.ToString("x2").ToCharArray();
    LookupTableUpper[i] = i.ToString("X2").ToCharArray();
  }
}

public static char[] ToCharLower(byte[] b, int bOffset)
{
  return LookupTableLower[b[bOffset]];
}

public static char[] ToCharUpper(byte[] b, int bOffset)
{
  return LookupTableUpper[b[bOffset]];
}

তুলনা

StringBuilderToStringFromBytes:   106148
BitConverterToStringFromBytes:     15783
ArrayConvertAllToStringFromBytes:  54290
ByteManipulationToCharArray:        8444
TableBasedToCharArray:              5651 *

* এই সমাধান

বিঃদ্রঃ

ডিকোডিংয়ের সময় আইওএক্সেপশন এবং ইনডেক্সআউটআউটফ্রেঞ্জএক্সসেপশন ঘটতে পারে (যদি কোনও চরিত্রের খুব বেশি মান থাকে> 256)। ডি / এনকোডিং স্ট্রিম বা অ্যারেগুলির জন্য পদ্ধতিগুলি প্রয়োগ করা উচিত, এটি কেবল ধারণার প্রমাণ।


2
আপনি যখন সিএলআরতে কোড চালান তখন 256 বাইটের মেমরির ব্যবহার নগণ্য।
ডলম্যান

9

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

private byte[] HexStringToByteArray(string hexString)
{
    int hexStringLength = hexString.Length;
    byte[] b = new byte[hexStringLength / 2];
    for (int i = 0; i < hexStringLength; i += 2)
    {
        int topChar = (hexString[i] > 0x40 ? hexString[i] - 0x37 : hexString[i] - 0x30) << 4;
        int bottomChar = hexString[i + 1] > 0x40 ? hexString[i + 1] - 0x37 : hexString[i + 1] - 0x30;
        b[i / 2] = Convert.ToByte(topChar + bottomChar);
    }
    return b;
}

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

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

3
রূপান্তর করুন। টোবাইট (শীর্ষচর + নীচেচর) (বাইট) (শীর্ষচর + নীচেচর) হিসাবে লেখা যেতে পারে
আমির

একটি বৃহত পারফরম্যান্স জরিমানা ছাড়াই উভয় ক্ষেত্রে পরিচালনা করতেhexString[i] &= ~0x20;
বেন ভয়েগট

9

কেন এটি জটিল? এটি ভিজ্যুয়াল স্টুডিও ২০০৮-তে সহজ:

সি #:

string hex = BitConverter.ToString(YourByteArray).Replace("-", "");

ভিবি:

Dim hex As String = BitConverter.ToString(YourByteArray).Replace("-", "")

2
কারণটি হল কর্মক্ষমতা, যখন আপনার উচ্চ পারফরম্যান্স সমাধানের প্রয়োজন হয়। :)
রিকি

7

এখানে প্রচুর উত্তরের সন্ধান করতে নয়, তবে আমি হ্যাক্স স্ট্রিং পার্সারটির সহজবোধ্য বাস্তবায়ন (মোটামুটি অনুকূল) (স্বীকৃতের চেয়ে ~ 4.5x ভাল) পেয়েছি। প্রথমত, আমার পরীক্ষাগুলি থেকে আউটপুট (প্রথম ব্যাচটি আমার বাস্তবায়ন):

Give me that string:
04c63f7842740c77e545bb0b2ade90b384f119f6ab57b680b7aa575a2f40939f

Time to parse 100,000 times: 50.4192 ms
Result as base64: BMY/eEJ0DHflRbsLKt6Qs4TxGfarV7aAt6pXWi9Ak58=
BitConverter'd: 04-C6-3F-78-42-74-0C-77-E5-45-BB-0B-2A-DE-90-B3-84-F1-19-F6-AB-5
7-B6-80-B7-AA-57-5A-2F-40-93-9F

Accepted answer: (StringToByteArray)
Time to parse 100000 times: 233.1264ms
Result as base64: BMY/eEJ0DHflRbsLKt6Qs4TxGfarV7aAt6pXWi9Ak58=
BitConverter'd: 04-C6-3F-78-42-74-0C-77-E5-45-BB-0B-2A-DE-90-B3-84-F1-19-F6-AB-5
7-B6-80-B7-AA-57-5A-2F-40-93-9F

With Mono's implementation:
Time to parse 100000 times: 777.2544ms
Result as base64: BMY/eEJ0DHflRbsLKt6Qs4TxGfarV7aAt6pXWi9Ak58=
BitConverter'd: 04-C6-3F-78-42-74-0C-77-E5-45-BB-0B-2A-DE-90-B3-84-F1-19-F6-AB-5
7-B6-80-B7-AA-57-5A-2F-40-93-9F

With SoapHexBinary:
Time to parse 100000 times: 845.1456ms
Result as base64: BMY/eEJ0DHflRbsLKt6Qs4TxGfarV7aAt6pXWi9Ak58=
BitConverter'd: 04-C6-3F-78-42-74-0C-77-E5-45-BB-0B-2A-DE-90-B3-84-F1-19-F6-AB-5
7-B6-80-B7-AA-57-5A-2F-40-93-9F

নির্ভুলতার জন্য পরীক্ষার জন্য বেস 64 এবং 'বিটকনভার্টার'ড' লাইন রয়েছে। তারা সমান নোট করুন।

রুপায়ণ:

public static byte[] ToByteArrayFromHex(string hexString)
{
  if (hexString.Length % 2 != 0) throw new ArgumentException("String must have an even length");
  var array = new byte[hexString.Length / 2];
  for (int i = 0; i < hexString.Length; i += 2)
  {
    array[i/2] = ByteFromTwoChars(hexString[i], hexString[i + 1]);
  }
  return array;
}

private static byte ByteFromTwoChars(char p, char p_2)
{
  byte ret;
  if (p <= '9' && p >= '0')
  {
    ret = (byte) ((p - '0') << 4);
  }
  else if (p <= 'f' && p >= 'a')
  {
    ret = (byte) ((p - 'a' + 10) << 4);
  }
  else if (p <= 'F' && p >= 'A')
  {
    ret = (byte) ((p - 'A' + 10) << 4);
  } else throw new ArgumentException("Char is not a hex digit: " + p,"p");

  if (p_2 <= '9' && p_2 >= '0')
  {
    ret |= (byte) ((p_2 - '0'));
  }
  else if (p_2 <= 'f' && p_2 >= 'a')
  {
    ret |= (byte) ((p_2 - 'a' + 10));
  }
  else if (p_2 <= 'F' && p_2 >= 'A')
  {
    ret |= (byte) ((p_2 - 'A' + 10));
  } else throw new ArgumentException("Char is not a hex digit: " + p_2, "p_2");

  return ret;
}

আমি কিছু স্টাফ চেষ্টা করেছি unsafeএবং (স্পষ্টভাবে অপ্রয়োজনীয়) চরিত্র থেকে নিবিল ক্রমটিকে ifঅন্য পদ্ধতিতে সরিয়ে নিয়েছি , তবে এটি এটি সবচেয়ে দ্রুততম ছিল।

(আমি স্বীকার করি যে এটি অর্ধেক প্রশ্নের জবাব দিয়েছে I আমি অনুভব করেছি যে স্ট্রিং-> বাইট [] রূপান্তরটি নীচে উপস্থাপিত হয়েছে, বাইট [] -> স্ট্রিং কোণটি ভালভাবে আবৃত বলে মনে হচ্ছে Thus সুতরাং, এই উত্তরটি))


1
নুথের অনুসারীদের জন্য: আমি এটি করেছি কারণ প্রতি কয়েক মিনিট বা তার পরে আমার কয়েক হাজার হেক্স স্ট্রিং পার্স করা দরকার, সুতরাং এটি যত তাড়াতাড়ি সম্ভব (অভ্যন্তরীণ লুপে, এটি যেমন ছিল) তত গুরুত্বপূর্ণ important টমলকের দ্রবণগুলি উল্লেখযোগ্যভাবে ধীর হয় না যদি এমন অনেকগুলি পার্স না ঘটে।
বেন মোশার

5

নিরাপদ সংস্করণ:

public static class HexHelper
{
    [System.Diagnostics.Contracts.Pure]
    public static string ToHex(this byte[] value)
    {
        if (value == null)
            throw new ArgumentNullException("value");

        const string hexAlphabet = @"0123456789ABCDEF";

        var chars = new char[checked(value.Length * 2)];
        unchecked
        {
            for (int i = 0; i < value.Length; i++)
            {
                chars[i * 2] = hexAlphabet[value[i] >> 4];
                chars[i * 2 + 1] = hexAlphabet[value[i] & 0xF];
            }
        }
        return new string(chars);
    }

    [System.Diagnostics.Contracts.Pure]
    public static byte[] FromHex(this string value)
    {
        if (value == null)
            throw new ArgumentNullException("value");
        if (value.Length % 2 != 0)
            throw new ArgumentException("Hexadecimal value length must be even.", "value");

        unchecked
        {
            byte[] result = new byte[value.Length / 2];
            for (int i = 0; i < result.Length; i++)
            {
                // 0(48) - 9(57) -> 0 - 9
                // A(65) - F(70) -> 10 - 15
                int b = value[i * 2]; // High 4 bits.
                int val = ((b - '0') + ((('9' - b) >> 31) & -7)) << 4;
                b = value[i * 2 + 1]; // Low 4 bits.
                val += (b - '0') + ((('9' - b) >> 31) & -7);
                result[i] = checked((byte)val);
            }
            return result;
        }
    }
}

অনিরাপদ সংস্করণ তাদের জন্য যারা পারফরম্যান্স পছন্দ করেন এবং অস্পষ্টতা থেকে ভয় পান না। ToHex প্রায় 35% দ্রুত এবং fromHex থেকে 10% দ্রুত।

public static class HexUnsafeHelper
{
    [System.Diagnostics.Contracts.Pure]
    public static unsafe string ToHex(this byte[] value)
    {
        if (value == null)
            throw new ArgumentNullException("value");

        const string alphabet = @"0123456789ABCDEF";

        string result = new string(' ', checked(value.Length * 2));
        fixed (char* alphabetPtr = alphabet)
        fixed (char* resultPtr = result)
        {
            char* ptr = resultPtr;
            unchecked
            {
                for (int i = 0; i < value.Length; i++)
                {
                    *ptr++ = *(alphabetPtr + (value[i] >> 4));
                    *ptr++ = *(alphabetPtr + (value[i] & 0xF));
                }
            }
        }
        return result;
    }

    [System.Diagnostics.Contracts.Pure]
    public static unsafe byte[] FromHex(this string value)
    {
        if (value == null)
            throw new ArgumentNullException("value");
        if (value.Length % 2 != 0)
            throw new ArgumentException("Hexadecimal value length must be even.", "value");

        unchecked
        {
            byte[] result = new byte[value.Length / 2];
            fixed (char* valuePtr = value)
            {
                char* valPtr = valuePtr;
                for (int i = 0; i < result.Length; i++)
                {
                    // 0(48) - 9(57) -> 0 - 9
                    // A(65) - F(70) -> 10 - 15
                    int b = *valPtr++; // High 4 bits.
                    int val = ((b - '0') + ((('9' - b) >> 31) & -7)) << 4;
                    b = *valPtr++; // Low 4 bits.
                    val += (b - '0') + ((('9' - b) >> 31) & -7);
                    result[i] = checked((byte)val);
                }
            }
            return result;
        }
    }
}

BTW বর্ণমালার পরীক্ষার জন্য বর্ণমালা পরীক্ষার জন্য প্রতিবার রূপান্তরিত ফাংশন হিসাবে ভুল বলা হয়, বর্ণমালা অবশ্যই কনস্ট (স্ট্রিংয়ের জন্য) বা স্ট্যাটিক রিডনলি (চর [] এর জন্য) হতে হবে। তারপরে বাইটের বর্ণমালা ভিত্তিক রূপান্তর [] স্ট্রিংয়ে বাইট ম্যানিপুলেশন সংস্করণগুলির মতো দ্রুত হয়ে যায়।

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


5

ওয়ালিদ আইসা কোডের জন্য বিপরীত ফাংশন (হেক্স স্ট্রিং টু বাইট অ্যারে):

    public static byte[] HexToBytes(this string hexString)        
    {
        byte[] b = new byte[hexString.Length / 2];            
        char c;
        for (int i = 0; i < hexString.Length / 2; i++)
        {
            c = hexString[i * 2];
            b[i] = (byte)((c < 0x40 ? c - 0x30 : (c < 0x47 ? c - 0x37 : c - 0x57)) << 4);
            c = hexString[i * 2 + 1];
            b[i] += (byte)(c < 0x40 ? c - 0x30 : (c < 0x47 ? c - 0x37 : c - 0x57));
        }

        return b;
    }

লোয়ার কেস সাপোর্ট সহ ওয়ালিদ আইসা ফাংশন:

    public static string BytesToHex(this byte[] barray, bool toLowerCase = true)
    {
        byte addByte = 0x37;
        if (toLowerCase) addByte = 0x57;
        char[] c = new char[barray.Length * 2];
        byte b;
        for (int i = 0; i < barray.Length; ++i)
        {
            b = ((byte)(barray[i] >> 4));
            c[i * 2] = (char)(b > 9 ? b + addByte : b + 0x30);
            b = ((byte)(barray[i] & 0xF));
            c[i * 2 + 1] = (char)(b > 9 ? b + addByte : b + 0x30);
        }

        return new string(c);
    }

4

সম্প্রসারণ পদ্ধতি (দাবি অস্বীকার: সম্পূর্ণরূপে অনির্ধারিত কোড, বিটিডাব্লু ...):

public static class ByteExtensions
{
    public static string ToHexString(this byte[] ba)
    {
        StringBuilder hex = new StringBuilder(ba.Length * 2);

        foreach (byte b in ba)
        {
            hex.AppendFormat("{0:x2}", b);
        }
        return hex.ToString();
    }
}

ইত্যাদি .. টমলকের তিনটি সমাধানের মধ্যে দুটিই ব্যবহার করুন (সর্বশেষে স্ট্রিংটিতে এক্সটেনশন পদ্ধতি হ'ল)।


কোডটির আগে এই জাতীয় প্রশ্নের আগে প্রস্তাব দেওয়ার আগে আপনার সম্ভবত পরীক্ষা করা উচিত।
jww

3

মাইক্রোসফ্ট এর বিকাশকারীদের কাছ থেকে, একটি দুর্দান্ত, সাধারণ রূপান্তর:

public static string ByteArrayToString(byte[] ba) 
{
    // Concatenate the bytes into one long string
    return ba.Aggregate(new StringBuilder(32),
                            (sb, b) => sb.Append(b.ToString("X2"))
                            ).ToString();
}

উপরেরটি পরিষ্কার এবং কমপ্যাক্ট থাকলেও পারফরম্যান্স জাঙ্কিরা এটির গণক ব্যবহার করে চিৎকার করবে। তোমালকের মূল উত্তরের উন্নত সংস্করণ দিয়ে আপনি শিখর পারফরম্যান্স পেতে পারেন :

public static string ByteArrayToString(byte[] ba)   
{   
   StringBuilder hex = new StringBuilder(ba.Length * 2);   

   for(int i=0; i < ba.Length; i++)       // <-- Use for loop is faster than foreach   
       hex.Append(ba[i].ToString("X2"));   // <-- ToString is faster than AppendFormat   

   return hex.ToString();   
} 

আমি এখন পর্যন্ত এখানে পোস্ট করা সমস্ত রুটিনগুলির মধ্যে এটি দ্রুততম। এটির জন্য কেবল আমার শব্দটি গ্রহণ করবেন না ... প্রতিটি রুটিনের পারফরম্যান্স পরীক্ষা করুন এবং এর জন্য নিজের সিআইএল কোডটি পরীক্ষা করুন।


2
পুনরুক্তি এই কোডের প্রধান সমস্যা নয়। আপনার উচিত মানদণ্ড b.ToSting("X2")
ডলমেন

2

এবং একটি এসকিউএল স্ট্রিং serোকানোর জন্য (আপনি যদি কমান্ড প্যারামিটার ব্যবহার না করেন):

public static String ByteArrayToSQLHexString(byte[] Source)
{
    return = "0x" + BitConverter.ToString(Source).Replace("-", "");
}

যদি Source == nullবা Source.Length == 0আমরা একটি সমস্যা স্যার!
Andrei Krasutski

2

গতির দিক থেকে এটি এখানে যে কোনও কিছুর চেয়ে ভাল বলে মনে হচ্ছে:

  public static string ToHexString(byte[] data) {
    byte b;
    int i, j, k;
    int l = data.Length;
    char[] r = new char[l * 2];
    for (i = 0, j = 0; i < l; ++i) {
      b = data[i];
      k = b >> 4;
      r[j++] = (char)(k > 9 ? k + 0x37 : k + 0x30);
      k = b & 15;
      r[j++] = (char)(k > 9 ? k + 0x37 : k + 0x30);
    }
    return new string(r);
  }

2

আপনি যে কোডটি কাজ করার পরামর্শ দিয়েছিলেন তা আমি পাইনি, অলিপ্রো। hex[i] + hex[i+1]স্পষ্টতই একটি ফিরে int

তবে আমি ওয়ালিডস কোড থেকে কিছু ইঙ্গিত নিয়ে এবং এটি এক সাথে হাতুড়ি করে কিছু সাফল্য পেয়েছি। এটি জাহান্নামের মতো কুৎসিত তবে এটি আমার পরীক্ষাগুলি অনুসারে অন্যদের তুলনায় (প্যাট্রিজ টেস্টিং মেকানিজম ব্যবহার করে) 1/3 সময় কাজ করে বলে মনে হয়। ইনপুট আকারের উপর নির্ভর করে। প্রথমে 0-9 আলাদা করতে?: S এর চারপাশে স্যুইচিংয়ের ফলে সম্ভবত কিছুটা দ্রুত ফলাফল পাওয়া যাবে যেহেতু অক্ষরের চেয়ে বেশি সংখ্যা রয়েছে।

public static byte[] StringToByteArray2(string hex)
{
    byte[] bytes = new byte[hex.Length/2];
    int bl = bytes.Length;
    for (int i = 0; i < bl; ++i)
    {
        bytes[i] = (byte)((hex[2 * i] > 'F' ? hex[2 * i] - 0x57 : hex[2 * i] > '9' ? hex[2 * i] - 0x37 : hex[2 * i] - 0x30) << 4);
        bytes[i] |= (byte)(hex[2 * i + 1] > 'F' ? hex[2 * i + 1] - 0x57 : hex[2 * i + 1] > '9' ? hex[2 * i + 1] - 0x37 : hex[2 * i + 1] - 0x30);
    }
    return bytes;
}

2

বাইটআরারিটোহেক্সভিয়াবাাইটমেনিপুলেশনের এই সংস্করণটি আরও দ্রুত হতে পারে।

আমার রিপোর্ট থেকে:

  • বাইটআরারিটোহেক্সভিয়া বাইটমনিপুলেশন 3: 1,68 গড় টিক্স (1000 রানেরও বেশি), 17,5X
  • বাইটআরারিওহেক্সভায়া বাইটমনিপুলেশন 2: 1,73 গড় টিক্স (1000 রানের বেশি), 16,9X
  • বাইটআরারিটোহেক্সভায়া বাইটমনিপুলেশন: ২,৯০ গড় টিক্স (১০০০ রানের বেশি), 10,1 এক্স
  • বাইটআরারিটোহেক্সভিয়া লাকআপঅ্যান্ড শিফট: ৩,২২২ টি গড় টিক্স (১০০০ রানের বেশি), 9,1 এক্স
  • ...

    static private readonly char[] hexAlphabet = new char[]
        {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    static string ByteArrayToHexViaByteManipulation3(byte[] bytes)
    {
        char[] c = new char[bytes.Length * 2];
        byte b;
        for (int i = 0; i < bytes.Length; i++)
        {
            b = ((byte)(bytes[i] >> 4));
            c[i * 2] = hexAlphabet[b];
            b = ((byte)(bytes[i] & 0xF));
            c[i * 2 + 1] = hexAlphabet[b];
        }
        return new string(c);
    }

এবং আমি মনে করি এটি একটি অপ্টিমাইজেশন:

    static private readonly char[] hexAlphabet = new char[]
        {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    static string ByteArrayToHexViaByteManipulation4(byte[] bytes)
    {
        char[] c = new char[bytes.Length * 2];
        for (int i = 0, ptr = 0; i < bytes.Length; i++, ptr += 2)
        {
            byte b = bytes[i];
            c[ptr] = hexAlphabet[b >> 4];
            c[ptr + 1] = hexAlphabet[b & 0xF];
        }
        return new string(c);
    }

2

আমি এই বিট ফিডলিং প্রতিযোগিতায় প্রবেশ করবো কারণ আমার কাছে একটি উত্তর রয়েছে যা হেক্সাডেসিমালগুলি ডিকোড করতে বিট-ফিডলিং ব্যবহার করে । নোট করুন যে ক্যারেক্টার অ্যারেগুলি ব্যবহার করা আরও ত্বরান্বিত হতে পারে কারণ কলিং StringBuilderপদ্ধতিগুলি পাশাপাশি সময় নিতে পারে।

public static String ToHex (byte[] data)
{
    int dataLength = data.Length;
    // pre-create the stringbuilder using the length of the data * 2, precisely enough
    StringBuilder sb = new StringBuilder (dataLength * 2);
    for (int i = 0; i < dataLength; i++) {
        int b = data [i];

        // check using calculation over bits to see if first tuple is a letter
        // isLetter is zero if it is a digit, 1 if it is a letter
        int isLetter = (b >> 7) & ((b >> 6) | (b >> 5)) & 1;

        // calculate the code using a multiplication to make up the difference between
        // a digit character and an alphanumerical character
        int code = '0' + ((b >> 4) & 0xF) + isLetter * ('A' - '9' - 1);
        // now append the result, after casting the code point to a character
        sb.Append ((Char)code);

        // do the same with the lower (less significant) tuple
        isLetter = (b >> 3) & ((b >> 2) | (b >> 1)) & 1;
        code = '0' + (b & 0xF) + isLetter * ('A' - '9' - 1);
        sb.Append ((Char)code);
    }
    return sb.ToString ();
}

public static byte[] FromHex (String hex)
{

    // pre-create the array
    int resultLength = hex.Length / 2;
    byte[] result = new byte[resultLength];
    // set validity = 0 (0 = valid, anything else is not valid)
    int validity = 0;
    int c, isLetter, value, validDigitStruct, validDigit, validLetterStruct, validLetter;
    for (int i = 0, hexOffset = 0; i < resultLength; i++, hexOffset += 2) {
        c = hex [hexOffset];

        // check using calculation over bits to see if first char is a letter
        // isLetter is zero if it is a digit, 1 if it is a letter (upper & lowercase)
        isLetter = (c >> 6) & 1;

        // calculate the tuple value using a multiplication to make up the difference between
        // a digit character and an alphanumerical character
        // minus 1 for the fact that the letters are not zero based
        value = ((c & 0xF) + isLetter * (-1 + 10)) << 4;

        // check validity of all the other bits
        validity |= c >> 7; // changed to >>, maybe not OK, use UInt?

        validDigitStruct = (c & 0x30) ^ 0x30;
        validDigit = ((c & 0x8) >> 3) * (c & 0x6);
        validity |= (isLetter ^ 1) * (validDigitStruct | validDigit);

        validLetterStruct = c & 0x18;
        validLetter = (((c - 1) & 0x4) >> 2) * ((c - 1) & 0x2);
        validity |= isLetter * (validLetterStruct | validLetter);

        // do the same with the lower (less significant) tuple
        c = hex [hexOffset + 1];
        isLetter = (c >> 6) & 1;
        value ^= (c & 0xF) + isLetter * (-1 + 10);
        result [i] = (byte)value;

        // check validity of all the other bits
        validity |= c >> 7; // changed to >>, maybe not OK, use UInt?

        validDigitStruct = (c & 0x30) ^ 0x30;
        validDigit = ((c & 0x8) >> 3) * (c & 0x6);
        validity |= (isLetter ^ 1) * (validDigitStruct | validDigit);

        validLetterStruct = c & 0x18;
        validLetter = (((c - 1) & 0x4) >> 2) * ((c - 1) & 0x2);
        validity |= isLetter * (validLetterStruct | validLetter);
    }

    if (validity != 0) {
        throw new ArgumentException ("Hexadecimal encoding incorrect for input " + hex);
    }

    return result;
}

জাভা কোড থেকে রূপান্তরিত।


হুম, আমার সত্যই Char[]Char
এটির

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

2

পারফরম্যান্সের জন্য আমি ড্রফ্রোজেন সলিউশন সহ যাব। ডিকোডারটির জন্য একটি ক্ষুদ্রতর অপ্টিমাইজেশন হ'ল "<< 4" থেকে মুক্তি পাওয়ার জন্য উভয় চরের জন্য একটি টেবিল ব্যবহার করা।

স্পষ্টতই দুটি পদ্ধতির কল ব্যয়বহুল। যদি ইনপুট বা আউটপুট ডেটাতে কোনও ধরণের চেক তৈরি করা হয় (সিআরসি, চেকসাম বা যে কোনও if (b == 255)...কিছু হতে পারে ) বাদ দেওয়া যেতে পারে এবং এর ফলে পদ্ধতিটি পুরোপুরি কল করে।

এর পরিবর্তে offset++এবং এর offsetপরিবর্তে offsetএবং offset + 1কিছু তাত্ত্বিক সুবিধা দিতে পারে তবে আমার সন্দেহ হয় যে সংকলকটি এটি আমার চেয়ে ভাল পরিচালনা করে।

private static readonly byte[] LookupTableLow = new byte[] {
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};

private static readonly byte[] LookupTableHigh = new byte[] {
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};

private static byte LookupLow(char c)
{
  var b = LookupTableLow[c];
  if (b == 255)
    throw new IOException("Expected a hex character, got " + c);
  return b;
}

private static byte LookupHigh(char c)
{
  var b = LookupTableHigh[c];
  if (b == 255)
    throw new IOException("Expected a hex character, got " + c);
  return b;
}

public static byte ToByte(char[] chars, int offset)
{
  return (byte)(LookupHigh(chars[offset++]) | LookupLow(chars[offset]));
}

এটি আমার মাথার উপরের অংশের বাইরে এবং পরীক্ষা বা বেঞ্চমার্ক করা হয়নি।


1

বৈচিত্র্যের জন্য আরও একটি ভিন্নতা:

public static byte[] FromHexString(string src)
{
    if (String.IsNullOrEmpty(src))
        return null;

    int index = src.Length;
    int sz = index / 2;
    if (sz <= 0)
        return null;

    byte[] rc = new byte[sz];

    while (--sz >= 0)
    {
        char lo = src[--index];
        char hi = src[--index];

        rc[sz] = (byte)(
            (
                (hi >= '0' && hi <= '9') ? hi - '0' :
                (hi >= 'a' && hi <= 'f') ? hi - 'a' + 10 :
                (hi >= 'A' && hi <= 'F') ? hi - 'A' + 10 :
                0
            )
            << 4 | 
            (
                (lo >= '0' && lo <= '9') ? lo - '0' :
                (lo >= 'a' && lo <= 'f') ? lo - 'a' + 10 :
                (lo >= 'A' && lo <= 'F') ? lo - 'A' + 10 :
                0
            )
        );
    }

    return rc;          
}

1

গতির জন্য অপ্টিমাইজড নয়, তবে বেশিরভাগ উত্তরের চেয়ে লিনকুই (। নেট 4.0):

<Extension()>
Public Function FromHexToByteArray(hex As String) As Byte()
    hex = If(hex, String.Empty)
    If hex.Length Mod 2 = 1 Then hex = "0" & hex
    Return Enumerable.Range(0, hex.Length \ 2).Select(Function(i) Convert.ToByte(hex.Substring(i * 2, 2), 16)).ToArray
End Function

<Extension()>
Public Function ToHexString(bytes As IEnumerable(Of Byte)) As String
    Return String.Concat(bytes.Select(Function(b) b.ToString("X2")))
End Function

1

দুটি ম্যাসআপ যা দুটি স্তম্ভিত অপারেশনগুলিকে একটিতে ভাঁজ করে।

সম্ভবত বেশ দক্ষ সংস্করণ:

public static string ByteArrayToString2(byte[] ba)
{
    char[] c = new char[ba.Length * 2];
    for( int i = 0; i < ba.Length * 2; ++i)
    {
        byte b = (byte)((ba[i>>1] >> 4*((i&1)^1)) & 0xF);
        c[i] = (char)(55 + b + (((b-10)>>31)&-7));
    }
    return new string( c );
}

বিট-হ্যাকিং সংস্করণ সহ অবক্ষয়যুক্ত লিনাক:

public static string ByteArrayToString(byte[] ba)
{
    return string.Concat( ba.SelectMany( b => new int[] { b >> 4, b & 0xF }).Select( b => (char)(55 + b + (((b-10)>>31)&-7))) );
}

এবং বিপরীত:

public static byte[] HexStringToByteArray( string s )
{
    byte[] ab = new byte[s.Length>>1];
    for( int i = 0; i < s.Length; i++ )
    {
        int b = s[i];
        b = (b - '0') + ((('9' - b)>>31)&-7);
        ab[i>>1] |= (byte)(b << 4*((i&1)^1));
    }
    return ab;
}

1
HexStringToByteArray ("09") 0x02 ফিরিয়ে দেয় যা খারাপ
কোপারনিক

1

অন্য উপায় হ'ল stackallocজিসি মেমরির চাপ কমাতে ব্যবহার করা:

static string ByteToHexBitFiddle(byte[] bytes)
{
        var c = stackalloc char[bytes.Length * 2 + 1];
        int b; 
        for (int i = 0; i < bytes.Length; ++i)
        {
            b = bytes[i] >> 4;
            c[i * 2] = (char)(55 + b + (((b - 10) >> 31) & -7));
            b = bytes[i] & 0xF;
            c[i * 2 + 1] = (char)(55 + b + (((b - 10) >> 31) & -7));
        }
        c[bytes.Length * 2 ] = '\0';
        return new string(c);
}

1

এটি আমার শট এখানে। স্ট্রিং এবং বাইট বাড়ানোর জন্য আমি একজোড়া এক্সটেনশন ক্লাস তৈরি করেছি। বড় ফাইল পরীক্ষায়, সম্পাদনাটি বাইট ম্যানিপুলেশন 2 এর সাথে তুলনীয়।

ToHexString এর জন্য নীচের কোডটি লুকিং এবং শিফট অ্যালগরিদমের একটি অনুকূলিত বাস্তবায়ন। এটা তোলে Behrooz পর এক প্রায় অভিন্ন, কিন্তু এটা একটা ব্যবহার সক্রিয় আউট foreachপুনরুক্তি করতে এবং একটি পাল্টা দ্রুত একটি স্পষ্টভাবে ইন্ডেক্স চেয়ে for

এটি আমার মেশিনে বাইট ম্যানিপুলেশন 2 এর পিছনে ২ য় স্থানে আসে এবং এটি খুব পঠনযোগ্য কোড। নিম্নলিখিত পরীক্ষার ফলাফলগুলিও আগ্রহের বিষয়:

টোহেক্সস্ট্রিংচরআরেউইথচরআর্রলুকআপ: ৪১,৫৯.6..6৯ গড় টিক্স (১০০০ রানেরও বেশি), 1.5X টোহেক্সস্ট্রিংচরআরে উইথস্ট্রিংলুকআপ: ৫০,764.0.০6 গড় টিক্স (১০০০ রানেরও বেশি), ১.২ এক্স টুহেক্সস্ট্রিং স্ট্রিংবিল্ডারথিক্র্যাচআরচিক্সিয়াস ৮০০, ৮০০, ৮০০, ৮০০, ৮০০, ৪০০, ৪০০, ওভারক্লুকআপ: tic২,

উপরের ফলাফলগুলির উপর ভিত্তি করে এই সিদ্ধান্তে পৌঁছানো নিরাপদ বলে মনে হচ্ছে:

  1. বড় ফাইল পরীক্ষায় বনাম একটি চরের অ্যারে তৈরির জন্য স্ট্রিংয়ে ইনডেক্স করার জন্য জরিমানাগুলি উল্লেখযোগ্য।
  2. স্ট্রিং তৈরির জন্য পরিচিত আকারের একটি পরিচিত অ্যারে বনাম পরিচিত স্ট্রিংবিল্ডার ব্যবহারের জরিমানা আরও তাত্পর্যপূর্ণ।

কোডটি এখানে:

using System;

namespace ConversionExtensions
{
    public static class ByteArrayExtensions
    {
        private readonly static char[] digits = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

        public static string ToHexString(this byte[] bytes)
        {
            char[] hex = new char[bytes.Length * 2];
            int index = 0;

            foreach (byte b in bytes)
            {
                hex[index++] = digits[b >> 4];
                hex[index++] = digits[b & 0x0F];
            }

            return new string(hex);
        }
    }
}


using System;
using System.IO;

namespace ConversionExtensions
{
    public static class StringExtensions
    {
        public static byte[] ToBytes(this string hexString)
        {
            if (!string.IsNullOrEmpty(hexString) && hexString.Length % 2 != 0)
            {
                throw new FormatException("Hexadecimal string must not be empty and must contain an even number of digits to be valid.");
            }

            hexString = hexString.ToUpperInvariant();
            byte[] data = new byte[hexString.Length / 2];

            for (int index = 0; index < hexString.Length; index += 2)
            {
                int highDigitValue = hexString[index] <= '9' ? hexString[index] - '0' : hexString[index] - 'A' + 10;
                int lowDigitValue = hexString[index + 1] <= '9' ? hexString[index + 1] - '0' : hexString[index + 1] - 'A' + 10;

                if (highDigitValue < 0 || lowDigitValue < 0 || highDigitValue > 15 || lowDigitValue > 15)
                {
                    throw new FormatException("An invalid digit was encountered. Valid hexadecimal digits are 0-9 and A-F.");
                }
                else
                {
                    byte value = (byte)((highDigitValue << 4) | (lowDigitValue & 0x0F));
                    data[index / 2] = value;
                }
            }

            return data;
        }
    }
}

নীচে আমি পরীক্ষার ফলাফলগুলি পেয়েছি যা যখন আমি আমার মেশিনে @ প্যাট্রিজের পরীক্ষামূলক প্রকল্পে আমার কোডটি রাখি। আমি হেক্সাডেসিমাল থেকে বাইট অ্যারে রূপান্তর করার জন্য একটি পরীক্ষাও যুক্ত করেছি। আমার কোডটি ব্যবহার করে এমন পরীক্ষাগুলি হ'ল বাইটআর্রেটিওহেক্সভিয়াঅপটিমাইজডলুকআপঅ্যান্ডশিফ্ট এবং হেক্সটোবাইটআরাইভিয়াবাাইটমনিপুলেশন। HexToByteArrayViaConvertToByte XXXXX থেকে নেওয়া হয়েছিল। @ মাইক্রফ্টের উত্তর থেকে হেক্সটোবাইটআরাইভিয়াসোপাএইচএক্সএক্সইবাইনারিটিই এটি।

ইন্টেল পেন্টিয়াম তৃতীয় জিওন প্রসেসর

    Cores: 4 <br/>
    Current Clock Speed: 1576 <br/>
    Max Clock Speed: 3092 <br/>

বাইটের অ্যারেকে হেক্সাডেসিমাল স্ট্রিং উপস্থাপনায় রূপান্তর করা


বাইটআর্রেটিওহেক্সভিয়াবাাইটমনিপুলেশন 2: 39,366.64 গড় টিক্স (1000 রানেরও বেশি), 22.4X

বাইটআরারিটোহেক্সভিয়াঅ্যাপ্টিমাইজড লকআপঅ্যান্ড শিফট: 41,588.64 গড় টিক্স (1000 রানের বেশি), 21.2X

বাইটআরারিটোহেক্সভিয়া লুকআপ: 55,509.56 গড় টিক্স (1000 রানের বেশি), 15.9X

বাইটআর্রেটিওহেক্সভায়া বাইটমনিপুলেশন: 65,349.12 গড় টিক্স (1000 রানের বেশি), 13.5X

বাইটআরারিটোহেক্সভিয়া লাকআপঅ্যান্ড শিফট: 86,926.87 গড় টিক্স (1000 রানেরও বেশি), 10.2X

বাইটআর্রেটিওহেক্স স্ট্রিংভিয়াবিটকনভার্টার: 139,353.73 গড় টিক্স (1000 রানেরও বেশি), 6.3X

বাইটআর্রেটিওহেক্সভিয়াসোপএইচএইচবাইনারি: 314,598.77 গড় টিক্স (1000 রানেরও বেশি), 2.8X

বাইটআর্রেটিওহেক্স স্ট্রিংভিয়া স্ট্রিং বিল্ডার ফরএচবিটাইটোস্ট্রিং: 344,264.63 গড় টিক্স (1000 রানেরও বেশি), 2.6X

বাইটআর্রেটিওহেক্স স্ট্রিংভিয়া স্ট্রিংবিল্ডার অগ্রিগ্রেটবাইটটোস্ট্রিং: 382,623.44 গড় টিক্স (1000 রানেরও বেশি), 2.3X

বাইটআর্রেটিওহেক্স স্ট্রিংভিয়া স্ট্রিংবিল্ডারফোচ এপ অ্যাপেন্ডফর্ম্যাট: 818,111.95 গড় টিক্স (1000 রানেরও বেশি), 1.1 এক্স

বাইটআর্রেটিওহেক্স স্ট্রিংভিয়া স্ট্রিংকনক্যাটআরাই কনভার্টএল: 839,244.84 গড় টিক্স (1000 রানেরও বেশি), 1.1 এক্স

বাইটআর্রেটিওহেক্স স্ট্রিংভিয়া স্ট্রিংবিল্ডার অগ্রিগেট অ্যাপেন্ডেন্ট ফর্ম্যাট: 867,303.98 গড় টিক্স (1000 রানেরও বেশি), 1.0X

বাইটআর্রেটিওহেক্স স্ট্রিংভিয়া স্ট্রিংজইনআরাই কনভার্টএল: 882,710.28 গড় টিক্স (1000 রানেরও বেশি), 1.0X



1

আর একটি দ্রুত কাজ ...

private static readonly byte[] HexNibble = new byte[] {
    0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
    0x8, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x0,
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF
};

public static byte[] HexStringToByteArray( string str )
{
    int byteCount = str.Length >> 1;
    byte[] result = new byte[byteCount + (str.Length & 1)];
    for( int i = 0; i < byteCount; i++ )
        result[i] = (byte) (HexNibble[str[i << 1] - 48] << 4 | HexNibble[str[(i << 1) + 1] - 48]);
    if( (str.Length & 1) != 0 )
        result[byteCount] = (byte) HexNibble[str[str.Length - 1] - 48];
    return result;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.