2016-03-07 79 views
0

上下文: 我使用python從flex應用程序解碼amf響應。如何將此值轉換爲十六進制? (amf值)

與pyamf我可以解碼所有的響應,但有一個值得到我的關注。

這個值\ xa2C轉化爲4419

#\xa2C -> 4419 
#\xddI -> 11977 

我知道\ x被用十六進制值有關,但我不能得到的功能改造4419到\ xa2C。

4419是一個整數。

---更新1

該原始值不是十六進制。

,因爲我這個值\ xa2I轉化爲4425.

那麼什麼樣的價值是\ xa2I ??? 謝謝!

- 更新2.

DJ = 5834 
0F = 15 
0G = error 
1F = 31 
a1f = 4294 
adI = 5833 
adg = 5863 
adh = 5864 

是奇怪˚F後,在其他情況一定的時間接受值顯示錯誤。但是不是十六進制的值。

+1

'a2C'不是4419十進制無論是。我注意到'C'是大寫的,(就像下一行的'I')。 –

+0

謝謝!我更新了這個問題! – wu4m4n

+0

你如何得到這些值?他們來自哪裏?我沒有看到AMF使用'\ x'前綴的證據,所以我懷疑你正在看Python * repr()'output *,其中可打印的ASCII字符就是這樣表示的。 –

回答

1

你所看到的是AmfInteger字節的字符串表示形式。第一個例子,\xa2C包括兩個字節:0xa2又名162,和C,這是67 ASCII表示:

>>> ord("\xa2C"[0]) 
162 
>>> ord("\xa2C"[1]) 
67 

將其轉換成AmfInteger,我們也要跟着AMF3 specifications,第1.3.1節(AmfInteger的格式在AMF0和AMF3中是相同的,所以我們看什麼規格都沒有關係)。

在該部分中,U29(可變長度無符號29位整數,這是AmfIntegers在內部用於表示值的值)被定義爲1,2,3或4字節序列。每個字節對關於值本身的信息進行編碼,以及是否接着另一個字節。爲了弄清楚另一個字節是否符合當前的,一個只需要檢查最顯著位是否被設置:

>>> (162 & 0x80) == 0x80 
True 
>>> (67 & 0x80) == 0x80 
False 

所以我們現在證實了,你看到的字節序列的確是一個充滿U29:第一個字節有它的高位設置,表示它後面跟着另一個字節。第二個字節的位未設置,表示序列結束。爲了充分利用這些字節的實際價值,我們現在只需要他們的價值觀結合起來,同時掩蓋了第一個字節的最高位:

>>> 162 & 0x7f 
34 
>>> 34 << 7 
4352 
>>> 4352 | 67 
4419 

從這一點應該很容易明白,爲什麼其他值給出你觀察到的結果。

爲了完整起見,這裏也是一個Python代碼段與解析U29,包括所有的角落案件的範例:

def parse_u29(byte_sequence): 
    value = 0 
    # Handle the initial bytes 
    for byte in byte_sequence[:-1]: 
     # Ensure it has its high bit set. 
     assert ord(byte) & 0x80 

     # Extract the value and add it to the accumulator. 
     value <<= 7 
     value |= ord(byte) & 0x7F 

    # Handle the last byte. 
    value <<= 8 if len(byte_sequence) > 3 else 7 
    value |= ord(byte_sequence[-1]) 

    # Handle sign. 
    value = (value + 2**28) % 2**29 - 2**28 

    return value 


print parse_u29("\xa2C"), 4419 
print parse_u29(map(chr, [0x88, 0x00])), 1024 
print parse_u29(map(chr, [0xFF, 0xFF, 0x7E])), 0x1ffffe 
print parse_u29(map(chr, [0x80, 0xC0, 0x80, 0x00])), 0x200000 
print parse_u29(map(chr, [0xBF, 0xFF, 0xFF, 0xFE])), 0xffffffe 
print parse_u29(map(chr, [0xC0, 0x80, 0x80, 0x01])), -268435455 
print parse_u29(map(chr, [0xFF, 0xFF, 0xFF, 0x81])), -127 
+0

非常感謝你! :) – wu4m4n

+0

有一個問題,我怎麼能做到這一點 4352 | 67 = 4419 如何從67和4419獲得4352?謝謝Ventero! – wu4m4n

+1

@NelsonGuamanLeiva查看規範中的第1.3.1節,第一個列表顯示瞭如何將特定範圍內的數字轉換爲amf整數。對於0x80到0x3fff之間的數字,將數字分成兩個字節,其中第一個設置了其最高位,後面是原始數字的最高7位,第二個獲取剩餘的,即'(4419> > 7)| 0x80 = 162'和'4419&0x7f = 67'。這就是你從原始字節序列中獲得162和67的方法。 – Ventero

相關問題