2009-08-23 90 views
128

我需要將int轉換爲byte[]這樣做的一種方式是使用BitConverter.GetBytes()。但即時通訊不確定如果滿足以下規格相匹配:C#int to byte []

的XDR符號整數是32位數據,在 範圍[-2147483648,2147483647]編碼的整數。整數用 表示補碼錶示法。最高和最低有效字節分別爲 0和3。整數聲明如下:

來源:RFC1014 3.2

我怎麼可以做的int字節改造將滿足上述規範?

+0

這是一個很好的問題。 – ChaosPandion 2009-08-23 16:25:36

回答

168

RFC只是試圖說一個有符號的整數是一個正常的4字節整數,字節以big-endian方式排序。

現在,你很可能在一個小端機器上工作,並且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; 
+3

或使用ToArray。 byte [] result = BitConverter.GetBytes(intValue).Reverse()。ToArray(); – 2011-11-20 21:05:19

19

BitConverter.GetBytes(int)幾乎你想要做什麼,除了字節順序是錯誤的。

可以使用IPAddress.HostToNetwork方法使用BitConverter.GetBytes之前互換整數值中的字節或使用喬恩斯基特的EndianBitConverter class。這兩種方法在可移植性方面做了正確的事情(tm)。

int value; 
byte[] bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(value)); 
3

當我看到這個說明,我有一種感覺,這XDR整數只是一個大端「標準」的整數,但它是最模糊的方式表達。我們更熟悉U2,這是我們在今天的處理器上使用的。字節順序表示它是一個big-endian表示法。
所以,回答你的問題,你應該顛倒你的數組中的元素(0 < - > 3,1 < - > 2),因爲它們是用小端編碼的。爲了確保,您應該首先檢查BitConverter.IsLittleEndian以查看您正在運行的機器。

2

如果您想了解代表,包括二的補數的各種方法的一般信息看看:在維基百科上

30

這裏

Two's ComplementSigned Number Representation另一種方式來做到這一點:大家都知道1個字節= 8x位,並且「常規」整數(int32)包含32位(4字節)。我們可以用>>操作符右移位數(>>操作不會改變值。)

int intValue = 566; 

byte[] bytes = new byte[4]; 

bytes[0] = (byte)(intValue >> 24); 
bytes[1] = (byte)(intValue >> 16); 
bytes[2] = (byte)(intValue >> 8); 
bytes[3] = (byte)intValue; 

Console.WriteLine("{0} breaks down to : {1} {2} {3} {4}", 
    intValue, bytes[0], bytes[1], bytes[2], bytes[3]); 
+0

數組初始化器和xor(^)和'&0xFF'位是不必要的。 – dtb 2009-08-23 16:42:59

+0

是的,但我只是想展示它是如何工作的 – Maciek 2009-08-23 16:43:48

+5

它是big-endian,所以MSB首先被存儲,所以你應該反轉你的索引。 – 2009-08-23 16:44:17

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

請添加更多的解釋 – 2018-02-21 22:51:04

+0

感謝您的回答,爲什麼會選擇使用https://stackoverflow.com/a/1318948/58553的寫一個新的實現呢? (是否有任何Pro或缺點與您的解決方案) – Peter 2018-02-22 07:37:44

+0

在情況下,當項目需要的不僅僅是一種語言來開發,它可以在形勢語言之間有用REALIZE代碼相似度時相同的想法必須得到執行。這種方式可能有助於捕捉錯誤。一定要使用「C#」功能「BitConverter.GetBytes」與「尾數」檢查所有需要的東西在大多數情況下。而且,在某些情況下,可能會發生不僅使用Int32(4字節)或Int64(8字節)而且使用其他字節數轉換的情況。謝謝。 – 2018-02-22 22:52:43

-1

爲什麼所有這些代碼上面的樣本中...

有顯式佈局一個結構的作用是雙向的,並沒有表現打

[StructLayout(LayoutKind.Explicit)] 
struct IntByte 
{ 
    [FieldOffset(0)] 
    public int IntVal; 

    [FieldOffset(0)] 
    public byte B0; 
    [FieldOffset(1)] 
    public byte B1; 
    [FieldOffset(2)] 
    public byte B2; 
    [FieldOffset(3)] 
    public byte B3; 
} 
+0

你會如何使用它?其次,你會得到相同的結果,即使你在'大端'和'小端'上運行。 – Peter 2018-03-05 13:37:22