Existem muitos MD5s para caracteres criptografados ASP na Internet e eles são muito comuns, mas MD5 para arquivos é realmente muito raro devido às limitações da própria linguagem ASP. Sabemos que o md5 de uma string pode criptografar texto simples de forma irreversível para garantir a segurança do armazenamento ou transmissão de dados. Da mesma forma, a criptografia md5 de arquivos também é usada para garantir que eles não sejam modificados e verificados durante a transmissão pela rede. Outro uso é em sites pessoais: pode garantir que as imagens ou arquivos carregados sejam exclusivos. O princípio é que após o upload para o servidor, o valor md5 do arquivo carregado é registrado no banco de dados ao mesmo tempo. Desta forma, na próxima vez que o mesmo arquivo for carregado, podemos consultar o banco de dados para ver se está. o mesmo arquivo. Se o valor md5 for o mesmo, consideraremos que é o mesmo. Para arquivos, o valor md5 é o "cartão de identificação" do arquivo. para fotos no Baidu e clicar na imagem, às vezes "Você também pode clicar no seguinte link para ver esta imagem: XXX URL" , o princípio é o mesmo, md5 o arquivo.
Sem mais delongas, vamos começar.
1. asp chama o programa .Net por meio do modo interativo xml para implementar o arquivo md5
Devido às limitações de sua própria linguagem, o asp não pode implementar o md5 dos arquivos, mas o .net pode sim fazer isso. É possível realizar o md5 no arquivo através do .net e depois enviar as informações para o asp para recebê-las, para que. o md5 do asp pode ser alcançado. Resposta Isso é certo. Isso envolve a interação entre programas ASP e .NET . Já escrevi uma classe ASP: "ASP Processing XML Data Sending and Reception Classes". /blog/item/dec182fc6db36587b801a0f6.html trata do processamento asp de envio e recebimento de dados xml e pode ser usado para comunicação entre interfaces API entre vários sistemas heterogêneos. Este artigo é uma aplicação desta classe. O código é o seguinte:
código lateral asp
xmlcls.asp
<%
Rem lida com envio e recebimento de classes de dados XML
'------------------------------------------------ -
'Esta informação de direitos autorais deve ser mantida ao reimprimir
'Autor: walkman
'Site: Rede Temática Móvel: http://www.shouji138.com
'Versão: ver1.0
'------------------------------------------------ -
ClasseXmlClass
Definição de variável Rem
XmlDoc privado,XmlHttp
Código de mensagem privada, SysKey, XmlPath
Privado m_GetXmlDoc,m_url
Inicialização
privada m_XmlDocAccept
Rem
Subclasse Privada_Initialize()
Em caso de erro, retomar o próximo
CódigoMensagem = ""
XmlPath = ""
Definir XmlDoc = Server.CreateObject("msxml2.FreeThreadedDOMDocument.3.0")
XmlDoc.ASYNC = Falso
Finalizar sub
Rem destrói o objeto
Subclasse Privada_Terminate()
Se IsObject (XmlDoc) então defina XmlDoc = Nada
Se IsObject (m_XmlDocAccept) então defina m_XmlDocAccept = Nada
Se IsObject (m_GetXmlDoc) então defina m_GetXmlDoc = Nada
Finalizar sub
'A definição do atributo público começa--------------------------
Mensagem de erro Rem
Propriedade pública obter mensagem()
Mensagem = CódigodaMensagem
Fim da propriedade
Rem o endereço para enviar xml
Propriedade pública Deixe URL (str)
m_url=str
Fim da propriedade
'Fim da definição do atributo público--------------------------
'Início de processo e método privado--------------------------
Rem carregar xml
Sub LoadXmlData privado()
Se XmlPath <> "" Então
Se não for XmlDoc.Load (XmlPath) então
XmlDoc.LoadXml "<?xml version=""1.0"" encoding=""gb2312""?><root/>"
Terminar se
Outro
XmlDoc.LoadXml "<?xml version=""1.0"" encoding=""gb2312""?><root/>"
Terminar se
Fim da conversão de caracteres Sub
Rem
Função privada AnsiToUnicode (ByVal str)
Dim i, j, c, i1, i2, u, fs, f, p
AnsiToUnicode = ""
p = ""
Para i = 1 para Len(str)
c = Médio (str, i, 1)
j = AscW(c)
Se j < 0 Então
j = j + 65536
Terminar se
Se j >= 0 E j <= 128 Então
Se p = "c" Então
AnsiToUnicode = " " & AnsiToUnicode
p = "e"
Terminar se
AnsiToUnicode = AnsiToUnicode & c
Outro
Se p = "e" Então
AnsiToUnicode = AnsiToUnicode & " "
p = "c"
Terminar se
AnsiToUnicode = AnsiToUnicode & ("&#" & j & ";")
Terminar se
Próximo
Função final
Conversão de caracteres Rem
Função privada strAnsi2Unicode(asContents)
Dim len1,i,varchar,varasc
strAnsi2Unicode = ""
len1=LenB(asConteúdo)
Se len1 = 0, então saia da função
Para i=1 para len1
varchar=MidB(asContents,i,1)
varasc=AscB(varchar)
Se varasc > 127 Então
Se MidB(asContents,i+1,1)<>"" Então
strAnsi2Unicode = strAnsi2Unicode & chr(ascw(midb(asContents,i+1,1) & varchar))
Terminar se
eu=eu+1
Outro
strAnsi2Unicode = strAnsi2Unicode & Chr(varasc)
Terminar se
Próximo
Função final
Rem acrescenta caracteres ao arquivo
Sub privado WriteStringToFile (nome do arquivo, str)
Em caso de erro, retomar o próximo
Dim fs,ts
Definir fs= createobject("script_ing.filesystemobject")
Se não for IsObject(fs), então saia do Sub
Definir ts=fs.OpenTextFile(Server.MapPath(nome do arquivo),8,True)
ts.writeline(str)
ts.fechar
Definir ts=Nada
Definir fs=Nada
Finalizar sub
'Fim do processo e método privado--------------------------
'O método público inicia--www.devdao.com------------------------
''''''''''' Envie a parte xml para começar
Rem preencher o objeto XmlDoc do arquivo xml externo
Sub LoadXmlFromFile público (caminho)
XmlPath = Servidor.MapPath(caminho)
CarregarXmlData()
Finalizar sub
Rem preencher objeto XmlDoc com string
Sub LoadXmlFromString público (str)
XmlDoc.LoadXml str
Finalizar sub
Rem define parâmetros de nó como NodeValue "appID",AppID,1,False
'------------------------------------------------ -
'parâmetro:
'NodeName nome do nó
'Valor NodeText
'Tipo de salvamento NodeType [text=0,cdata=1]
'blnEncode se deve codificar [true, false]
'------------------------------------------------ -
Sub NodeValue público (Byval NodeName, Byval NodeText, Byval NodeType, Byval blnEncode)
Dim ChildNode,CreateCDATASection
NodeName = Lcase(NodeName)
Se XmlDoc.documentElement.selectSingleNode(NodeName) não for nada, então
Definir ChildNode = XmlDoc.documentElement.appendChild(XmlDoc.createNode(1,NodeName,""))
Outro
Definir ChildNode = XmlDoc.documentElement.selectSingleNode(NodeName)
Terminar se
Se blnEncode = True então
NodeText = AnsiToUnicode(NodeText)
Terminar se
Se NodeType = 1 então
ChildNode.Text = ""
Definir CreateCDATASection = XmlDoc.createCDATASection(Replace(NodeText,"]]>","]]>"))
ChildNode.appendChild(criarCDATASection)
Outro
ChildNode.Text = NodeText
Terminar se
Finalizar sub
'------------------------------------------------ -
'Obtém o valor do nó no pacote XML enviado
'parâmetro:
'Str nome do nó
'------------------------------------------------ -
Propriedade pública GetXmlNode(ByvalStr)
Se XmlDoc.documentElement.selectSingleNode(Str) for nada, então
XmlNode = "Nulo"
Outro
XmlNode = XmlDoc.documentElement.selectSingleNode(Str).texto
Terminar se
Propriedade final
'---------------------------------------------------------- ----
'Obtém o objeto de dados XML retornado
'exemplo:
'Quando GetXmlData não é NULL, GetXmlData é um objeto XML
'------------------------------------------------ -
Propriedade Pública Obter GetXmlData()
Definir GetXmlData = m_GetXmlDoc
Fim da propriedade
'------------------------------------------------ -
'Enviar pacote xml
'------------------------------------------------ -
Sub público SendHttpData()
Dim i,GetXmlDoc,LoadAppid
Definir Xmlhttp = Server.CreateObject("MSXML2.ServerXMLHTTP.3.0")
Set GetXmlDoc = Server.CreateObject("msxml2.FreeThreadedDOMDocument.3.0") ' Retorna pacote xml
XmlHttp.Open "POST", m_url, falso
XmlHttp.SetRequestHeader "tipo de conteúdo", "texto/xml"
XmlHttp.Enviar XmlDoc
'Response.Write strAnsi2Unicode(xmlhttp.responseBody)
Se GetXmlDoc.load(XmlHttp.responseXML) Então
Definir m_GetXmlDoc = GetXmlDoc
Outro
MessageCode = "Erro ao solicitar dados!"
Sair do sub
Terminar se
Definir GetXmlDoc = Nada
Definir XmlHttp = Nada
Finalizar sub
'------------------------------------------------ -
'Imprime dados XML da solicitação de envio
'------------------------------------------------ -
Sub PrintSendXmlData() público
Resposta.Limpar
Response.ContentType = "texto/xml"
Response.CharSet = "gb2312"
Resposta.Expira = 0
Response.Write "<?xml version=""1.0"" encoding=""gb2312""?>"&vbNewLine
Response.Write XmlDoc.documentElement.XML
Finalizar sub
'------------------------------------------------ -
'Imprime dados XML retornados
'------------------------------------------------ -
Sub PrintGetXmlData() público
Resposta.Limpar
Response.ContentType = "texto/xml"
Response.CharSet = "gb2312"
Resposta.Expira = 0
Se IsObject(m_GetXmlDoc) então
Response.Write "<?xml version=""1.0"" encoding=""gb2312""?>"&vbNewLine
Response.Write m_GetXmlDoc.documentElement.XML
Outro
Response.Write "<?xml version=""1.0"" encoding=""gb2312""?><root></root>"
Terminar se
Finalizar sub
Rem salva os dados xml da solicitação de envio em um arquivo chamado sendxml_date.txt
Sub SaveSendXmlDataToFile() público
Dim nome do arquivo, str
nome do arquivo = "sendxml_" & DateValue (agora) & ".txt"
str = ""
str = str & ""& Now() & vbNewLine
str = str& "--------------------------------------------- --- "& vbNovaLinha
str = str & "<?xml version=""1.0"" encoding=""gb2312""?>" & vbNewLine
str = str & XmlDoc.documentElement.XML & vbNewLine
str = str& "--------------------------------------------- --- "& vbNovaLinha
str = str & vbNovaLinha & vbNovaLinha & vbNovaLinha
Nome do arquivo WriteStringToFile,str
Finalizar sub
Rem salva os dados XML retornados em um arquivo chamado getxml_date.txt
Sub SaveGetXmlDataToFile() público
Dim nome do arquivo, str
nome do arquivo = "getxml_" & DateValue (agora) & ".txt"
str = ""
str = str & ""& Now() & vbNewLine
str = str& "--------------------------------------------- --- "& vbNovaLinha
Se IsObject(m_GetXmlDoc) então
str = str & "<?xml version=""1.0"" encoding=""gb2312""?>" & vbNewLine
str = str & m_GetXmlDoc.documentElement.XML
Outro
str = str & "<?xml version=""1.0"" encoding=""gb2312""?>" & vbNewLine & "<root>" & vbNewLine & "</root>"
Terminar se
str = str & vbNovaLinha
str = str& "--------------------------------------------- --- "& vbNovaLinha
str = str & vbNovaLinha & vbNovaLinha & vbNovaLinha
Nome do arquivo WriteStringToFile,str
Finalizar sub
'------------------------------------------------ -
'Obtém as informações do nó do xml retornado
'XmlClassObj.GetSingleNode("//msg")
'------------------------------------------------ -
Função pública GetSingleNode(nodestring)
Se IsObject(m_GetXmlDoc) então
GetSingleNode = m_GetXmlDoc.documentElement.selectSingleNode(nodestring).text
Outro
GetSingleNode = ""
Terminar se
Função final
'''''''''''''''''Fim do envio da parte xml
'''''''''''''''''A parte de recebimento do xml começa
'------------------------------------------------ -
'Recebe pacote XML, informações de erro são obtidas através do objeto Message
'------------------------------------------------ -
Função pública AcceptHttpData()
Dim XMLdom
Definir XMLdom = Server.CreateObject("Microsoft.XMLDOM")
XMLdom.Async = Falso
XMLdom.Load(Solicitação)
Se XMLdom.parseError.errorCode <> 0 Então
MessageCode = "Não é possível receber dados corretamente" & "Descript_ion: " & XMLdom.parseError.reason & "<br>Line: " & XMLdom.parseError.Line
Definir m_XmlDocAccept = Nulo
Outro
Definir m_XmlDocAccept = XMLdom
Terminar se
Função final
'---------------------------------------------------------- ----
'Retorna para receber informações do nó do pacote XML
'XmlClassObj.GetSingleNode("//msg")
'------------------------------------------------ -
Função pública AcceptSingleNode(nodestring)
Se IsObject(m_XmlDocAccept) então
AcceptSingleNode = m_XmlDocAccept.documentElement.selectSingleNode(nodestring).text
Outro
AceitarSingleNode = ""
Terminar se
Função final
'------------------------------------------------ -
'Imprime os dados XML recebidos pelo destinatário
'------------------------------------------------ -
Sub PrintAcceptXmlData() público
Resposta.Limpar
Response.ContentType = "texto/xml"
Response.CharSet = "gb2312"
Resposta.Expira = 0
Se IsObject(m_XmlDocAccept) então
Response.Write "<?xml version=""1.0"" encoding=""gb2312""?>"&vbNewLine
Response.Write m_XmlDocAccept.documentElement.XML
Outro
Response.Write "<?xml version=""1.0"" encoding=""gb2312""?><root></root>"
Terminar se
Finalizar sub
Rem salva os dados do pacote XML recebido em um arquivo chamado acceptxml_date.txt
Sub SaveAcceptXmlDataToFile() público
Dim nome do arquivo, str
nome do arquivo = "acceptxml_" & DateValue (agora) & ".txt"
str = ""
str = str & ""& Now() & vbNewLine
str = str& "--------------------------------------------- --- "& vbNovaLinha
Se IsObject(m_XmlDocAccept) então
str = str & "<?xml version=""1.0"" encoding=""gb2312""?>" & vbNewLine
str = str & m_XmlDocAccept.documentElement.XML
Outro
str = str & "<?xml version=""1.0"" encoding=""gb2312""?>" & vbNewLine & "<root>" & vbNewLine & "</root>"
Terminar se
str = str & vbNovaLinha
str = str& "--------------------------------------------- --- "& vbNovaLinha
str = str & vbNovaLinha & vbNovaLinha & vbNovaLinha
Nome do arquivo WriteStringToFile,str
Finalizar sub
'''''''''''''''''Receba a parte xml e finalize
Rem Salve os dados de depuração em um arquivo chamado debugnote_date.txt.
Sub público SaveDebugStringToFile(debugstr)
Dim nome do arquivo, str
nome do arquivo = "debugnote_" & DateValue (agora) & ".txt"
str = ""
str = str & ""& Now() & vbNewLine
str = str& "--------------------------------------------- --- "& vbNovaLinha
str = str & debugstr & vbNewLine
str = str& "--------------------------------------------- --- "
str = str & vbNovaLinha & vbNovaLinha & vbNovaLinha
Nome do arquivo WriteStringToFile,str
End Sub
'Método público termina--------------------------
Fim da aula
%>
filemd5fun.asp
<!--#Include File="xmlcls.asp"-->
<%
Rem obtém o md5 do arquivo, o parâmetro é o nome do arquivo
Função GetFileMD5 (nome do arquivo)
Const Apisysno = "k8n6g2b0m1a6b0f6e8" 'O valor da chave da interface deve ser consistente para evitar aplicação ilegal da interface
DimXmlClassObj
Set XmlClassObj = new XmlClass 'Criar objeto
XmlClassObj.LoadXmlFromString("<?xml version=""1.0"" encoding=""gb2312""?><root/>") 'Preencha o objeto XMLDOC com caracteres xml e use-o para enviar xml
XmlClassObj.URL = " http://www.shouji138.com/aspnet2/FileMD5.aspx " 'Defina o URL de resposta, que deve ser alterado para o seu URL
Formato Rem XML
Rem "<?xml version="1.0" encoding="gb2312"?>
Rem <raiz>
Rem <sysno></sysno>
Rem <apiaction></apiaction>
Rem <nome do arquivo></nome do arquivo>
Rem </root>
XmlClassObj.NodeValue "sysno",Apisysno,0,False 'Valor chave da interface para evitar aplicações ilegais
XmlClassObj.NodeValue "apiaction","createfilemd5",0,False 'Ação de resposta da interface, usada para definir uma interface para múltiplos propósitos
XmlClassObj.NodeValue "filename",filename,0,False 'Caminho e nome do arquivo, use
caminho relativo'XmlClassObj.SaveSendXmlDataToFile() 'Salve o pacote de banco de dados xml enviado em um arquivo txt para fins de depuração
XmlClassObj.SendHttpData() 'Envia dados xml
'XmlClassObj.SaveGetXmlDataToFile() 'Salva os dados xml recebidos
Resultado do processamento Rem
Mensagem dim, status
status = XmlClassObj.GetSingleNode("//status") 'Exibe o status, se estiver OK, significa sucesso, caso contrário ocorre um erro
message = XmlClassObj.GetSingleNode("//message") 'Exibe o valor MD5 obtido Se o status não for OK, a mensagem é uma mensagem de erro.
Definir XmlClassObj = Nada
Se status = "OK" Então
GetFileMD5 = mensagem
Outro
GetFileMD5 = ""
Terminar se
Função final
%>
test.asp
<!--#Incluir arquivo="filemd5fun.asp"-->
<%
Response.Write "O valor md5 de web.config é:" & GetFileMD5("web.config") & "<br />"
Response.Write "O valor md5 de files/logo-yy.gif é:" & GetFileMD5("files/logo-yy.gif") & "<br />"
Response.Write "O valor md5 de xmlcls.asp é:" & GetFileMD5("xmlcls.asp") & "<br />"
%>
Código lateral .net:
MD5.cs
usando o sistema;
usando System.Collections.Generic;
usando System.Text;
usando o namespace System.IO
Winsteps.FileMD5
;
{
classe pública MD5
{
string estática pública md5_hash (caminho da string)
{
tentar
{
FileStream get_file = novo FileStream(caminho, FileMode.Open, FileAccess.Read, FileShare.Read);
System.Security.Cryptography.MD5CryptoServiceProvider get_md5 = novo System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] hash_byte = get_md5.ComputeHash(get_file);
string resultado = System.BitConverter.ToString (hash_byte);
resule = resule.Replace("-", "");
resultado de retorno;
}
pegar (Exceção e)
{
retornar e.Mensagem;
}
}
}
}
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="servidor">
<title>Site do tema móvel: http://www.shouji138.com</title>
</head>
<corpo>
<form id="form1" runat="servidor">
<div>
</div>
</form>
</body>
</html>
FileMD5.aspx.cs
usando Sistema;
usando System.Data;
usando System.Configuration;
usando System.Collections;
usando System.Web;
usando System.Web.Security;
usando System.Web.UI;
usando System.Web.UI.WebControls;
usando System.Web.UI.WebControls.WebParts;
usando System.Web.UI.HtmlControls;
usando System.Xml;
usando
o namespace System.Configuration Winsteps.FileMD5
;
{
classe parcial pública FileMD5: System.Web.UI.Page
{
protegido void Page_Load (remetente do objeto, EventArgs e)
{
string sysno = "11111";
string status = "Falso";
string mensagem = "Erro não especificado";
string net2sysno = ConfigurationManager.AppSettings["sysno"];
XmlDocument doc = new XmlDocument();
tentar
{
doc.Load(Request.InputStream);
sysno = doc.SelectSingleNode("//sysno").InnerText.Trim();
if (net2sysno! = sysno)
{
mensagem = "Aplicativo ilegal!";
}
outro
{
string nome do arquivo = Server.MapPath(doc.SelectSingleNode("//nome do arquivo").InnerText.Trim());
mensagem = MD5.md5_hash (nome do arquivo);
estado = "OK";
}
}
catch(Exceção ex)
{
mensagem = ex.Mensagem;
}
finalmente
{
if (doc! = nulo)
documento = nulo;
}
Response.Clear(); //Limpa caracteres HTML
Response.ContentType = "texto/xml";
Response.Charset = "GB2312";//Se a string xml contiver chinês
Response.Write("<?xml version="1.0" encoding="GB2312"?>");
Response.Write("<raiz>");
Response.Write(" <status>" + status + "</status>");
Response.Write("<mensagem>" + mensagem + "</message>");
Response.Write("</root>");
Resposta.End()
;
}
}
Web.config
<?xml version="1.0" encoding="utf-8"?>
<configuração>
<configurações do aplicativo>
<add key="sysno" value="k8n6g2b0m1a6b0f6e8"></add>
</appSettings>
<sistema.web>
<httpRuntime execuçãoTimeout="3600" maxRequestLength="1048576"/>
<compilação debug="true" defaultLanguage="c#" />
<customErrors mode="Desligado" />
<identidade personificar="true"/>
<modo de autenticação="Formulários">
<forms name="forums" path="/" loginUrl="Login.aspx" proteção="All" timeout="40">
</formulários>
</autenticação>
<pages validRequest="false"></pages>
<globalização requestEncoding="gb2312" responseEncoding="gb2312" culture="zh-CN" uiCulture="zh-CN"/>
</system.web>
</configuração>
O sysno do web.config deve ser consistente com o Apisysno no filemd5fun.asp Durante a aplicação específica, você deve alterar esta chave para seu próprio valor para garantir a segurança.
Endereço de demonstração: http://www.shouji138.com/aspnet2/filemd5.asp
Embora o código seja longo, o princípio é simples. O ASP envia dados xml para asp.net (o xml contém o nome do arquivo como md5) -> asp.net recebe o xml e executa md5 no arquivo -> asp.net retorna. o resultado para asp por meio de xml (o xml contém o valor md5 obtido) -> asp obtém o xml retornado e analisa o valor md5.
Escopo de aplicação:
1. Ao transferir arquivos entre dois sistemas, você pode executar o arquivo md5 antes da transmissão e o arquivo md5 após a transmissão para verificar se os dois valores são iguais, significa que não foram modificados durante o processo de transmissão.
2. No sistema de upload, caso seja necessário que o mesmo arquivo não possa ser carregado, o md5 do arquivo carregado pode ser armazenado no banco de dados. Desta forma, se o mesmo arquivo for carregado na próxima vez, o md5 será o. mesmo e o upload será recusado.
3. Nos motores de busca e no software Xunlei b2b, para o arquivo md5, os arquivos com o mesmo md5 são considerados o mesmo arquivo, independentemente de os nomes dos arquivos serem iguais, e os arquivos podem ser compartilhados de várias fontes.
4. Outras aplicações. . . . .
2. asp implementa md5 por meio de componentes COM (o componente precisa ser registrado no servidor)
para registrar um componente md5 de arquivo asp, endereço de download: DelphiASPObj.in_path=Server.Mappath("Web.config") 'Caminho do arquivo
Response.Write "O valor md5 de web.config é:" & DelphiASPObj.get_path_md5 & "<br />"
Definir DelphiASPObj = nada
%>
3. Comparação de duas maneiras de obter o arquivo md5
O primeiro método é obter o md5 do arquivo interagindo com os dados xml com o programa asp.net O servidor precisa suportar asp.net. ambiente asp.net, mas o preço é mais alto;
O segundo método é implementado registrando componentes COM, que requer permissões de servidor e é mais adequado para quem possui um servidor.
Além disso, o primeiro método de interação torna o ASP mais flexível e pode ser usado em dois servidores diferentes para interação de dados, podendo ser amplamente utilizado em diversas plataformas heterogêneas.
4. Para obter o endereço de download, acesse meu site e rede de tema móvel para visualizar a demonstração e baixar o endereço de demonstração do pacote do programa: http://www.shouji138.com/aspnet2/filemd5.asp
Download do pacote de download do programa: