接昨天,發(fā)現(xiàn)在python3里面,2次提供相同的url,hash的數(shù)值的確是不一致的。google 了一下,發(fā)現(xiàn)這個是Python 為了防止惡意攻擊做的一個操作。
下面藍框,如果要解除這個問題,建議使用hashlib 模塊。
好吧,直接找了下它的實現(xiàn):
https://docs.python.org/3/library/hashlib.html
比較喜歡這個blake2b的實現(xiàn),指定長度,而且加入key 防止被暴力破解。
把這段代碼引入到 昨天的代碼中,問題解決。貼代碼
import redisimport reimport jsonimport timeimport cgifrom redis import StrictRedis, ConnectionPoolfrom flask import Flask,jsonify,requestimport requestsfrom hashlib import blake2bapp = Flask(__name__)def create_url(): print(“Come to the function create_url()”) prefix = “http://127.0.0.1/api/url/” suffix = time.strftime(“%Y-%m-%d-%H:%M:%S”, time.localtime()) url = prefix + suffix print(url) print(“Come out of the function create_url()”) return urldef dohash(url): print(“—-come to function— dohash(url)”) FILES_HASH_PERSON = b’57challenges’ #設置一個key h = blake2b(digest_size=10,person=FILES_HASH_PERSON) #設置加密長度及指定key h.update(url.encode()) primkey = h.hexdigest() print(“the hash of {0} is {1}”.format(url,primkey)) print(“—-come out of function— dohash(url)”) return primkeydef insert_into_redis(primkey,textcontent): #mock 把數(shù)據插入數(shù)據庫,primkey 和 textcontent print(“—-come to function— insert_into_redis(primkey,textcontent)”) pool = ConnectionPool(host=’localhost’, port=6379, db=0, decode_responses=True) r = StrictRedis(connection_pool=pool) try: r.hset(“document”, primkey, json.dumps({“content”: textcontent})) except: return 0 print(“—-come out of function— insert_into_redis(primkey,textcontent)”) return 1def check_url_if_exist(url): # mock檢查邏輯 print(“—-come to function—check_url_if_exist(url)”) print(“The received url is {0}”.format(url)) key = dohash(url) print(“to search this key {0},check if it exist”.format(key)) pool = ConnectionPool(host=’localhost’, port=6379, db=0, decode_responses=True) r = StrictRedis(connection_pool=pool) if r.hexists(“document”,key): result = 1 print(“it exist”) else: result = 0 print(“it not exist”) print(“—-come out of function—check_url_if_exist(url)”) return resultdef get_text(url): print(“—-come to function—get_text(url)”) pool = ConnectionPool(host=’localhost’, port=6379, db=0, decode_responses=True) r = StrictRedis(connection_pool=pool) key = dohash(url) textinfojson = r.hmget(“document”,key) print(textinfojson) #debug , 整個信息內容展示 print(type(textinfojson)) # 看看類型,原來是List print(textinfojson[0]) # 展示list 中第一個元素內容 print(type(textinfojson[0])) # 看看類型是str print(json.loads(textinfojson[0])[“content”]) #把str 類型轉為字典,并讀取字典里面key 為”content”的內容 textinfo = json.loads(textinfojson[0])[“content”] print(“—-come out of function—get_text(url)”) return textinfo”””1.保存文檔:功能邏輯:接收前端請求,把文字存到數(shù)據庫,并返回成功信息到后端。輸入: {“text”: “this is the info for test”}輸出: {“info”: “information has been successful saved”} 功能邏輯:1. 獲取輸入 2. 把輸入的text 文檔生成一個url3. 把URL 做hash ,并把hash(url)作為key4. 把{hash(url): text} 存入數(shù)據庫5. 如果存儲成功,則返回信息給到客戶端redis 表結構設計: {md5(url): text} “””@app.route(‘/api/storedoc’,methods=[‘POST’])def store_doc(): textcontent = request.json[‘text’] # 獲取輸入 url = create_url() primkey = dohash(url) if insert_into_redis(primkey,textcontent) == 1: info =” insert into redis key {0} {1} pair success”.format(url,textcontent) else: info = “something error has happened” return jsonify({“info”:info})”””2.編輯文檔:功能邏輯: 收集客戶端的編輯請求,進入url 并找到對應的數(shù)據,把text 數(shù)據展示在前端,輸入:{“edit”: “http://127.0.0.1/api/202206100906”}輸出:{“textinfo”:”this is the info for test”}供客戶端邏輯把這個text 數(shù)據做展示。2-1: 接收輸入的URL2-2: 把URL做hash,并到數(shù)據庫查找數(shù)據2-3: 如果存在則返回數(shù)據,如果不存在則返回信息告訴不存在 result = 0″””@app.route(‘/api/editdoc’,methods=[‘POST’])def edit_doc(): url = request.json[‘edit’] print(“We have got the input url, it’s {0}”.format(url)) if check_url_if_exist(url) == 1: textinfo = get_text(url) print(” info: the text info is {0}”.format(textinfo)) return jsonify({“info”: “the url is exist”,”url”:url}) else: return jsonify({“info”: “the url {0} is not exist”.format(url)})if __name__ == ‘__main__’: app.run(host=’0.0.0.0′,port=8008,debug = True)
前端插入效果
后臺信息:
看到key 是這個 9265 結尾的。
我用同一個url鏈接,反向找下對應的數(shù)值:
后端的日志:key 沒變
操作三次,查看數(shù)據庫,信息是完備的。