用asp獲取文件md5值

  網上asp加密字符的MD5很多,也很普遍,但是對文件進行md5的確很少,因爲受到asp語言本身的限制。我們知道字符串的md5可以對明文進行不可逆的加密,從而保證數據儲存或者傳送的安全性。同樣的,對文件進行md5加密也是爲了保證在網絡傳送時不被修改和校驗,另外還有一個用途就是在個人站點裏面的應用:可以保證上傳的圖片或文件具有唯一性。原理是,上傳到服務器之後,同時在數據庫中記錄該上傳文件的md5值,這樣在下次傳同樣文件的時候,可以通過查詢數據庫是否是相同的文件,md5值相同,我們就認爲它是相同的文件,md5值就是文件的「身份證」,其實百度也有這方面的應用,在百度搜索圖片,點開圖片後,有時候會出現「您還可以點擊以下鏈接查看到這張圖片:XXX網址」,原理也是一樣,對文件進行md5。
  廢話少說,開始正文。
  一、asp通過xml交互方式調用.Net程序實現文件md5
  asp由于本身語言的限制,無法實現文件的md5,但是.net確可以,那是不是可以通過.net對文件進行md5,然後發送信息給asp接收,這樣就可以做到asp的md5了呢,答案是肯定的。這裏涉及到asp與.net程序間的交互,我以前寫過一個asp的類:《asp處理xml數據的發送、接收類》,可以上我的百度空間看:http://hi.baidu.com/manbutianmi/blog/item/dec182fc6db36587b801a0f6.html,講的是asp處理xml數據的發送與接收,可用于各種異構系統之間API接口間通訊。本文正好是這個類的一個應用。代碼如下:
  asp端代碼
  xmlcls.asp
  <%
  Rem 處理xml數據的發送、接收類
  '--------------------------------------------------
  '轉載的時候必須保留此版權信息
  '作者:walkman
  '網址:手機主題網:http://www.shouji138.com
  '版本:ver1.0
  '--------------------------------------------------
  Class XmlClass
  Rem 變量定義
  Private XmlDoc,XmlHttp
  Private MessageCode,SysKey,XmlPath
  Private m_GetXmlDoc,m_url
  Private m_XmlDocAccept
  Rem 初始化
  Private Sub Class_Initialize()
   On Error Resume Next
   MessageCode = ""
   XmlPath = ""
   Set XmlDoc = Server.CreateObject("msxml2.FreeThreadedDOMDocument.3.0")
   XmlDoc.ASYNC = False
  End Sub
  Rem 銷毀對象
  Private Sub Class_Terminate()
   If IsObject(XmlDoc) Then Set XmlDoc = Nothing
   If IsObject(m_XmlDocAccept) Then Set m_XmlDocAccept = Nothing
   If IsObject(m_GetXmlDoc) Then Set m_GetXmlDoc = Nothing
  End Sub
  '公共屬性定義開始--------------------------
  Rem 錯誤信息
  Public Property Get Message()
   Message = MessageCode
  End Property
  Rem 發送xml的地址
  Public Property Let URL(str)
   m_url = str
  End Property
  '公共屬性定義結束--------------------------
  '私有過程、方法開始--------------------------
  Rem 加載xml
  Private Sub LoadXmlData()
   If XmlPath <> "" Then
   If Not XmlDoc.Load(XmlPath) Then
   XmlDoc.LoadXml "<?xml version=""1.0"" encoding=""gb2312""?><root/>"
   End If
   Else
   XmlDoc.LoadXml "<?xml version=""1.0"" encoding=""gb2312""?><root/>"
   End If
  End Sub
  Rem 字符轉化
  Private Function AnsiToUnicode(ByVal str)
   Dim i, j, c, i1, i2, u, fs, f, p
   AnsiToUnicode = ""
   p = ""
   For i = 1 To Len(str)
   c = Mid(str, i, 1)
   j = AscW(c)
   If j < 0 Then
   j = j + 65536
   End If
   If j >= 0 And j <= 128 Then
   If p = "c" Then
   AnsiToUnicode = " " & AnsiToUnicode
   p = "e"
   End If
   AnsiToUnicode = AnsiToUnicode & c
   Else
   If p = "e" Then
   AnsiToUnicode = AnsiToUnicode & " "
   p = "c"
   End If
   AnsiToUnicode = AnsiToUnicode & ("&#" & j & ";")
   End If
   Next
  End Function
  Rem 字符轉化
  Private Function strAnsi2Unicode(asContents)
   Dim len1,i,varchar,varasc
   strAnsi2Unicode = ""
   len1=LenB(asContents)
   If len1=0 Then Exit Function
   For i=1 to len1
   varchar=MidB(asContents,i,1)
   varasc=AscB(varchar)
   If varasc > 127 Then
   If MidB(asContents,i+1,1)<>"" Then
   strAnsi2Unicode = strAnsi2Unicode & chr(ascw(midb(asContents,i+1,1) & varchar))
   End If
   i=i+1
   Else
   strAnsi2Unicode = strAnsi2Unicode & Chr(varasc)
   End If
   Next
  End Function
  Rem 往文件中追加字符
  Private Sub WriteStringToFile(filename,str)
   On Error Resume Next
   Dim fs,ts
   Set fs= createobject("script_ing.filesystemobject")
   If Not IsObject(fs) Then Exit Sub
   Set ts=fs.OpenTextFile(Server.MapPath(filename),8,True)
   ts.writeline(str)
   ts.close
   Set ts=Nothing
   Set fs=Nothing
  End Sub
  '私有過程、方法結束--------------------------
  '公共方法開始--www.devdao.com------------------------
  '''''''''''發送xml部分開始
  Rem 從外部xml文件填充XmlDoc對象
  Public Sub LoadXmlFromFile(path)
   XmlPath = Server.MapPath(path)
   LoadXmlData()
  End Sub
  Rem 用字符串填充XmlDoc對象
  Public Sub LoadXmlFromString(str)
   XmlDoc.LoadXml str
  End Sub
  Rem 設置node的參數 如 NodeValue "appID",AppID,1,False
  '--------------------------------------------------
  '參數 :
  'NodeName 節點名
  'NodeText 值
  'NodeType 保存類型 [text=0,cdata=1]
  'blnEncode 是否編碼 [true,false]
  '--------------------------------------------------
  Public Sub NodeValue(Byval NodeName,Byval NodeText,Byval NodeType ,Byval blnEncode)
   Dim ChildNode,CreateCDATASection
   NodeName = Lcase(NodeName)
   If XmlDoc.documentElement.selectSingleNode(NodeName) is nothing Then
   Set ChildNode = XmlDoc.documentElement.appendChild(XmlDoc.createNode(1,NodeName,""))
   Else
   Set ChildNode = XmlDoc.documentElement.selectSingleNode(NodeName)
   End If
   If blnEncode = True Then
   NodeText = AnsiToUnicode(NodeText)
   End If
   If NodeType = 1 Then
   ChildNode.Text = ""
   Set CreateCDATASection = XmlDoc.createCDATASection(Replace(NodeText,"]]>","]]&gt;"))
   ChildNode.appendChild(createCDATASection)
   Else
   ChildNode.Text = NodeText
   End If
  End Sub
  '--------------------------------------------------
  '獲取發送包XML中節點的值
  '參數 :
  'Str 節點名
  '--------------------------------------------------
  Public Property Get XmlNode(Byval Str)
   If XmlDoc.documentElement.selectSingleNode(Str) is Nothing Then
   XmlNode = "Null"
   Else
   XmlNode = XmlDoc.documentElement.selectSingleNode(Str).text
   End If
  End Property
  '--------------------------------------------------
  '獲取返回XML數據對象
  '例:
  '當GetXmlData不爲NULL時,GetXmlData爲XML對象
  '--------------------------------------------------
  Public Property Get GetXmlData()
   Set GetXmlData = m_GetXmlDoc
  End Property
  '--------------------------------------------------
  '發送xml包
  '--------------------------------------------------
  Public Sub SendHttpData()
   Dim i,GetXmlDoc,LoadAppid
   Set Xmlhttp = Server.CreateObject("MSXML2.ServerXMLHTTP.3.0")
   Set GetXmlDoc = Server.CreateObject("msxml2.FreeThreadedDOMDocument.3.0") ' 返回xml包
   XmlHttp.Open "POST", m_url, false
   XmlHttp.SetRequestHeader "content-type", "text/xml"
   XmlHttp.Send XmlDoc
   'Response.Write strAnsi2Unicode(xmlhttp.responseBody)
   If GetXmlDoc.load(XmlHttp.responseXML) Then
   Set m_GetXmlDoc = GetXmlDoc
   Else
   MessageCode = "請求數據錯誤!"
   Exit Sub
   End If
   Set GetXmlDoc = Nothing
   Set XmlHttp = Nothing
  End Sub
  
  
  '--------------------------------------------------
  '打印發送請求XML數據
  '--------------------------------------------------
  Public Sub PrintSendXmlData()
   Response.Clear
   Response.ContentType = "text/xml"
   Response.CharSet = "gb2312"
   Response.Expires = 0
   Response.Write "<?xml version=""1.0"" encoding=""gb2312""?>"&vbNewLine
   Response.Write XmlDoc.documentElement.XML
  End Sub
  '--------------------------------------------------
  '打印返回XML數據
  '--------------------------------------------------
  Public Sub PrintGetXmlData()
  
   Response.Clear
   Response.ContentType = "text/xml"
   Response.CharSet = "gb2312"
   Response.Expires = 0
   If IsObject(m_GetXmlDoc) Then
   Response.Write "<?xml version=""1.0"" encoding=""gb2312""?>"&vbNewLine
   Response.Write m_GetXmlDoc.documentElement.XML
   Else
   Response.Write "<?xml version=""1.0"" encoding=""gb2312""?><root></root>"
   End If
  End Sub
  Rem 保存發送請求xml數據到文件,文件名爲sendxml_日期.txt
  Public Sub SaveSendXmlDataToFile()
   Dim filename,str
   filename = "sendxml_" & DateValue(now) & ".txt"
   str = ""
   str = str & ""& Now() & vbNewLine
   str = str & "---------------------------------------------"& vbNewLine
   str = str & "<?xml version=""1.0"" encoding=""gb2312""?>" & vbNewLine
   str = str & XmlDoc.documentElement.XML & vbNewLine
   str = str & "---------------------------------------------"& vbNewLine
   str = str & vbNewLine & vbNewLine & vbNewLine
   WriteStringToFile filename,str
  End Sub
  Rem 保存返回XML數據到文件,文件名爲getxml_日期.txt
  Public Sub SaveGetXmlDataToFile()
   Dim filename,str
   filename = "getxml_" & DateValue(now) & ".txt"
   str = ""
   str = str & ""& Now() & vbNewLine
   str = str & "---------------------------------------------"& vbNewLine
   If IsObject(m_GetXmlDoc) Then
   str = str & "<?xml version=""1.0"" encoding=""gb2312""?>" & vbNewLine
   str = str & m_GetXmlDoc.documentElement.XML
   Else
   str = str & "<?xml version=""1.0"" encoding=""gb2312""?>" & vbNewLine & "<root>" & vbNewLine & "</root>"
   End If
   str = str & vbNewLine
   str = str & "---------------------------------------------"& vbNewLine
   str = str & vbNewLine & vbNewLine & vbNewLine
   WriteStringToFile filename,str
  End Sub
  
  '--------------------------------------------------
  '獲取返回xml的節點信息
  'XmlClassObj.GetSingleNode("//msg")
  '--------------------------------------------------
  Public Function GetSingleNode(nodestring)
   If IsObject(m_GetXmlDoc) Then
   GetSingleNode = m_GetXmlDoc.documentElement.selectSingleNode(nodestring).text
   Else
   GetSingleNode = ""
   End If
  End Function
  ''''''''''''''''''發送xml部分結束
  
  ''''''''''''''''''接收xml部分開始
  '--------------------------------------------------
  '接收XML包,錯誤信息通過Message對象獲取
  '--------------------------------------------------
  Public Function AcceptHttpData()
   Dim XMLdom
   Set XMLdom = Server.CreateObject("Microsoft.XMLDOM")
   XMLdom.Async = False
   XMLdom.Load(Request)
   If XMLdom.parseError.errorCode <> 0 Then
   MessageCode = "不能正確接收數據" & "Descript_ion: " & XMLdom.parseError.reason & "<br>Line: " & XMLdom.parseError.Line
   Set m_XmlDocAccept = Null
   Else
   Set m_XmlDocAccept = XMLdom
   End If
  End Function
  '--------------------------------------------------
  '返回接收XML包節點信息
  'XmlClassObj.GetSingleNode("//msg")
  '--------------------------------------------------
  Public Function AcceptSingleNode(nodestring)
   If IsObject(m_XmlDocAccept) Then
   AcceptSingleNode = m_XmlDocAccept.documentElement.selectSingleNode(nodestring).text
   Else
   AcceptSingleNode = ""
   End If
  End Function
  '--------------------------------------------------
  '打印接收端接收到的XML數據
  '--------------------------------------------------
  Public Sub PrintAcceptXmlData()
   Response.Clear
   Response.ContentType = "text/xml"
   Response.CharSet = "gb2312"
   Response.Expires = 0
   If IsObject(m_XmlDocAccept) Then
   Response.Write "<?xml version=""1.0"" encoding=""gb2312""?>"&vbNewLine
   Response.Write m_XmlDocAccept.documentElement.XML
   Else
   Response.Write "<?xml version=""1.0"" encoding=""gb2312""?><root></root>"
   End If
  End Sub
  Rem 保存接收的XML包數據到文件,文件名爲acceptxml_日期.txt
  Public Sub SaveAcceptXmlDataToFile()
   Dim filename,str
   filename = "acceptxml_" & DateValue(now) & ".txt"
   str = ""
   str = str & ""& Now() & vbNewLine
   str = str & "---------------------------------------------"& vbNewLine
   If IsObject(m_XmlDocAccept) Then
   str = str & "<?xml version=""1.0"" encoding=""gb2312""?>" & vbNewLine
   str = str & m_XmlDocAccept.documentElement.XML
   Else
   str = str & "<?xml version=""1.0"" encoding=""gb2312""?>" & vbNewLine & "<root>" & vbNewLine & "</root>"
   End If
   str = str & vbNewLine
   str = str & "---------------------------------------------"& vbNewLine
   str = str & vbNewLine & vbNewLine & vbNewLine
   WriteStringToFile filename,str
  End Sub
  ''''''''''''''''''接收xml部分結束
  Rem 保存調試數據到文件,文件名爲debugnote_日期.txt
  Public Sub SaveDebugStringToFile(debugstr)
   Dim filename,str
   filename = "debugnote_" & DateValue(now) & ".txt"
   str = ""
   str = str & ""& Now() & vbNewLine
   str = str & "---------------------------------------------"& vbNewLine
   str = str & debugstr & vbNewLine
   str = str & "---------------------------------------------"
   str = str & vbNewLine & vbNewLine & vbNewLine
   WriteStringToFile filename,str
  End Sub
  '公共方法結束--------------------------
  End Class
  %>
  filemd5fun.asp
  <!--#Include File="xmlcls.asp"-->
  <%
  Rem 取得文件的md5,參數爲文件名
  Function GetFileMD5(filename)
  Const Apisysno = "k8n6g2b0m1a6b0f6e8" '接口的Key值,防止被非法適用 接口應該保持一致
  Dim XmlClassObj
  Set XmlClassObj = new XmlClass '創建對象
  XmlClassObj.LoadXmlFromString("<?xml version=""1.0"" encoding=""gb2312""?><root/>") '用xml字符填充XMLDOC對象,用來發送xml
  XmlClassObj.URL = "http://www.shouji138.com/aspnet2/FileMD5.aspx" '設置響應的url,這裏應該改成你的網址
  Rem xml格式
  Rem "<?xml version="1.0" encoding="gb2312"?>
  Rem <root>
  Rem <sysno></sysno>
  Rem <apiaction></apiaction>
  Rem <filename></filename>
  Rem </root>
  XmlClassObj.NodeValue "sysno",Apisysno,0,False '接口的Key值,防止被非法適用
  XmlClassObj.NodeValue "apiaction","createfilemd5",0,False '接口的響應動作,用于定義一個接口用于多種用途
  XmlClassObj.NodeValue "filename",filename,0,False '文件路徑和文件名,用相對路徑
  'XmlClassObj.SaveSendXmlDataToFile() '將發送的xml數據庫包存入txt文件,用于調試之用
  XmlClassObj.SendHttpData() '發送xml數據
  'XmlClassObj.SaveGetXmlDataToFile() '保存接收到的xml數據
  Rem 處理結果
  Dim message,status
  status = XmlClassObj.GetSingleNode("//status") '顯示狀態,如果爲OK則表示成功,否則有錯誤發生
  message = XmlClassObj.GetSingleNode("//message") '顯示取到的MD5值,如果status不爲OK,則message爲錯誤信息
  Set XmlClassObj = Nothing
  If status = "OK" Then
   GetFileMD5 = message
  Else
   GetFileMD5 = ""
  End If
  End Function
  %>
  test.asp
  <!--#Include File="filemd5fun.asp"-->
  <%
  Response.Write "web.config的md5值是:" & GetFileMD5("web.config") & "<br />"
  Response.Write "files/logo-yy.gif的md5值是:" & GetFileMD5("files/logo-yy.gif") & "<br />"
  Response.Write "xmlcls.asp的md5值是:" & GetFileMD5("xmlcls.asp") & "<br />"
  %>
  .net端代碼:
  MD5.cs
  using System;
  using System.Collections.Generic;
  using System.Text;
  using System.IO;
  namespace Winsteps.FileMD5
  {
   public class MD5
   {
   public static string md5_hash(string path)
   {
   try
   {
   FileStream get_file = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
   System.Security.Cryptography.MD5CryptoServiceProvider get_md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
   byte[] hash_byte = get_md5.ComputeHash(get_file);
   string resule = System.BitConverter.ToString(hash_byte);
   resule = resule.Replace("-", "");
   return resule;
   }
   catch (Exception e)
   {
   return e.Message;
   }
   }
   }
  }
  FileMD5.aspx
  <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="FileMD5.aspx.cs" Inherits="Winsteps.FileMD5.FileMD5" %>
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  <html xmlns="http://www.w3.org/1999/xhtml" >
  <head runat="server">
   <title>手機主題網:http://www.shouji138.com</title>
  </head>
  <body>
   <form id="form1" runat="server">
   <div>
  
   </div>
   </form>
  </body>
  </html>
  FileMD5.aspx.cs
  using System;
  using System.Data;
  using System.Configuration;
  using System.Collections;
  using System.Web;
  using System.Web.Security;
  using System.Web.UI;
  using System.Web.UI.WebControls;
  using System.Web.UI.WebControls.WebParts;
  using System.Web.UI.HtmlControls;
  using System.Xml;
  using System.Configuration;
  namespace Winsteps.FileMD5
  {
   public partial class FileMD5 : System.Web.UI.Page
   {
   protected void Page_Load(object sender, EventArgs e)
   {
   string sysno = "11111";
   string status = "False";
   string message = "未指定的錯誤";
   string net2sysno = ConfigurationManager.AppSettings["sysno"];
   XmlDocument doc = new XmlDocument();
   try
   {
  
   doc.Load(Request.InputStream);
   sysno = doc.SelectSingleNode("//sysno").InnerText.Trim();
   if (net2sysno != sysno)
   {
   message = "非法適用!";
   }
   else
   {
   string filename = Server.MapPath(doc.SelectSingleNode("//filename").InnerText.Trim());
   message = MD5.md5_hash(filename);
   status = "OK";
   }
   }
   catch(Exception ex)
   {
   message = ex.Message;
   }
   finally
   {
   if (doc != null)
   doc = null;
   }
   Response.Clear(); //清楚html字符
   Response.ContentType = "text/xml";
   Response.Charset = "GB2312";//如果xml字符串中包含中文
   Response.Write("<?xml version=\"1.0\" encoding=\"GB2312\"?>");
   Response.Write("<root>");
   Response.Write(" <status>" + status + "</status>");
   Response.Write(" <message>" + message + "</message>");
   Response.Write("</root>");
   Response.End();
   }
   }
  }
  Web.config
  <?xml version="1.0" encoding="utf-8"?>
  <configuration>
   <appSettings>
   <add key="sysno" value="k8n6g2b0m1a6b0f6e8"></add>
   </appSettings>
   <system.web>
   <httpRuntime executionTimeout="3600" maxRequestLength="1048576"/>
   <compilation debug="true" defaultLanguage="c#" />
   <customErrors mode="Off" />
   <identity impersonate="true"/>
   <authentication mode="Forms">
   <forms name="forums" path="/" loginUrl="Login.aspx" protection="All" timeout="40">
   </forms>
   </authentication>
   <pages validateRequest="false"></pages>
   <globalization requestEncoding="gb2312" responseEncoding="gb2312" culture="zh-CN" uiCulture="zh-CN"/>
   </system.web>
  </configuration>
  web.config的sysno要跟filemd5fun.asp裏面的Apisysno保持一致,具體應用時應該要把這個key改成你自己的值來保證安全。
  演示地址:http://www.shouji138.com/aspnet2/filemd5.asp
  代碼雖然長,但是原理簡單,asp發送xml數據給asp.net(xml中包含了要md5的文件名)->asp.net接收xml對文件進行md5->asp.net將結果通過xml返回給asp(xml中包含了獲取到的md5值)->asp獲取返回的xml,解析出md5值。
  應用範圍:
  1. 在兩個系統之間傳送文件時,可以在傳送前進行文件md5,傳送後進行文件md5,檢查兩值是否相等,如果相等則表示在傳送過程中沒有被修改。
  2. 做上傳系統中,如果要求不能上傳同文件的話,可以在上傳之後的文件進行md5存入數據庫中,這樣下次上傳同樣文件,則md5會相同,拒絕上傳。
  3. 在搜索引擎、迅雷本b2b軟件中,對文件md5,具有相同md5的文件被認爲是相同文件,而不管文件名是否相同,可以從多個源來分享文件。
  4. 其他應用。。。。。
  二、asp通過COM組件實現md5(需要在服務器上注冊組件)
  注冊一個asp的文件md5組件,下載地址:http://www.shouji138.com/aspnet2/files/aspmd5.rar
  然後將PARmf.dll文件拷貝到服務器的c:\WINDOWS\system32目錄,運行regsvr32 parmf.dll進行注冊,重啓IIS。
  調用代碼:
  <%
  Set DelphiASPObj = Server.CreateObject("PARmf.md5file")
   DelphiASPObj.in_path=Server.Mappath("Web.config") '文件路徑
   Response.Write "web.config的md5值是:" & DelphiASPObj.get_path_md5 & "<br />"
   Set DelphiASPObj=nothing
  %>
  三、兩種方式獲取文件md5的對比
  第一種方法通過與asp.net程序交互xml數據來得到文件的md5,需要服務器支持asp.net,一般的虛擬主機都提供asp.net環境,但是價格高點;
  第二種方法通過注冊COM組件實現,需要有服務器的權限,對于擁有服務器的比較合適。
  另外第一種方式的這種交互方法使得asp具有更大的靈活性,可以應用在2台不同的服務器上面進行數據交互,可廣泛應用于各種異構平台。
  四、下載地址
  請到偶的小站,手機主題網查看演示和下載程序包
  演示地址:http://www.shouji138.com/aspnet2/filemd5.asp
  程序下載打包下載:http://www.shouji138.com/aspnet2/files/FileMD5.rar
  asp的文件md5組件:http://www.shouji138.com/aspnet2/files/aspmd5.rar