将PHPcrypt()函数移植到C#问题能够使用他们的旧密码。但是,为了让它工作,我需要能够根据新输入的密码将旧哈希与新计算的哈希进行比较。我四处搜索,发现这是由PHP调用的crypt()的实际发现:char*crypt_md5(constchar*pw,constchar*salt){MD5_CTXctx,ctx1;无符号长l;诠释sl,pl;u_inti;u_charfinal[MD5_SIZE];静态常量char*sp,*ep;静态字符密码[120],*p;staticconstchar*magic="$1$";/*先优化盐*/sp=salt;/*如果它以魔法字符串开头,则跳过它*/if(!strncmp(sp,magic,strlen(magic)))sp+=strlen(magic);/*它在第一个'$'处停止,最多8个字符*/for(ep=sp;*ep&&*ep!='$'&&ep0;pl-=MD5_SIZE)MD5Update(&ctx,(constu_char*)最后,(u_int)(pl>MD5_SIZE?MD5_SIZE:pl));/*不要在他们可以使用的vm中留下任何东西。*/memset(final,0,sizeof(final));/*然后有些东西真的很奇怪...*/for(i=strlen(pw);i;i>>=1)if(i&1)MD5Update(&ctx,(constu_char*)final,1);否则MD5Update(&ctx,(constu_char*)pw,1);/*现在输出字符串*/strcpy(passwd,magic);strncat(密码d,sp,(u_int)sl);strcat(密码,“$”);MD5Final(最终,&ctx);/**现在,只是为了确保事情不会运行得太快*在60MhzPentium上这需要34毫秒,所以你*需要30秒来构建一个包含1000个条目的字典...*/for(i=0;我<1000;我++){MD5Init(&ctx1);if(i&1)MD5Update(&ctx1,(constu_char*)pw,strlen(pw));否则MD5Update(&ctx1,(constu_char*)final,MD5_SIZE);如果(i%3)MD5Update(&ctx1,(constu_char*)sp,(u_int)sl);if(i%7)MD5Update(&ctx1,(constu_char*)pw,strlen(pw));if(i&1)MD5Update(&ctx1,(constu_char*)final,MD5_SIZE);否则MD5Update(&ctx1,(constu_char*)pw,strlen(pw));MD5Final(final,&ctx1);}p=passwd+strlen(密码);l=(最终[0]<<16)|(最终[6]<<8)|最终[12];_crypt_to64(p,l,4);p+=4;l=(最终[1]<<16)|(最终[7]<<8)|最终[13];_crypt_to64(p,l,4);p+=4;l=(最终[2]<<16)|(最终[8]<<8)|最终[14];_crypt_to64(p,l,4);p+=4;l=(最终[3]<<16)|(最终[9]<<8)|最终[15];_crypt_to64(p,l,4);p+=4;l=(最终[4]<<16)|(最终[10]<<8)|最后[5];_crypt_to64(p,l,4);p+=4;l=最终[11];_crypt_to64(p,l,2);p+=2;*p='';/*不要在他们可以使用的vm中留下任何东西。*/memset(final,0,sizeof(final));返回(密码);并且,这是我在C#中的版本,以及预期的匹配使用系统;使用System.Collections.Generic;使用System.Linq;使用系统文本;使用系统诊断;使用System.Security.Cryptography;使用System.IO;使用系统管理;namespaceTest{classProgram{staticvoidMain(string[]args){byte[]salt=Encoding.ASCII.GetBytes("$1$ls3xPLpO$Wu/FQ.PtP2XBCqrM.w847/");Console.WriteLine("Hash:"+Encoding.ASCII.GetString(salt));byte[]passkey=Encoding.ASCII.GetBytes("suckit");byte[]newhash=md5_crypt(密码,盐);Console.WriteLine("Hash2:"+Encoding.ASCII.GetString(newhash));byte[]newhash2=md5_crypt(密码,newhash);Console.WriteLine("Hash3:"+Encoding.ASCII.GetString(newhash2));控制台.ReadKey(true);}publicstaticbyte[]md5_crypt(byte[]pw,byte[]salt){MemoryStreamctx,ctx1;乌龙l;诠释sl,pl;诠释我;字节[]最终;诠释sp,ep;//**更改指向数组索引的指针MemoryStreampasswd=newMemoryStream();byte[]magic=Encoding.ASCII.GetBytes("$1$");//先提炼盐sp=0;//**改为数组索引,而不是指针。//如果它以魔法字符串开头,则跳过if(salt[0]==magic[0]&&salt[1]==magic[1]&&salt[2]==magic[2]){sp+=魔术。长度;}//它在第一个'$'处停止,最多8个字符for(ep=sp;(ep+sp
