• python完成加密参数sign计算并输出指定格式的字符串


    加密规则:

    1.固定加密字符串+字符串组合(key/value的形式,并通过aissc码排序),

    2.通过sha1算法对排序后的字符串进行加密,

    3.最终输出需要的参数sign

    4.完成请求参数数据的格式输出(因为浏览器复制出来的格式直接用python是不能请求的所以我用了之前写的一个方法来完成请求数据格式的转换)

    例如:

    输入:

    '''course_finance_id[0]:252638
    total_price:0
    state:1
    finan_rmk:343
    timestamp:122
    sign:11'''xxx

    输出:

    'course_finance_id[0]=252638&total_price=0&state=1&finan_rmk=343&timestamp=1572505825134&sign=feab1228e93329b4e4adcebc7bcx'x'x2c4225a1eccba'

    不废话,上代码:

        def fwh_sign_sha1(self,str_in):#服务号请求签名处理封装
            '''主要过程:
                1.替换输入字符串中的时间戳为最新的时间戳
                2.将字符串中的sign字段过滤掉并通过ascii对其进行排序,因为加密时不需要此字段
                3.将排序且处理后的字符串通过sha1算法,得到加密字符串
                4.将得到的加密字符串替换至原字符串'''
            search_time_str='timestamp:'
            search_sign_str='sign:'
            str_inSource=re.search('(%s.+)'%(search_time_str),str_in)#匹配字段时间戳(timestamp)
            if str_inSource is not None:
                time_str=self.get_timestamp()#最终需要的时间戳,13位
                str_inSource=str_inSource.group()
                search_str_inSource=re.search('s',str_inSource)
                #匹配时间戳,key与value是否包含空格
                #如果包含空格,替换时加上空格,如果不处理会有问题(字符串格式与其他地方不一致)
                if search_str_inSource is not None:
                    str_equalSource=re.sub(str_inSource,'%s%s%s'%(search_time_str,search_str_inSource.group(),time_str),
                    str_in)#将输入的时间戳替换为需要的时间戳,并加上匹配出来得空格
                else:
                    str_equalSource=re.sub(str_inSource,'%s%s'%(search_time_str,time_str),
                    str_in)#将输入的时间戳替换为需要的时间戳
                input_list_source=str_equalSource.split('
    ')#以换行符分隔字符串并转换位列表
                input_list=[a for a in input_list_source 
                    if (search_sign_str or '%ss'%(search_sign_str) ) not in a]#列表过滤字段sign
                out_list=sorted(input_list)#对list进行排序
                out_str='
    '.join(out_list)#将排序后的list拼接为字符串
                input_sign_str=self.requestDataToStr_firefoxAndChrome(out_str,'','').decode()#获取拼接完成后的请求参数字符串(sign)
                '''这个方法默认对请求参数进行了编码处理,所以这里需手动解码'''
                out_sign_str=self.sha1_Encry(input_sign_str)#得到加密后的加密字符串
                str_inSource_sign=re.search('(%s.+)'%(search_sign_str),str_in)#匹配字段签名验证(sign)
                if str_inSource_sign is not None:
                    str_inSource_sign=str_inSource_sign.group()
                    search_inSource_sign=re.search('s',str_inSource)
                    #匹配sign,key与value是否包含空格
                    #如果包含空格,替换时加上空格,如果不处理会有问题(字符串格式与其他地方不一致)
                    if search_inSource_sign is not None:
                        str_last_sign=re.sub(str_inSource_sign,'%s%s%s'%(search_sign_str,search_inSource_sign.group(),
                        out_sign_str),str_equalSource)#将输入的时间戳替换为需要的时间戳
                    else:
                        str_last_sign=re.sub(str_inSource_sign,'%s%s'%(search_sign_str,out_sign_str),
                        str_equalSource)#将输入的时间戳替换为需要的时间戳
                    # print(str_last_sign)
                    str_give=self.requestDataToStr_firefoxAndChrome(str_last_sign)
                    # print(str_give)
                    return str_give
    
                else:
                    print('输入字符串没有sign对象:sign,无法完成数据转换')
                    return None
    
            else:
                print('输入字符串没有时间戳对象:timestamp,无法完成数据转换')
                return None
        
    #字符串进行sha1算法加密方法
    def sha1_Encry(self,str_in,Encay_strOne=Encay_str):#对字符串进行加密 str_out=hashlib.sha1() #采用sha1加密 str_out.update(str('%s%s'%(str_in,Encay_str)).encode(encoding='utf-8')) return str_out.hexdigest()
        
    #输出13位时间戳方法
    def get_timestamp(self):#输出当前时间的13位时间戳 current_milli_time = lambda: int(round(time.time() * 1000))#输出13位时间戳,round:对浮点数进行四舍五入 return str(current_milli_time())
        
    #字符串格式处理方法
    def requestDataToStr_firefoxAndChrome(self,str_in,space_one='=',space_two='&'): try: str_colon=re.search(':W?|s*:W?',str_in) #匹配出字符串中所有的冒号 if not str_colon==None: str_colon=str_colon.group() str_equal=re.sub(str_colon,space_one,str_in) #将字符串中的冒号替换为等于号(: >>> =) str_lin=re.search("(s *){2,}|(s *)",str_equal) #匹配出字符串中所有的换行符与空格,不写表示不限定匹配次数 if not str_lin==None: str_lin=str_lin.group() str_give=re.sub(str_lin,space_two,str_equal) #将字符串中的换行符替换为& ( >>> &) str_lin2=re.search('s.*',str_give) if str_lin2 is not None: str_lin2=str_lin2.group() str_lin3=re.search('=',str_lin2) if str_lin3 is not None and 'time' in str_give: #对请求参数含有时间字段进行特殊处理 try: str_lin3=str_lin3.group() str_give2=re.sub(str_lin3,':',str_lin2) str_give3=re.sub(str_lin2,str_give2,str_give) # print(str_give3) return str_give3.encode() #返回字符串,并对数据进行编码处理 except Exception as error: print(error) else: # print(str_give) return str_give.encode() else: # print(str_give) return str_give.encode() else: return str_equal.encode() else: print("字符串格式匹配错误") return None except Exception as error: print("数据处理失败,原因为: %s"%(error))

    写这个方法的时候遇到了一些问题,所以各位再实践的过程中一定要细心,字符串处理时一定要注意对空格的处理,最好保持格式的统一(参数替换时如果其他参数带有空格,替换时不要全给替换掉了,因为正则匹配时匹配不到就会使转换后的字符串达不到预期效果,看后续能不能想到更好的解决方法把),这样能避免一些问题

  • 相关阅读:
    interview ms1 N_Dorm
    interview ms1 robert move **
    LeetCode OJ-- Jump Game II **
    LeetCode OJ-- Jump Game
    LeetCode OJ-- Palindrome Partitioning II ***
    LeetCode OJ--Palindrome Partitioning **
    LeetCode OJ--Palindrome Number
    LeetCode OJ-- Linked List Cycle II **
    3dContactPointAnnotationTool开发日志(十一)
    3dContactPointAnnotationTool开发日志(十)
  • 原文地址:https://www.cnblogs.com/qtclm/p/11771327.html
Copyright © 2020-2023  润新知