2012-11-02 56 views
0

我必須在客戶端(C#)和服務器(PHP)文件結構上的MD5散列文件/文件夾。 (服務器域是PHP,客戶端域是c#)。問題在於他們的工作不匹配。任何想法,將不勝感激c#散列和php MD5文件/文件夾散列不一樣

這裏是我的兩個算法

C#

using System; 
using System.IO; 
using System.Security.Cryptography; 
using System.Text; 

namespace nofolder 
{ 
    public class classHasher 
    { 
     /********** 
     * recursive folder MD5 hash of a dir 
     */ 
     MD5 hashAlgo = null; 
     StringBuilder sb; 
     public classHasher() 
     { 
      hashAlgo = new MD5CryptoServiceProvider(); 
     } 
     public string getHash(String path) 
     { 
      // get the file attributes for file or directory 
      if (File.Exists(path)) return getHashOverFile(path); 
      if (Directory.Exists(path)) return getHashOverFolder(path); 
      return ""; 
     } 
     public string getHashOverFolder(String path) 
     { 
      sb = new StringBuilder(); 
      getFolderContents(path); 
      return sb.ToString().GetHashCode().ToString(); 
     } 
     public string getHashOverFile(String filename) 
     { 
      sb = new StringBuilder(); 
      getFileHash(filename); 
      return sb.ToString().GetHashCode().ToString(); 
     } 
     private void getFolderContents(string fold) 
     { 
      foreach (var d in Directory.GetDirectories(fold)) 
      { 
       getFolderContents(d); 
      } 
      foreach (var f in Directory.GetFiles(fold)) 
      { 
       getFileHash(f); 
      } 
     } 
     private void getFileHash(String f) 
     { 
      using (FileStream file = new FileStream(f, FileMode.Open, FileAccess.Read)) 
      { 
       byte[] retVal = hashAlgo.ComputeHash(file); 
       file.Close(); 
       foreach (var y in retVal) 
       { 
        sb.Append(y.ToString()); 
       } 
      } 
     } 
    } 
} 

PHP

function include__md5_dir($dir){ 
    /********** 
    * recursive folder MD5 hash of a dir 
    */ 
    if (!is_dir($dir)){ 
     return md5_file($dir); 
    } 

    $filemd5s = array(); 
    $d = dir($dir); 

    while (false !== ($entry = $d->read())){ 
     if ($entry != '.' && $entry != '..'){ 
      if (is_dir($dir.'/'.$entry)){ 
       $filemd5s[] = include__md5_dir($dir.'/'.$entry); 
      } 
      else{ 
       $filemd5s[] = md5_file($dir.'/'.$entry); 
      } 
     } 
    } 
    $d->close(); 
    return md5(implode('', $filemd5s)); 
} 

編輯。

我已決定c#必須更改PHP很好,因爲它是。該工程100%的第一代碼獲得賞金

回答

0

我最終自己修復了這個問題,並且包含了未來後代的答案 - 這個解決方案的關鍵在於根除了不同的默認目錄,命令linux和windows使用。這僅在Linux服務器(Cent OS6.3)和Windows 7客戶端上進行了測試。

C#

public class classHasher 
    { 
     /********** 
     * recursive folder MD5 hash of a dir 
     */ 
     MD5 hashAlgo = null; 
     StringBuilder sb; 
     public classHasher() 
     { 
      hashAlgo = new MD5CryptoServiceProvider(); 
     } 

     public string UltraHasher(String path) 
     { 
      /********** 
      * recursive folder MD5 hash of a dir 
      */ 
      if (!Directory.Exists(path)) 
      { 
       return getHashOverFile(path); 
      } 

      List<string> filemd5s = new List<string>(); 
      List<string> dir = new List<string>(); 

      if (Directory.GetDirectories(path) != null) foreach (var d in Directory.GetDirectories(path)) 
      { 
       dir.Add(d); 

      } 
      if (Directory.GetFiles(path) != null) foreach (var f in Directory.GetFiles(path)) 
      { 
       dir.Add(f);     
      } 

      dir.Sort(); 

      foreach (string entry in dir) 
      { 
       if (Directory.Exists(entry)) 
       { 
        string rtn = UltraHasher(entry.ToString()); 
        //Debug.WriteLine(" ULTRRAAHASHER:! " + entry.ToString() + ":" + rtn); 
        filemd5s.Add(rtn); 
       } 
       if (File.Exists(entry)) 
       { 
        string rtn = getHashOverFile(entry.ToString()); 
        //Debug.WriteLine(" FILEEEEHASHER:! " + entry.ToString() + ":" + rtn); 
        filemd5s.Add(rtn); 
       } 
      } 

      //Debug.WriteLine(" ULTRRAASUMMMM:! " + String.Join("", filemd5s.ToArray())); 
      string tosend = CalculateMD5Hash(String.Join("", filemd5s.ToArray())); 
      //Debug.WriteLine(" YEAHHAHHAHHAH:! " + tosend); 
      return tosend; 
     } 

     public string getHashOverFile(String filename) 
     { 
      sb = new StringBuilder(); 
      getFileHash(filename); 
      return sb.ToString(); 
     } 
     private void getFileHash(String f) 
     { 
      using (FileStream file = new FileStream(f, FileMode.Open, FileAccess.Read)) 
      { 
       byte[] retVal = hashAlgo.ComputeHash(file); 
       file.Close(); 
       foreach (var y in retVal) 
       { 
        sb.Append(y.ToString("x2")); 
       } 
      } 
     } 
     public string CalculateMD5Hash(string input) 
     { 
      byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input); 
      byte[] hash = hashAlgo.ComputeHash(inputBytes); 

      StringBuilder sz = new StringBuilder(); 
      for (int i = 0; i < hash.Length; i++) 
      { 
       sz.Append(hash[i].ToString("x2")); 
      } 
      return sz.ToString(); 
     } 
} 

PHP

function md5_dir($dir){ 
     /********** 
     * recursive folder MD5 hash of a dir 
     */ 
     if (!is_dir($dir)){ 
      return md5_file($dir); 
     } 

     $filemd5s = array(); 
     $bit = array(); 
     $d = scandir($dir); 

     foreach($d as $entry){ 
      if ($entry != '.' && $entry != '..'){ 
       $bit[] = $entry; 
      } 
     } 

     asort($bit); 

     foreach($bit as $entry){ 
      if (is_dir($dir.'/'.$entry)){ 
       $sz = md5_dir($dir.'/'.$entry); 
       //echo "\n ULTRRAAHASHER:! ".$dir.'/'.$entry.":$sz"; 
       $filemd5s[] = $sz; 
      } 
      else{ 
       $sz = md5_file($dir.'/'.$entry); 
       $filemd5s[] = $sz; 
       //echo "\n FILEEEEHASHER:! ".$dir.'/'.$entry.":$sz"; 
      } 
     } 
     //echo "\n ULTRRAASUMMMM:! ".implode('', $filemd5s).""; 
     //echo "\n YEAHHAHHAHHAH:! ".md5(implode('', $filemd5s)).""; 
     return md5(implode('', $filemd5s)); 
    } 

這兩個會遍歷無論是C#Windows和或PHP Linux文件夾,並返回相同的哈希所有迪爾斯(遞歸的,所以它包含子迪爾斯)在Linuxland內部和Windowsland內部。

1

您的PHP代碼組裝十六進制數字(按照md5_file()文檔)

你的C#代碼是組裝非填充0十進制數。
你需要y.ToString("x2")格式爲十六進制。

另外,return sb.ToString().GetHashCode().ToString();是非常錯誤的。不要致電GetHashCode();這不是你想要的。

+0

我將這些建議添加到C#(我同意,C#是錯誤的) - 但它現在不返回任何東西 – conners

+0

好吧,以確認這個答案可能部分在正確的軌道上,並非常感謝它,但 - 說實話 - 無論如何它都無法工作 – conners