騰訊AI開放平臺的簽名演算法(Python)
阿新 • • 發佈:2018-12-29
前幾天老師佈置了一個作業,要求使用python進行語音合成,實現班級點名的功能。後來使用了pyttsx庫,發現這個庫合成的語音聽起來不清晰,於是果斷拋棄。然後就想起了使用騰訊的語音合成api,發現騰訊優圖的語音合成還是比較清晰的。本來騰訊ai開放平臺的api使用起來不難,但就是計算 “sign” 這個簽名時有些不好理解。這裡只對這個簽名的演算法進行講解。
官方提供的介紹如下:
下面分步介紹:
# 在執行這一步時首先要保證parms裡的所有必須引數(sign除外)都已經完整 # 我的params如下: params = { 'app_id' : self.APP_ID, 'time_stamp' : time_stamp, 'nonce_str' : nonce_str, 'text' : self.TEXT, 'model_type' : self.model_type, # 語音 0~2。0:女。1:女英文。2:男 'speed' : self.speed, # 語速 -2:0.6,-1:0.8, 0:正常, 1:1.2倍,2:1.5倍 }; # 其中的time_stamp和nonce_str需要實時計算。方法如下: time_stamp = int(time.time()); # 獲得時間戳(秒級),防止請求重放 nonce_str = ''.join(random.sample(string.ascii_letters + string.digits, 10)); # 獲得隨機字串,保證簽名不被預測。 """將<key, value>請求引數對按key進行字典升序排序,得到有序的引數對列表N 將列表N中的引數對按URL鍵值對的格式拼接成字串,得到字串T(如:key1=value1&key2=value2),URL鍵值拼接過程value部分需要URL編碼,URL編碼演算法用大寫字母,例如%E8,而不是小寫%e8""" # 獲得sign對應的值 before_sign = ''; # 對key排序拼接 for key in sorted(params): before_sign += f'{key}={quote(str(params[key]).encode("utf8"))}&';
# 將應用祕鑰以app_key為鍵名,拼接到before_sign的末尾
before_sign += f"app_key={self.APP_KEY}";
# 對獲得的before_sign進行MD5加密(結果大寫),得到藉口請求籤名
sign = hashlib.md5(before_sign.encode("utf-8")).hexdigest().upper();
# 將請求籤名新增進引數字典
params["sign"] = sign;
最後附上完整程式碼:
# 獲得時間戳(秒級),防止請求重放 time_stamp = int(time.time()); # 獲得隨機字串,保證簽名不被預測 nonce_str = ''.join(random.sample(string.ascii_letters + string.digits, 10)) # 組合引數(缺少sign,其值要根據以下獲得) params = { 'app_id' : self.APP_ID, 'time_stamp' : time_stamp, 'nonce_str' : nonce_str, 'text' : self.TEXT, 'model_type' : self.model_type, # 語音 0~2。0:女。1:女英文。2:男 'speed' : self.speed, # 語速 -2:0.6,-1:0.8, 0:正常, 1:1.2倍,2:1.5倍 }; # 獲得sign對應的值 before_sign = ''; # 對key排序拼接 for key in sorted(params): before_sign += f'{key}={quote(str(params[key]).encode("utf8"))}&'; # 將應用祕鑰以app_key為鍵名,拼接到before_sign的末尾 before_sign += f"app_key={self.APP_KEY}"; # 對獲得的before_sign進行MD5加密(結果大寫),得到藉口請求籤名 sign = hashlib.md5(before_sign.encode("utf-8")).hexdigest().upper(); # 將請求籤名新增進引數字典 params["sign"] = sign;