[英]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.