2012-09-11 41 views
1

我有一個字符串保存到一個數據庫中,該數據庫由Actionscript通過base64ing進行編碼,然後zlib將其壓縮。在python中從actionscript中讀取base64/zlib編碼的字符串

的示例串是這樣的: 「eNrj4mZkrShgWdHBx1mUmJfNosQIACUhBCI =」

如果我解壓並通過ActionScript聯合國的base64這一點,我得到了我期望:

{ 「XP」:656398, 「等級」:34 }

但是,我需要能夠讀取這個服務器端。目前我正在使用Python,但我會開放給一個有效的PHP解決方案或類似的。

所以在Python到目前爲止,我已經試過這樣:

import base64 
import zlib 

s = 'eNrj4mZkrShgWdHBx1mUmJfNosQIACUhBCI=' 

print s.decode("base64").decode("zlib") 

它看起來像的Actionscript增加了一些額外的比特到頭部,但我的Python是沒有強大到足以擊敗這個:)任何幫助將不勝感激!

編輯:動作腳本首先需要一個AS對象,並將其轉換爲ByteArray,之後zlib將其壓縮並base64ing它。它看起來像是生成額外的頭/損壞的數據信息。

+2

請再想一想,告訴我們100%的確定性:按照何種順序執行編碼?先是拉鍊,然後是b64運輸,或者反過來呢? –

回答

0

閃存可以重整這一點,但你應該如果您使用的是第三方庫共享

從ActionScript創建並檢查該數據的例子中,它可能如果你使用的是官方庫是使用備用字符集,比Python期待。

,似乎Actionscript以不同的方式實現UTF8和ascii(有不同的方法在這裏 - http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/utils/Base64Encoder.html

只是看到actionscript並注意是否存在庫或代碼的問題比試圖對此進行反向工程更容易。

我想這也可能是值得嘗試的反向修正錯誤這個...

import base64 
import zlib 

flash = "eNrj4mZkrShgWdHBx1mUmJfNosQIACUhBCI=" 

original = '{"xp": 656398, "rank": 34}' 
encoded = original.encode('zlib').encode('base64') 
decoded = encoded.decode('base64').decode('zlib') 
print original 
print encoded 
print decoded 

可我還想問你爲什麼連這樣做呢?

1-除非你的數據包更大,否則你不會節省很多帶寬。實際上,對小型有效載荷的壓縮實際上可以增加尺寸。假設這是基於網絡的,你應該可以讓服務器在運行中執行此操作。

+0

是的,我很確定Flash/actionscript是通過添加一些額外的字符來改變這一點,正如我原先所說的。我會嘗試找到用於編碼和發佈的精確的Actionscript代碼。 – Tosh

+0

爲了回答你的問題,是的,我們的大部分數據包都大得多。這是我能找到的最小的例子,但大多數未壓縮的數據包的大小是幾百kb。對於2,我們有數百萬行數據存檔,我們要轉換到一個新的系統,所以沒有實時系統來運行它。我可以構建一個AS查詢器,查詢數據庫中的字符串,讀取它們,然後重寫,但我真的希望用python來做這個服務器端。 – Tosh

+0

瞭解檔案 - 是的,這將是非常快速的蟒蛇。我擔心如果不使用閃存代碼,試圖弄清楚發生了什麼,會有很多痛苦。 flash可以使用不同的有效載荷,或者填充有效載荷,或者可以編碼字符串的某種不同表示。 希望你可以找到閃光燈,因爲我真的想知道發生了什麼事。 (如果你有.swf,我們也可以反編譯它...) –

0

對我來說,它看起來像你的Python腳本以錯誤的順序解碼。如果你說的編碼順序什麼是正確的,首先的base64,然後zlib,則必須以相反的順序進行解碼:

print s.decode("zlib").decode("base64") 
+0

它不能; base64然後zlib的結果是不是文字:) – hobbs

+0

@Tosh說,他第一次b64編碼,然後拉鍊兩次。這是有道理的。 –

+0

那麼,試圖解壓縮然後base64解碼示例數據只會給出一個錯誤,因爲它顯然不zlib壓縮。 – hobbs

0

託什,你說,你第一次的base64編碼數據,然後將其存儲之前壓縮它到數據庫。迄今爲止這很好。壓縮數據後,它是二進制數據。因此,我假設你已經將這些數據以二進制格式存儲在數據庫中。現在你告訴我們,一個字符串:

的示例串是這樣的:「eNrj4mZkrShgWdHBx1mUmJfNosQIACUhBCI =」

爲此,根據你,表示壓縮數據。現在有矛盾。一方面,壓縮數據是二進制數據,另一方面,您清楚地向我們展示了一個由base64編碼產生的字符串(正如您可以從最後的'='中推斷的那樣)。

你混淆了一些東西。

+0

它存儲在mysql數據庫的MEDIUMTEXT字段中。 unzip和unbase64順序是正確的,我相信actionscript不使用標準編碼,並在zip頭中留下了額外的東西。 – Tosh

1

如果字符串是第一個base64-ed然後壓縮,解碼應該是相反的方式!

您的示例和輸出字符串不匹配;

In [1]: t = '{"xp": 656398, "rank": 34}' 

In [2]: t.encode('base64') 
Out[2]: 'eyJ4cCI6IDY1NjM5OCwgInJhbmsiOiAzNH0=\n' 

In [3]: t.encode('zlib').encode('base64') 
Out[3]: 'eJyrVqooULJSMDM1M7a00FFQKkrMywbyjU1qAVupBsE=\n' 

In [4]: t.encode('base64').encode('zlib') 
Out[4]: 'x\x9cK\xad\xf42Iv\xf64\xf3t\x894\xf4\xcb\xf25\xf5w.O\xf7\xcc\xf3\xcaH\xca-\xce\xf4\xcft\xac\xf2\xf30\xb0\xe5\x02\x00\xe3E\x0b\xd7' 

給定的輸入字符串 '{ 「XP」:656398, 「等級」:34}' 不產生輸出示例(參見缺貨[3]和Out [4])。

你也應該注意,在這種情況下,base64編碼字符串是比原來的,和附加zlib編碼是最長的。壓縮字符串通常不值得花費。

如果我們拿你的例子輸出並處理它,這就是我們得到的;

In [5]: s = 'eNrj4mZkrShgWdHBx1mUmJfNosQIACUhBCI=' 

In [6]: s.decode('base64') 
Out[6]: 'x\xda\xe3\xe2fd\xad(`Y\xd1\xc1\xc7Y\x94\x98\x97\xcd\xa2\xc4\x08\x00%!\x04"' 

In [7]: s.decode('base64').decode('zlib') 
Out[7]: '\n\x0b\x01\x05xp\x04\xa8\x88\x0e\trank\x04"\x01' 

您可以在輸出中清楚地看到文本'xp'和'rank'。而「'接近尾聲,可以解釋爲整數34

看來你的動作做一些數據的mangling編碼和壓縮它。