簡體   English   中英

c# hash 和 php MD5 文件/文件夾 Z0800FC577294C34E04528AD2839Z 不同

[英]c# hash and php MD5 file/folder hash not the same

我必須在客戶端(C#)和服務器(PHP)文件結構上使用 MD5 hash 文件/文件夾。 (服務器區是 PHP,客戶端區是 c#。)問題是它們工作時不匹配。 任何想法將不勝感激

這是我的兩個算法

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% 有效的代碼獲得賞金

您的PHP代碼正在組裝十六進制數字(根據md5_file()文檔)

您的C#代碼正在組裝非0填充的十進制數字。
您需要y.ToString("x2")格式化為十六進制。

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

我最終自己解決了這個問題,並為以后的解決提供了答案- 該解決方案的關鍵是闡明Linux和Windows使用的不同默認目錄ORDERING 僅在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內部的所有目錄返回遞歸的SAME散列(遞歸,因此它包括子目錄)。

對於像 C# 這樣的排序, asort() 區分大小寫,因此您需要每個示例 natcasesort()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM