2009-08-25 94 views
4

我有一串數字,我想以二進制數據的形式發送到套接字連接上。將整數列表轉換爲python中的二進制「字符串」

作爲一個實例,我開始與以下列表:

data = [2,25,0,0,ALPHA,0,23,18,188] 

在上述列表中,ALPHA可以是1和999之間的任何值起初,我使用此轉換成一個字符串

hexdata = ''.join([chr(item) for item in data]) 

所以如果Alpha是101,這將返回以下字符串:

>>> data = [2,25,0,0,101,0,23,18,188] 
>>> hexdata = ''.join([chr(item) for item in data]) 
>>> hexdata 
'\x02\x19\x00\x00e\x00\x17\x12\xbc' 

這工作得很好,'\ x02 \ x19 \ x00 \ x00e \ x00 \ x17 \ x12 \ xbc'是我需要發出的字符串。

但是,這不會爲超過255 ALPHA值工作,因爲它出了CHR聲明的範圍。例如,如果ALPHA爲999的話,我想獲得以下字符串:

data = [2,25,0,0,999,0,23,18,188] 
hexdata = '\x02\x19\x00\x03\xed\x00\x17\x12\xbc' 

我一直在struct.pack(看文檔),但不能看到如何可以用來acheive上面的字符串。 ALPHA是列表中唯一的變量。

任何幫助將不勝感激。

編輯1

你想要什麼行爲? 256和65535之間的任何 佔用2個字節來表示 。你想解壓它在 對方嗎?請根據您的意願更新帖子 。 - gahooa 1分鐘前

那是正確的,因爲999是在256的閾值,它由兩個字節表示:

data = [2,25,0,0,999,0,23,18,188] 

hexdata = '\x02\x19\x00**\x03\xed**\x00\x17\x12\xbc' 

這是否有道理?

至於拆包而言,我只是出發送這個數據到插座,我將收到的數據,但多數民衆贊成採取已經照顧。

編輯2

我發送的字符串是總是固定長度。 爲簡單起見,我認爲它能夠更好地代表名單如下:

ALPHA = 101 

data = [25,alpha1,alpha2,1] 
hexdata = '\x19\x00e\x01' 


ALPHA = 301 

data = [25,alpha1,alpha2,1] 
hexdata = 'x19\x01\x2d\x01' 

,你可以在hexdata串看到,這個就變成了:\ X01 \ X2D \

如果ALPHA < 256,ALPHA1 = 0。

+2

你想要什麼行爲做? 256到65535之間的任何內容都需要2個字節來表示。你想在另一邊解開它嗎?請用* intent *更新信息。 – gahooa 2009-08-25 21:48:09

+0

'\ x03 \ xed'是1005的bigendian簡稱?你如何到達那個?也是\ x00打算缺少的那個? – 2009-08-25 21:59:18

+0

我強烈建議你爲數據包使用一個固定大小的記錄,它會使你的協議變得更簡單(並且由於對齊/打包問題,大小可能保持不變)。 – tonfa 2009-08-25 22:29:04

回答

9

您想爲ALPHA發送一個字節,如果是< 256,但如果> = 256兩個字節?這似乎很奇怪 - 接收器怎麼知道是哪種情況...?

但是,如果這是你想要的東西,然後

x = struct.pack(4*'B' + 'HB'[ALPHA<256] + 4*'B', *data) 

是實現這一目標的方法之一。

+0

謝謝亞歷克斯! 這似乎工作正常 – mozami 2009-08-25 22:16:09

+1

對於999的情況,這會產生'\ x02 \ x19 \ x00 \ x00 \ xe7 \ x03 \ x00 \ x17 \ x12 \ xbc'。注意兩個\ x00和錯誤的字節順序(至少在x86機器上)。 – 2009-08-25 22:23:19

+3

我建議使用big-endian,應該是每個網絡協議的情況(以避免任何意外)。 – tonfa 2009-08-25 22:26:58

3

您可以使用Python array

import array 
a = array.array('i') 
a.extend([2,25,0,0,101,0,23,18,188]) 
output = a.tostring() 
+2

雖然這不能回答可變寬度alpha通道的原始(奇怪)要求,但這對於我所需要的很有用。謝謝! – natevw 2012-11-04 00:25:41

1

字節的值不能超過255,所以當ALPHA超過255時,你將不得不將它分成兩個字節。這可以這樣完成:

high, low = divmod(ALPHA, 255) 

然後,您可以將高位和低位粘貼到值列表中。

還有其他的變化,如使用bytearray(在2.6)或struct.pack等,但最後你將不得不以某種方式轉換該數字兩個兩個字節。

5

如果您知道數據和ALPHA位置提前,這將是最好使用struct.pack與大端短的這一立場,並省略可能被改寫0:

def output(ALPHA): 
    data = [2,25,0,ALPHA,0,23,18,188] 
    format = ">BBBHBBBB" 
    return struct.pack(format, *data) 
output(101) # result: '\x02\x19\x00\x00e\x00\x17\x12\xbc' 
output(999) # result: '\x02\x19\x00\x03\xe7\x00\x17\x12\xbc' 
+0

謝謝! 這正是我正在尋找的! – mozami 2009-08-25 22:56:56

0

你想要爲ALPHA發送一個字節,如果它是< 256,但是如果> = 256則有兩個字節?

其它的(也許更通用)的方法是:

x = reduce(lambda x, y: x + y, map(lambda x: struct.pack('B', x), data)) 
相關問題