c# - सी#int बाइट




.net bit-manipulation (5)

मुझे एक int को एक byte[] परिवर्तित करने की आवश्यकता है byte[] ऐसा करने का एक तरीका BitConverter.GetBytes() का उपयोग BitConverter.GetBytes() । लेकिन अगर मैं निम्नलिखित विनिर्देशों से मेल खाता हूं तो मुझे यकीन नहीं है:

एक एक्सडीआर हस्ताक्षर पूर्णांक 32-बिट डेटाम है जो सीमा [-2147483648,2147483647] में एक पूर्णांक को एन्कोड करता है। पूर्णांक दो पूरक पूरक में दर्शाया गया है। क्रमशः सबसे कम से कम महत्वपूर्ण बाइट 0 और 3 हैं। इंटीजर निम्नानुसार घोषित किए गए हैं:

स्रोत: RFC1014 3.2

मैं बाइट परिवर्तन के लिए एक int कैसे कर सकता हूं जो उपर्युक्त विनिर्देश को पूरा करेगा?


आरएफसी सिर्फ यह कहने की कोशिश कर रहा है कि एक हस्ताक्षरित पूर्णांक एक सामान्य 4-बाइट पूर्णांक है जो बाइट्स के साथ बड़े-बड़े तरीके से आदेश दिया जाता है।

अब, आप शायद एक छोटी-छोटी मशीन पर काम कर रहे हैं और BitConverter.GetBytes() आपको byte[] उलट देगा। तो आप कोशिश कर सकते हैं:

int intValue;
byte[] intBytes = BitConverter.GetBytes(intValue);
Array.Reverse(intBytes);
byte[] result = intBytes;

कोड को सबसे पोर्टेबल होने के लिए, हालांकि, आप इसे इस तरह से कर सकते हैं:

int intValue;
byte[] intBytes = BitConverter.GetBytes(intValue);
if (BitConverter.IsLittleEndian)
    Array.Reverse(intBytes);
byte[] result = intBytes;

उपरोक्त नमूने में यह सब कोड क्यों ...

स्पष्ट लेआउट वाला एक स्ट्रक्चर दोनों तरीकों से कार्य करता है और इसमें कोई प्रदर्शन हिट नहीं होता है।

अद्यतन: चूंकि अंतहीनता से निपटने के तरीके पर एक सवाल है, इसलिए मैंने एक इंटरफ़ेस जोड़ा जो बताता है कि उसे कैसे सारणीबद्ध किया जाए। एक और कार्यान्वयन संरचना विपरीत मामले से निपट सकती है

public interface IIntToByte
{
    Int32 Int { get; set;}

    byte B0 { get; }
    byte B1 { get; }
    byte B2 { get; }
    byte B3 { get; }
}

[StructLayout(LayoutKind.Explicit)]
public struct IntToByteLE : UserQuery.IIntToByte
{
    [FieldOffset(0)]
    public Int32 IntVal;

    [FieldOffset(0)]
    public byte b0;
    [FieldOffset(1)]
    public byte b1;
    [FieldOffset(2)]
    public byte b2;
    [FieldOffset(3)]
    public byte b3;

    public Int32 Int {
        get{ return IntVal; }
        set{ IntVal = value;}
    }

    public byte B0 => b0;
    public byte B1 => b0;
    public byte B2 => b0;
    public byte B3 => b0; 
}

जब मैं इस विवरण को देखता हूं, तो मुझे एहसास होता है कि यह xdr पूर्णांक केवल एक बड़ा-अंत "मानक" पूर्णांक है, लेकिन यह सबसे अधिक खराब तरीके से व्यक्त किया गया है। दो के पूरक नोटेशन को यू 2 के रूप में बेहतर तरीके से जाना जाता है, और आज हम प्रोसेसर पर इसका उपयोग कर रहे हैं। बाइट ऑर्डर इंगित करता है कि यह एक big-endian नोटेशन है।
तो, अपने प्रश्न का उत्तर दें, आपको अपने सरणी में तत्वों को उलटा करना चाहिए (0 <-> 3, 1 <-> 2), क्योंकि वे छोटे-अंत में एन्कोड किए गए हैं। बस यह सुनिश्चित करने के लिए, आपको पहले कौन सी मशीन चल रही है, यह देखने के लिए आपको BitConverter.IsLittleEndian जांच करनी चाहिए।


यदि आप दो के पूरक सहित संख्याओं का प्रतिनिधित्व करने के विभिन्न तरीकों के बारे में अधिक सामान्य जानकारी चाहते हैं तो इस पर एक नज़र डालें:

विकिपीडिया पर दो का पूरक और हस्ताक्षरित संख्या प्रतिनिधित्व


byte[] Take_Byte_Arr_From_Int(Int64 Source_Num)
{
   Int64 Int64_Num = Source_Num;
   byte Byte_Num;
   byte[] Byte_Arr = new byte[8];
   for (int i = 0; i < 8; i++)
   {
      if (Source_Num > 255)
      {
         Int64_Num = Source_Num / 256;
         Byte_Num = (byte)(Source_Num - Int64_Num * 256);
      }
      else
      {
         Byte_Num = (byte)Int64_Num;
         Int64_Num = 0;
      }
      Byte_Arr[i] = Byte_Num;
      Source_Num = Int64_Num;
   }
   return (Byte_Arr);
}




nfs