1. 程式人生 > 其它 >記一個python字典和json.dumps()的坑

記一個python字典和json.dumps()的坑

記一個python字典和json.dumps()的坑

最近專案中需要與管易雲erp做對接,看了他的介面文件,php的示例程式碼,於是用python仿寫。

其中傳的引數data中前面幾個json資料是固定的,最後需要加一個簽名,該簽名是對前面的json資料字串化後,首尾拼接上screct字串,再做md5處理(32位大寫),再將該簽名新增到之前的json中作為post引數傳遞過去。

問題就出在組裝json字串和簽名中,因為python內建的字典是無序的,導致我組裝好的json資料作為引數傳遞給自己編寫的簽名函式時,字典內部的順序是變化的,所以簽名前後的md5值不一樣,導致頻頻報錯,自己起初沒在意資料順序的事,因為對接金蝶erp時沒有簽名這一項,資料傳遞的很簡單,導致排錯時方向出現錯誤。後來想到這了顧開始解決。

解決方法是使用collections庫中的OrderedDict(有序字典)模組,組裝好的資料就不會亂序,做的md5簽名也就前後一致了

但,在對json資料使用json.dumps()方法時,字串化後的資料在逗號後會有一個空格,導致md5值出錯

原理:

根據json.dumps()官方文件,為了美觀預設會加上逗號空格和冒號空格如果想消除空格,指定引數separators=(',',':')

json.dumps(data,separators=(',',':'))

最後,將自己寫的函式留下來做個例子

def getShops():
    data = OrderedDict()
    data["appkey"] = appkey
    data["sessionkey"] = sessionkey
    data["method"] = method
    data["page_no"] = "1"
    data["page_size"] = "10"
    data["sign"] = sign(data,secret)
    
    response = requests.post(url=url, data=json.dumps(data))
    print(response.text)


def sign(data,secret):
    str = json.dumps(data,separators=(',',':'))
    fullStr = secret+str+secret
    signCode = hashlib.md5(fullStr.encode("utf-8")).hexdigest().upper()
    #print(signCode)
    return signCode

再訪問新增訂單介面時,又報簽名出錯,按著之前的邏輯去查,發現json.dumps()含中文資料時,會將中文預設轉為ascii碼,從而導致MD5不一致,需轉成中文才行

原理:

def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
        allow_nan=True, cls=None, indent=None, separators=None,
        default=None, sort_keys=False, **kw):

解決:將上述程式碼紅色引數改為False即可。

轉自:

https://www.cnblogs.com/miaoweiye/p/12461499.html