<% option explicit '功能:支付宝接口公用函数(封装) '版本:1.0 '作者:Joost '创建日期:2011-1-26 '说明: '封装支付宝接口,方便调用,不涉及功能变动,用户只需实例化该类,设置参数就可以,如果你发现BUG也可以在http://wei0523123.iteye.com/给我留言 '该代码仅供学习和研究支付宝接口使用,只是提供一个参考。 %> <% 'dim alipay 'set alipay=new cls_alipay ''---------------------------------------------------------- ''基本参数设定 'alipay.partner="lvcheng" 'alipay.key="lvcheng" 'alipay.seller_email="lvcheng" ''alipay.input_charset="gb2312" 'alipay.notify_url="http://www.lvcheng123.com" 'alipay.return_url="http://www.lvcheng123.com" 'alipay.show_url="http://www.lvcheng123.com" 'alipay.sign_type="MD5" 'alipay.antiphishing="0" 'alipay.mainname="绿城团购" ''---------------------------------------------------------- ''alipay.out_trade_no 'alipay.subject="会员xxxx订购xxxx" 'alipay.body="订单详细" 'alipay.total_fee=5000 'alipay.pay_mode="directPay" ''alipay.encrypt_key ''alipay.exter_invoke_ip ''alipay.extra_common_param ''alipay.buyer_email ''alipay.royalty_type ''alipay.royalty_parameters ''alipay.it_b_pay=15 ' ''---------------------------------------------------------- 'alipay.alipay_service() 'dim arr:arr=alipay.para 'response.Write(alipay.input_charset&"<br>") 'response.Write(arr(0)&"<br>") 'response.Write alipay.create_url() 'set alipay=nothing Class cls_alipay private alipay_md5 private gateway '网关地址 private mysign '加密结果(签名结果) private sPara '需要加密的已经过滤后的参数数 '---------------------------------------------------------- '基本参数设定 private s_partner private s_key private s_seller_email private s_input_charset private s_notify_url private s_return_url private s_show_url private s_sign_type private s_antiphishing private s_mainname '---------------------------------------------------------- '请求参数 private s_out_trade_no private s_subject private s_body '订单描述、订单详细、订单备注,显示在支付宝收银台里的"商品描述"里 private s_total_fee private s_pay_mode private s_paymethod private s_defaultbank private s_encrypt_key private s_exter_invoke_ip private s_extra_common_param private s_buyer_email private s_royalty_type private s_royalty_parameters private s_it_b_pay private s_para '---------------------------------------------------------- public Property Let partner(byval val) s_partner = val end Property public Property Get partner() partner = s_partner end Property '---------------------------------------------------------- '---------------------------------------------------------- public Property Let key(byval val) s_key = val end Property public Property Get key() key = s_key end Property '---------------------------------------------------------- '---------------------------------------------------------- public Property Let seller_email(byval val) s_seller_email = val end Property public Property Get seller_email() seller_email = s_seller_email end Property '---------------------------------------------------------- '---------------------------------------------------------- public Property Let input_charset(byval val) s_input_charset = val end Property public Property Get input_charset() input_charset = s_input_charset end Property '---------------------------------------------------------- '---------------------------------------------------------- public Property Let notify_url(byval val) s_notify_url = val end Property public Property Get notify_url() notify_url = s_notify_url end Property '---------------------------------------------------------- '---------------------------------------------------------- public Property Let return_url(byval val) s_return_url = val end Property public Property Get return_url() return_url = s_return_url end Property '---------------------------------------------------------- '---------------------------------------------------------- public Property Let show_url(byval val) s_show_url = val end Property public Property Get show_url() show_url = s_show_url end Property '---------------------------------------------------------- '---------------------------------------------------------- public Property Let sign_type(byval val) s_sign_type = val end Property public Property Get sign_type() sign_type = s_sign_type end Property '---------------------------------------------------------- '---------------------------------------------------------- public Property Let antiphishing(byval val) if(val = "1") then s_encrypt_key = query_timestamp(s_partner) s_exter_invoke_ip = getip() '获取客户端的IP地址 end if s_antiphishing = val end Property public Property Get antiphishing() antiphishing = s_antiphishing end Property '---------------------------------------------------------- '---------------------------------------------------------- public Property Let mainname(byval val) s_mainname = val end Property public Property Get mainname() mainname = s_mainname end Property '---------------------------------------------------------- '---------------------------------------------------------- '---------------------------------------------------------- public Property Let out_trade_no(byval val) s_out_trade_no = val end Property public Property Get out_trade_no() out_trade_no = s_out_trade_no end Property '---------------------------------------------------------- '---------------------------------------------------------- public Property Let subject(byval val) s_subject = val end Property public Property Get subject() subject = s_subject end Property '---------------------------------------------------------- '---------------------------------------------------------- public Property Let body(byval val) s_body = val end Property public Property Get body() body = s_body end Property '---------------------------------------------------------- '---------------------------------------------------------- public Property Let total_fee(byval val) s_total_fee = val end Property public Property Get total_fee() total_fee = s_total_fee end Property '---------------------------------------------------------- '---------------------------------------------------------- public Property Let pay_mode(byval val) if val = "directPay" then s_paymethod = "directPay" '默认支付方式,四个值可选:bankPay(网银); cartoon(卡通); directPay(余额); CASH(网点支付) s_defaultbank = "" else s_paymethod = "bankPay" '默认支付方式,四个值可选:bankPay(网银); cartoon(卡通); directPay(余额); CASH(网点支付) s_defaultbank = val '默认网银代号,代号列表见http://club.alipay.com/read.php?tid=8681379 end if s_pay_mode = val end Property public Property Get pay_mode() pay_mode = s_pay_mode end Property '---------------------------------------------------------- '---------------------------------------------------------- '只读 ' public Property Let defaultbank(byval val) ' s_defaultbank = val ' end Property public Property Get defaultbank() defaultbank = s_defaultbank end Property '---------------------------------------------------------- '---------------------------------------------------------- '只读 ' public Property Let defaultbank(byval val) ' s_defaultbank = val ' end Property public Property Get paymethod() paymethod = s_paymethod end Property '---------------------------------------------------------- '---------------------------------------------------------- '只读 ' public Property Let encrypt_key(byval val) ' s_encrypt_key = val ' end Property public Property Get encrypt_key() encrypt_key = s_encrypt_key end Property '---------------------------------------------------------- '---------------------------------------------------------- public Property Let exter_invoke_ip(byval val) s_exter_invoke_ip = val end Property public Property Get exter_invoke_ip() exter_invoke_ip = s_exter_invoke_ip end Property '---------------------------------------------------------- '---------------------------------------------------------- public Property Let extra_common_param(byval val) s_extra_common_param = val end Property public Property Get extra_common_param() extra_common_param = s_extra_common_param end Property '---------------------------------------------------------- '---------------------------------------------------------- public Property Let buyer_email(byval val) s_buyer_email = val end Property public Property Get buyer_email() buyer_email = s_buyer_email end Property '---------------------------------------------------------- '---------------------------------------------------------- public Property Let royalty_type(byval val) s_royalty_type = val end Property public Property Get royalty_type() royalty_type = s_royalty_type end Property '---------------------------------------------------------- '---------------------------------------------------------- public Property Let royalty_parameters(byval val) s_royalty_parameters = val end Property public Property Get royalty_parameters() royalty_parameters = s_royalty_parameters end Property '---------------------------------------------------------- '---------------------------------------------------------- public Property Let it_b_pay(byval val) s_it_b_pay = val end Property public Property Get it_b_pay() it_b_pay = s_it_b_pay end Property '---------------------------------------------------------- '---------------------------------------------------------- '只读 ' public Property Let input_charset(byval val) ' s_input_charset = val ' end Property public Property Get para() para = s_para end Property '---------------------------------------------------------- '初始化 '---------------------------------------------------------- private sub Class_Initialize dim sTime '网关地址 gateway ="http://notify.alipay.com/trade/notify_query.do?" '---------------------------------------------------------- '以下默认初始化参数 s_partner ="lvcheng" s_key ="lvcheng" s_seller_email ="lvcheng" s_input_charset ="utf-8" '设置编码 s_notify_url ="http://www.lvcheng123.com" s_return_url ="http://www.lvcheng123.com" s_show_url ="http://www.lvcheng123.com" s_sign_type ="MD5" s_antiphishing ="0" s_mainname ="绿城团购" s_paymethod ="directPay" sTime=Now() '初始订单编号 s_out_trade_no =year(sTime)&month(sTime)&day(sTime)&hour(sTime)&minute(sTime)&second(sTime) '以上默认初始化参数 '---------------------------------------------------------- set alipay_md5=new cls_alipay_md5 '设置MD5编码 alipay_md5.input_charset=s_input_charset end sub '---------------------------------------------------------- '销毁对象 '---------------------------------------------------------- private sub Class_Terminate set alipay_md5=nothing end sub '---------------------------------------------------------- '构造要请求的参数数组,无需改动 '---------------------------------------------------------- private sub cate_para() s_para = Array("service=create_direct_pay_by_user","payment_type=1","partner="&s_partner,"seller_email="&s_seller_email,"return_url="&s_return_url,"notify_url="&s_notify_url,"_input_charset="&s_input_charset,"show_url="&s_show_url,"out_trade_no="&s_out_trade_no,"subject="&s_subject,"body="&s_body,"total_fee="&s_total_fee,"paymethod="&s_paymethod,"defaultbank="&s_defaultbank,"anti_phishing_key="&s_encrypt_key,"exter_invoke_ip="&s_exter_invoke_ip,"extra_common_param="&s_extra_common_param,"buyer_email="&s_buyer_email,"royalty_type="&s_royalty_type,"royalty_parameters="&s_royalty_parameters,"it_b_pay="&s_it_b_pay) end sub '---------------------------------------------------------- '构造函数 '从配置文件及入口文件中初始化变量 'inputPara 需要加密的参数数组 '---------------------------------------------------------- function alipay_service() dim sort_para '构造要请求的参数数组 call cate_para() gateway = "https://www.alipay.com/cooperate/gateway.do?" sPara = para_filter(s_para) sort_para = arg_sort(sPara) '得到从字母a到z排序后的加密参数数组 '获得签名结果 mysign = build_mysign(sort_para,s_key) end function '---------------------------------------------------------- '构造请求URL(GET方式请求) '输出 请求url '---------------------------------------------------------- function create_url() dim sort_para,arg,url url = gateway sort_para = arg_sort(sPara) arg = create_linkstring_urlencode(sort_para) '把数组所有元素,按照"参数=参数值"的模式用"&"字符拼接成字符串 url = url & arg & "sign=" &mysign & "&sign_type=" & s_sign_type create_url = url end function '---------------------------------------------------------- '构造Post表单提交HTML(POST方式请求) '输出 表单提交HTML文本 '---------------------------------------------------------- function build_postform() dim nCount,nLen,sHtml,pos,itemName,itemValue sHtml = "<form id='alipaysubmit' name='alipaysubmit' action='"& gateway &"_input_charset="&s_input_charset&"' method='post'>" nCount = ubound(sPara) for i = 0 to nCount '把sArray的数组里的元素格式:变量名=值,分割开来 pos = Instr(sPara(i),"=") '获得=字符的位置 nLen = Len(sPara(i)) '获得字符串长度 itemName = left(sPara(i),pos-1) '获得变量名 itemValue = right(sPara(i),nLen-pos)'获得变量的值 sHtml = sHtml & "<input type='hidden' name='"& itemName &"' value='"& itemValue &"'/>" next sHtml = sHtml & "<input type='hidden' name='sign' value='"& mysign &"'/>" sHtml = sHtml & "<input type='hidden' name='sign_type' value='"& s_sign_type &"'/></form>" sHtml = sHtml & "<input type=""button"" name=""v_action"" value=""支付宝确认付款"" onClick=""document.forms['alipaysubmit'].submit();"">" build_postform = sHtml end function '******************************************************************************** '---------------------------------------------------------- '对notify_url的认证 '输出 验证结果:true/false function notify_verify() dim responseTxt,sGetArray,sArray,sort_para,sWord responseTxt = get_http() '判断消息是不是支付宝发出 sGetArray = GetRequestPost() '获取支付宝POST过来通知消息,并以"参数名=参数值"的形式组成数组 if IsArray(sGetArray) then '验证是否有数组传来 '生成签名结果 sArray = para_filter(sGetArray) '对所有POST反馈回来的数据去空格 sort_para = arg_sort(sArray) '对所有POST反馈回来的数据排序 mysign = build_mysign(sort_para,s_key) '生成签名结果 '写日志记录(若要调试,请取消下面两行注释) sWord = "responseTxt="& responseTxt &"\n return_url_log:sign="&request.Form("sign")&"&mysign="&mysign&"&"&create_linkstring(sort_para) log_result(sWord) '判断veryfy_responsetTxtresult是否为ture,生成的签名结果mysign与获得的签名结果sign是否一致 'responsetTxt的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关 'mysign与sign不等,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关 if mysign = request.Form("sign") and responseTxt = "true" then notify_verify = true else notify_verify = false end if else notify_verify = false end if end function '---------------------------------------------------------- '对return_url的认证 '输出 验证结果:true/false '---------------------------------------------------------- function return_verify() dim sWord,responseTxt,sGetArray,sArray,sort_para responseTxt = get_http() '判断消息是不是支付宝发出 sGetArray = GetRequestGet() '获取支付宝GET过来通知消息,并以"参数名=参数值"的形式组成数组 if IsArray(sGetArray) then '验证是否有数组传来 '生成签名结果 sArray = para_filter(sGetArray) '对所有GET反馈回来的数据去空格 sort_para = arg_sort(sArray) '对所有GET反馈回来的数据排序 mysign = build_mysign(sort_para,s_key) '生成签名结果 '写日志记录(若要调试,请取消下面两行注释) ' sWord = "responseTxt="& responseTxt &"\n return_url_log:sign="&request.QueryString("sign")&"&mysign="&mysign&"&"&create_linkstring(sort_para) ' log_result(sWord) '判断responsetTxt是否为ture,生成的签名结果mysign与获得的签名结果sign是否一致 'responsetTxt的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关 'mysign与sign不等,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关 if mysign = request.QueryString("sign") and responseTxt = "true" then return_verify = true else return_verify = false end if else return_verify = false end if end function '---------------------------------------------------------- '获取支付宝GET过来通知消息,并以"参数名=参数值"的形式组成数组 '输出 request回来的信息组成的数组 '---------------------------------------------------------- function GetRequestGet() dim sArray(),varItem,i i = 0 For Each varItem in Request.QueryString Redim Preserve sArray(i) sArray(i) = varItem&"="&Request(varItem) i = i + 1 Next if i = 0 then '验证是否有数组传来 GetRequestGet = "" else GetRequestGet = sArray end if end function '---------------------------------------------------------- '获取支付宝POST过来通知消息,并以"参数名=参数值"的形式组成数组 '输出 request回来的信息组成的数组 '---------------------------------------------------------- function GetRequestPost() dim sArray(),varItem,i i = 0 For Each varItem in Request.Form Redim Preserve sArray(i) sArray(i) = varItem&"="&Request(varItem) i = i + 1 Next if i = 0 then '验证是否有数组传来 GetRequestPost = "" else GetRequestPost = sArray end if end function '---------------------------------------------------------- '获取远程服务器ATN结果 '输出 服务器ATN结果字符串 '---------------------------------------------------------- private function get_http() dim Retrieval,ResponseTxt gateway = gateway &"partner=" & s_partner & "¬ify_id=" & request("notify_id") Set Retrieval = Server.CreateObject("Msxml2.ServerXMLHTTP.3.0") Retrieval.setOption 2, 13056 Retrieval.open "GET", gateway, False, "", "" Retrieval.send() ResponseTxt = Retrieval.ResponseText set Retrieval = Nothing get_http = ResponseTxt end function '---------------------------------------------------------- '******************************************************************************** '---------------------------------------------------------- '生成签名结果 'sArray 要加密的数组 'key 安全校验码 'sign_type 加密类型 '输出 签名结果字符串 '---------------------------------------------------------- private function build_mysign(sArray, key) dim prestr,nLen prestr = create_linkstring(sArray) '把数组所有元素,按照"参数=参数值"的模式用"&"字符拼接成字符串 '去掉最後一個&字符 nLen = Len(prestr) prestr = left(prestr,nLen-1) prestr = prestr & key '把拼接后的字符串再与安全校验码直接连接起来 mysign = sign(prestr) '把最终的字符串加密,获得签名结果 build_mysign = mysign end function '---------------------------------------------------------- '把数组所有元素,按照"参数=参数值"的模式用"&"字符拼接成字符串 'sArray 需要拼接的数组 '输出 拼接完成以后的字符串 '---------------------------------------------------------- private function create_linkstring(sArray) dim nCount,i nCount = ubound(sArray) dim prestr for i = 0 to nCount prestr = prestr & sArray(i) & "&" next create_linkstring = prestr end function '---------------------------------------------------------- '把数组所有元素,按照"参数=参数值"的模式用"&"字符拼接成字符串 '使用场景:GET方式请求时,对URL的中文进行编码 'sArray 需要拼接的数组 '输出 拼接完成以后的字符串 '---------------------------------------------------------- private function create_linkstring_urlencode(sArray) dim nCount,i,pos,nLen,itemName,itemValue nCount = ubound(sArray) dim prestr for i = 0 to nCount '把sArray的数组里的元素格式:变量名=值,分割开来 pos = Instr(sArray(i),"=") '获得=字符的位置 nLen = Len(sArray(i)) '获得字符串长度 itemName = left(sArray(i),pos-1) '获得变量名 itemValue = right(sArray(i),nLen-pos)'获得变量的值 if itemName <> "service" and itemName <> "_input_charset" then prestr = prestr & itemName &"=" & server.URLEncode(itemValue) & "&" else prestr = prestr & sArray(i) & "&" end if next create_linkstring_urlencode = prestr end function '---------------------------------------------------------- '除去数组中的空值和签名参数 'sArray 加密参数组 '输出 去掉空值与签名参数后的新加密参数组 '---------------------------------------------------------- private function para_filter(sArray) dim para(),nCount,i,pos,nLen,itemName,itemValue nCount = ubound(sArray) dim j j = 0 for i = 0 to nCount '把sArray的数组里的元素格式:变量名=值,分割开来 pos = Instr(sArray(i),"=") '获得=字符的位置 nLen = Len(sArray(i)) '获得字符串长度 itemName = left(sArray(i),pos-1) '获得变量名 itemValue = right(sArray(i),nLen-pos)'获得变量的值 if itemName <> "sign" and itemName <> "sign_type" and itemValue <> "" then Redim Preserve para(j) para(j) = sArray(i) j = j + 1 end if next para_filter = para end function '---------------------------------------------------------- '对数组排序 'sArray 排序前的数组 '输出 排序后的数组 '---------------------------------------------------------- private function arg_sort(sArray) dim nCount,i,minmax,minmaxSlot,j,mark,temp nCount = ubound(sArray) For i = nCount TO 0 Step -1 minmax = sArray( 0 ) minmaxSlot = 0 For j = 1 To i mark = (sArray( j ) > minmax) If mark Then minmax = sArray( j ) minmaxSlot = j end If Next If minmaxSlot <> i Then temp = sArray( minmaxSlot ) sArray( minmaxSlot ) = sArray( i ) sArray( i ) = temp end If Next arg_sort = sArray end function '---------------------------------------------------------- '加密字符串 'prestr 需要加密的字符串 'sign_type 加密类型 '输出 加密结果 '---------------------------------------------------------- private function sign(prestr) dim sResult if s_sign_type = "MD5" then sResult = alipay_md5.md5(prestr) else sResult = "" end if sign = sResult end function '---------------------------------------------------------- '用于防钓鱼,调用接口query_timestamp来获取时间戳的处理函数 '注意:远程解析XML出错,与IIS服务器配置有关 'partner 合作身份者ID '输出 时间戳字符串 '---------------------------------------------------------- private function query_timestamp(partner) dim url,UserData,encrypt_key, http,xml url = "https://mapi.alipay.com/gateway.do?service=query_timestamp&partner="&s_partner Set http=Server.CreateObject("Microsoft.XMLHTTP") http.Open "GET",url,False http.send Set xml=Server.CreateObject("Microsoft.XMLDOM") xml.Async=true xml.ValidateOnParse=False xml.Load(http.ResponseXML) set UserData=xml.getElementsByTagName("encrypt_key") ' 节点的名称 if isnull(xml.getElementsByTagName("encrypt_key") ) then encrypt_key = "" else encrypt_key = UserData.item(0).childnodes(0).text end if query_timestamp = encrypt_key end function '---------------------------------------------------------- '写日志,方便测试(看网站需求,也可以改成存入数据库) 'sWord 要写入日志里的文本内容 '---------------------------------------------------------- private function log_result(sWord) dim fs,ts set fs= createobject("scripting.filesystemobject") set ts=fs.createtextfile(server.MapPath("/pay/log/"&replace(now(),":","")&Rnd(1000)&".txt"),true) ts.writeline(sWord) ts.close set ts=Nothing set fs=Nothing end function '---------------------------------------------------------- '过滤特殊字符 'Str 要被过滤的字符串 '输出 已被过滤掉的新字符串 '---------------------------------------------------------- private function delstr(str) if IsNull(str) Or IsEmpty(str) Then str = "" end if delstr = Replace(str,";","") delstr = Replace(delstr,"'","") delstr = Replace(delstr,"&","") delstr = Replace(delstr," ","") delstr = Replace(delstr," ","") delstr = Replace(delstr,"%20","") delstr = Replace(delstr,"--","") delstr = Replace(delstr,"==","") delstr = Replace(delstr,"<","") delstr = Replace(delstr,">","") delstr = Replace(delstr,"%","") end function '-------------------------------------------------- '获取客户端IP的处理函数 '输出 IP '-------------------------------------------------- public function getip() Dim addr, x, y x = request.ServerVariables("HTTP_X_FORWARDED_FOR") y = request.ServerVariables("REMOTE_ADDR") if(isN(x) or lCase(x)="unknown")then addr=y else addr=x end if if InStr(addr,".")=0 Then addr = "0.0.0.0" getip = addr end function '-------------------------------------------------- '判断字段是否为空的处理函数 '输出 true or false '-------------------------------------------------- private function isN(ByVal s) isN = False Select Case VarType(s) Case vbEmpty, vbNull isN = True : Exit Function Case vbString If s="" Then isN = True : Exit Function Case vbObject Select Case TypeName(s) Case "Nothing","Empty" isN = True : Exit Function Case "Recordset" If s.State = 0 Then isN = True : Exit Function If s.Bof And s.Eof Then isN = True : Exit Function Case "Dictionary" If s.Count = 0 Then isN = True : Exit Function End Select Case vbArray,8194,8204,8209 If Ubound(s)=-1 Then isN = True : Exit Function End Select end function End Class Private Const BITS_TO_A_BYTE = 8 Private Const BYTES_TO_A_WORD = 4 Private Const BITS_TO_A_WORD = 32 Class cls_alipay_md5 '功能:支付宝MD5加密处理核心文件,不需要修改 '版本:3.0 '修改日期:2010-05-27 private s_input_charset Private m_lOnBits(30) Private m_l2Power(30) Public Property Let input_charset(byval val) s_input_charset = val End Property Public Property Get input_charset() input_charset = s_input_charset End Property Private Function LShift(lValue, iShiftBits) If iShiftBits = 0 Then LShift = lValue Exit Function ElseIf iShiftBits = 31 Then If lValue And 1 Then LShift = &H80000000 Else LShift = 0 End If Exit Function ElseIf iShiftBits < 0 Or iShiftBits > 31 Then Err.Raise 6 End If If (lValue And m_l2Power(31 - iShiftBits)) Then LShift = ((lValue And m_lOnBits(31 - (iShiftBits + 1))) * m_l2Power(iShiftBits)) Or &H80000000 Else LShift = ((lValue And m_lOnBits(31 - iShiftBits)) * m_l2Power(iShiftBits)) End If End Function Private Function str2bin(varstr) Dim varasc Dim i Dim varchar Dim varlow Dim varhigh str2bin="" For i=1 To Len(varstr) varchar=mid(varstr,i,1) varasc = Asc(varchar) If varasc<0 Then varasc = varasc + 65535 End If If varasc>255 Then varlow = Left(Hex(Asc(varchar)),2) varhigh = right(Hex(Asc(varchar)),2) str2bin = str2bin & chrB("&H" & varlow) & chrB("&H" & varhigh) Else str2bin = str2bin & chrB(AscB(varchar)) End If Next End Function Private Function str2bin_utf(varstr) Dim varchar, code, codearr, j, i str2bin_utf = "" For i=1 To Len(varstr) varchar = Mid(varstr,i,1) code = Server.UrlEncode(varchar) If(code="+") Then code="%20" If Len(code) = 1 Then str2bin_utf = str2bin_utf & chrB(AscB(code)) Else codearr = Split(code,"%") For j = 1 to UBound(codearr) str2bin_utf = str2bin_utf & ChrB("&H" & codearr(j)) Next End If Next End Function Private Function RShift(lValue, iShiftBits) If iShiftBits = 0 Then RShift = lValue Exit Function ElseIf iShiftBits = 31 Then If lValue And &H80000000 Then RShift = 1 Else RShift = 0 End If Exit Function ElseIf iShiftBits < 0 Or iShiftBits > 31 Then Err.Raise 6 End If RShift = (lValue And &H7FFFFFFE) \ m_l2Power(iShiftBits) If (lValue And &H80000000) Then RShift = (RShift Or (&H40000000 \ m_l2Power(iShiftBits - 1))) End If End Function Private Function RotateLeft(lValue, iShiftBits) RotateLeft = LShift(lValue, iShiftBits) Or RShift(lValue, (32 - iShiftBits)) End Function Private Function AddUnsigned(lX, lY) Dim lX4 Dim lY4 Dim lX8 Dim lY8 Dim lResult lX8 = lX And &H80000000 lY8 = lY And &H80000000 lX4 = lX And &H40000000 lY4 = lY And &H40000000 lResult = (lX And &H3FFFFFFF) + (lY And &H3FFFFFFF) If lX4 And lY4 Then lResult = lResult Xor &H80000000 Xor lX8 Xor lY8 ElseIf lX4 Or lY4 Then If lResult And &H40000000 Then lResult = lResult Xor &HC0000000 Xor lX8 Xor lY8 Else lResult = lResult Xor &H40000000 Xor lX8 Xor lY8 End If Else lResult = lResult Xor lX8 Xor lY8 End If AddUnsigned = lResult End Function Private Function md5_F(x, y, z) md5_F = (x And y) Or ((Not x) And z) End Function Private Function md5_G(x, y, z) md5_G = (x And z) Or (y And (Not z)) End Function Private Function md5_H(x, y, z) md5_H = (x Xor y Xor z) End Function Private Function md5_I(x, y, z) md5_I = (y Xor (x Or (Not z))) End Function Private Sub md5_FF(a, b, c, d, x, s, ac) a = AddUnsigned(a, AddUnsigned(AddUnsigned(md5_F(b, c, d), x), ac)) a = RotateLeft(a, s) a = AddUnsigned(a, b) End Sub Private Sub md5_GG(a, b, c, d, x, s, ac) a = AddUnsigned(a, AddUnsigned(AddUnsigned(md5_G(b, c, d), x), ac)) a = RotateLeft(a, s) a = AddUnsigned(a, b) End Sub Private Sub md5_HH(a, b, c, d, x, s, ac) a = AddUnsigned(a, AddUnsigned(AddUnsigned(md5_H(b, c, d), x), ac)) a = RotateLeft(a, s) a = AddUnsigned(a, b) End Sub Private Sub md5_II(a, b, c, d, x, s, ac) a = AddUnsigned(a, AddUnsigned(AddUnsigned(md5_I(b, c, d), x), ac)) a = RotateLeft(a, s) a = AddUnsigned(a, b) End Sub Private Function ConvertToWordArray(sMessage) Dim lMessageLength Dim lNumberOfWords Dim lWordArray() Dim lBytePosition Dim lByteCount Dim lWordCount Const MODULUS_BITS = 512 Const CONGRUENT_BITS = 448 lMessageLength = LenB(sMessage) lNumberOfWords = (((lMessageLength + ((MODULUS_BITS - CONGRUENT_BITS) \ BITS_TO_A_BYTE)) \ (MODULUS_BITS \ BITS_TO_A_BYTE)) + 1) * (MODULUS_BITS \ BITS_TO_A_WORD) ReDim lWordArray(lNumberOfWords - 1) lBytePosition = 0 lByteCount = 0 Do Until lByteCount >= lMessageLength lWordCount = lByteCount \ BYTES_TO_A_WORD lBytePosition = (lByteCount Mod BYTES_TO_A_WORD) * BITS_TO_A_BYTE lWordArray(lWordCount) = lWordArray(lWordCount) Or LShift(AscB(MidB(sMessage, lByteCount + 1, 1)), lBytePosition) lByteCount = lByteCount + 1 Loop lWordCount = lByteCount \ BYTES_TO_A_WORD lBytePosition = (lByteCount Mod BYTES_TO_A_WORD) * BITS_TO_A_BYTE lWordArray(lWordCount) = lWordArray(lWordCount) Or LShift(&H80, lBytePosition) lWordArray(lNumberOfWords - 2) = LShift(lMessageLength, 3) lWordArray(lNumberOfWords - 1) = RShift(lMessageLength, 29) ConvertToWordArray = lWordArray End Function Private Function WordToHex(lValue) Dim lByte Dim lCount For lCount = 0 To 3 lByte = RShift(lValue, lCount * BITS_TO_A_BYTE) And m_lOnBits(BITS_TO_A_BYTE - 1) WordToHex = WordToHex & Right("0" & Hex(lByte), 2) Next End Function Public Function MD5(sMessage) m_lOnBits(0) = CLng(1) m_lOnBits(1) = CLng(3) m_lOnBits(2) = CLng(7) m_lOnBits(3) = CLng(15) m_lOnBits(4) = CLng(31) m_lOnBits(5) = CLng(63) m_lOnBits(6) = CLng(127) m_lOnBits(7) = CLng(255) m_lOnBits(8) = CLng(511) m_lOnBits(9) = CLng(1023) m_lOnBits(10) = CLng(2047) m_lOnBits(11) = CLng(4095) m_lOnBits(12) = CLng(8191) m_lOnBits(13) = CLng(16383) m_lOnBits(14) = CLng(32767) m_lOnBits(15) = CLng(65535) m_lOnBits(16) = CLng(131071) m_lOnBits(17) = CLng(262143) m_lOnBits(18) = CLng(524287) m_lOnBits(19) = CLng(1048575) m_lOnBits(20) = CLng(2097151) m_lOnBits(21) = CLng(4194303) m_lOnBits(22) = CLng(8388607) m_lOnBits(23) = CLng(16777215) m_lOnBits(24) = CLng(33554431) m_lOnBits(25) = CLng(67108863) m_lOnBits(26) = CLng(134217727) m_lOnBits(27) = CLng(268435455) m_lOnBits(28) = CLng(536870911) m_lOnBits(29) = CLng(1073741823) m_lOnBits(30) = CLng(2147483647) m_l2Power(0) = CLng(1) m_l2Power(1) = CLng(2) m_l2Power(2) = CLng(4) m_l2Power(3) = CLng(8) m_l2Power(4) = CLng(16) m_l2Power(5) = CLng(32) m_l2Power(6) = CLng(64) m_l2Power(7) = CLng(128) m_l2Power(8) = CLng(256) m_l2Power(9) = CLng(512) m_l2Power(10) = CLng(1024) m_l2Power(11) = CLng(2048) m_l2Power(12) = CLng(4096) m_l2Power(13) = CLng(8192) m_l2Power(14) = CLng(16384) m_l2Power(15) = CLng(32768) m_l2Power(16) = CLng(65536) m_l2Power(17) = CLng(131072) m_l2Power(18) = CLng(262144) m_l2Power(19) = CLng(524288) m_l2Power(20) = CLng(1048576) m_l2Power(21) = CLng(2097152) m_l2Power(22) = CLng(4194304) m_l2Power(23) = CLng(8388608) m_l2Power(24) = CLng(16777216) m_l2Power(25) = CLng(33554432) m_l2Power(26) = CLng(67108864) m_l2Power(27) = CLng(134217728) m_l2Power(28) = CLng(268435456) m_l2Power(29) = CLng(536870912) m_l2Power(30) = CLng(1073741824) Dim x Dim k Dim AA Dim BB Dim CC Dim DD Dim a Dim b Dim c Dim d Const S11 = 7 Const S12 = 12 Const S13 = 17 Const S14 = 22 Const S21 = 5 Const S22 = 9 Const S23 = 14 Const S24 = 20 Const S31 = 4 Const S32 = 11 Const S33 = 16 Const S34 = 23 Const S41 = 6 Const S42 = 10 Const S43 = 15 Const S44 = 21 If LCase(s_input_charset) = "utf-8" Then x = ConvertToWordArray(str2bin_utf(sMessage)) Else x = ConvertToWordArray(str2bin(sMessage)) End If a = &H67452301 b = &HEFCDAB89 c = &H98BADCFE d = &H10325476 For k = 0 To UBound(x) Step 16 AA = a BB = b CC = c DD = d md5_FF a, b, c, d, x(k + 0), S11, &HD76AA478 md5_FF d, a, b, c, x(k + 1), S12, &HE8C7B756 md5_FF c, d, a, b, x(k + 2), S13, &H242070DB md5_FF b, c, d, a, x(k + 3), S14, &HC1BDCEEE md5_FF a, b, c, d, x(k + 4), S11, &HF57C0FAF md5_FF d, a, b, c, x(k + 5), S12, &H4787C62A md5_FF c, d, a, b, x(k + 6), S13, &HA8304613 md5_FF b, c, d, a, x(k + 7), S14, &HFD469501 md5_FF a, b, c, d, x(k + 8), S11, &H698098D8 md5_FF d, a, b, c, x(k + 9), S12, &H8B44F7AF md5_FF c, d, a, b, x(k + 10), S13, &HFFFF5BB1 md5_FF b, c, d, a, x(k + 11), S14, &H895CD7BE md5_FF a, b, c, d, x(k + 12), S11, &H6B901122 md5_FF d, a, b, c, x(k + 13), S12, &HFD987193 md5_FF c, d, a, b, x(k + 14), S13, &HA679438E md5_FF b, c, d, a, x(k + 15), S14, &H49B40821 md5_GG a, b, c, d, x(k + 1), S21, &HF61E2562 md5_GG d, a, b, c, x(k + 6), S22, &HC040B340 md5_GG c, d, a, b, x(k + 11), S23, &H265E5A51 md5_GG b, c, d, a, x(k + 0), S24, &HE9B6C7AA md5_GG a, b, c, d, x(k + 5), S21, &HD62F105D md5_GG d, a, b, c, x(k + 10), S22, &H2441453 md5_GG c, d, a, b, x(k + 15), S23, &HD8A1E681 md5_GG b, c, d, a, x(k + 4), S24, &HE7D3FBC8 md5_GG a, b, c, d, x(k + 9), S21, &H21E1CDE6 md5_GG d, a, b, c, x(k + 14), S22, &HC33707D6 md5_GG c, d, a, b, x(k + 3), S23, &HF4D50D87 md5_GG b, c, d, a, x(k + 8), S24, &H455A14ED md5_GG a, b, c, d, x(k + 13), S21, &HA9E3E905 md5_GG d, a, b, c, x(k + 2), S22, &HFCEFA3F8 md5_GG c, d, a, b, x(k + 7), S23, &H676F02D9 md5_GG b, c, d, a, x(k + 12), S24, &H8D2A4C8A md5_HH a, b, c, d, x(k + 5), S31, &HFFFA3942 md5_HH d, a, b, c, x(k + 8), S32, &H8771F681 md5_HH c, d, a, b, x(k + 11), S33, &H6D9D6122 md5_HH b, c, d, a, x(k + 14), S34, &HFDE5380C md5_HH a, b, c, d, x(k + 1), S31, &HA4BEEA44 md5_HH d, a, b, c, x(k + 4), S32, &H4BDECFA9 md5_HH c, d, a, b, x(k + 7), S33, &HF6BB4B60 md5_HH b, c, d, a, x(k + 10), S34, &HBEBFBC70 md5_HH a, b, c, d, x(k + 13), S31, &H289B7EC6 md5_HH d, a, b, c, x(k + 0), S32, &HEAA127FA md5_HH c, d, a, b, x(k + 3), S33, &HD4EF3085 md5_HH b, c, d, a, x(k + 6), S34, &H4881D05 md5_HH a, b, c, d, x(k + 9), S31, &HD9D4D039 md5_HH d, a, b, c, x(k + 12), S32, &HE6DB99E5 md5_HH c, d, a, b, x(k + 15), S33, &H1FA27CF8 md5_HH b, c, d, a, x(k + 2), S34, &HC4AC5665 md5_II a, b, c, d, x(k + 0), S41, &HF4292244 md5_II d, a, b, c, x(k + 7), S42, &H432AFF97 md5_II c, d, a, b, x(k + 14), S43, &HAB9423A7 md5_II b, c, d, a, x(k + 5), S44, &HFC93A039 md5_II a, b, c, d, x(k + 12), S41, &H655B59C3 md5_II d, a, b, c, x(k + 3), S42, &H8F0CCC92 md5_II c, d, a, b, x(k + 10), S43, &HFFEFF47D md5_II b, c, d, a, x(k + 1), S44, &H85845DD1 md5_II a, b, c, d, x(k + 8), S41, &H6FA87E4F md5_II d, a, b, c, x(k + 15), S42, &HFE2CE6E0 md5_II c, d, a, b, x(k + 6), S43, &HA3014314 md5_II b, c, d, a, x(k + 13), S44, &H4E0811A1 md5_II a, b, c, d, x(k + 4), S41, &HF7537E82 md5_II d, a, b, c, x(k + 11), S42, &HBD3AF235 md5_II c, d, a, b, x(k + 2), S43, &H2AD7D2BB md5_II b, c, d, a, x(k + 9), S44, &HEB86D391 a = AddUnsigned(a, AA) b = AddUnsigned(b, BB) c = AddUnsigned(c, CC) d = AddUnsigned(d, DD) Next MD5 = LCase(WordToHex(a) & WordToHex(b) & WordToHex(c) & WordToHex(d)) End Function End Class %>