python 把string的值當做16進位制處理
阿新 • • 發佈:2019-01-29
一個string的,因為某種原因我們需要將它的值看成hex來處理。
這個問題的上下文是這樣的。 我們公司有個一個APK Parser可以獲取APK的屬性,包括package Name, permissionName之類的,然後以XML文字的形式儲存起來。這裡出現了一些問題。就是APK的某些項包含特殊字元的時候,我們如果不作任何編碼直接放在XML檔案裡面可能會由於特殊字元的干擾造成XML檔案不被識別 (典型的特殊字元比如 ‘\’)。 於是我們的工程師就對所有的文字進行來了一次utf-16-le (UTF-16-LITTLE-ENDIAN)的編碼。然後在XML裡面的字串以編碼後的16進位制raw string來代替。e.g: 63006f006d002e006600370032003900300077006500690072002e0065006c00730066006b002e0074007800 表示com.f7290weir.elsfk.tx
但是我現在需要對這個已經編碼後的16進位制字串進行解析,進行一個逆向工程來得到原文。
str = 63006f006d002e006600370032003900300077006500690072002e0065006c00730066006b002e0074007800
print decode(str,'uft16')
>> ㌶〰昶〰搶〰攲〰㘶〰㜳〰㈳〰㤳〰〳〰㜷〰㔶〰㤶〰㈷〰攲〰㔶〰挶〰㌷〰㘶〰戶〰攲〰傌〰㠷〰
用以上方法明顯行不通。 因為我們是以little endian的方式編碼的,所以相對而言也需要以同樣的方式解碼。
使用了little-endian任然有問題。在這個問題上我想到應該是由於我們的str並沒有被認為是16進位制的值,從而我們decode的物件實際上是string化的這麼一長串數字。str = 63006f006d002e006600370032003900300077006500690072002e0065006c00730066006b002e0074007800 print decode(str,'uft_16_el') >>㌶〰昶〰搶〰攲〰㘶〰㜳〰㈳〰㤳〰〳〰㜷〰㔶〰㤶〰㈷〰攲〰㔶〰挶〰㌷〰㘶〰戶〰攲〰傌〰㠷〰
這個問題如何解決呢。對每兩位前面加一個"\x"是我們最容易想到的。
a = "63006f006d002e006600370032003900300077006500690072002e0065006c00730066006b002e0074007800" retval = '' for i in range ( 0, len( a ) / 2 ): retval = retval + '\x' + a[i * 2] + a[i * 2 + 1] print [retval] >>ValueError: invalid \x escape
很遺憾這個方法不行。 在我們寫下面那段程式碼的時候python就已經無法忍受的報錯了。
+ '\x' +
這很可以理解,python直譯器無法認同''\x" 這種型別的空串。但是如果這不行的話我們還能有什麼方法表達String的值為16進位制碼呢。
其實很簡單,因為它是一個表示16進位制的字串。換句話說它也就是經過16進位制編碼過一次的string串兒。我們直接對它進行一次hex的解碼就行了。
a = "63006f006d002e006600370032003900300077006500690072002e0065006c00730066006b002e0074007800"print a.decode( 'hex' ).decode( 'utf_16_le' ) 就這麼簡單。