最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

.NET根據(jù)文件的哈希值篩選重復(fù)文件的實(shí)現(xiàn)思路

 更新時(shí)間:2025年03月14日 10:19:41   作者:醉酒的李白、  
文章介紹了文件哈希值的概念,包括哈希算法、唯一性、固定長度、不可逆性以及其在文件驗(yàn)證、數(shù)據(jù)完整性檢查、文件去重、密碼存儲等領(lǐng)域的應(yīng)用,接著,通過一個(gè)示例代碼說明了如何通過文件大小分組并比對哈希值來篩選出重復(fù)文件,感興趣的朋友一起看看吧

如題。先介紹下概念。

Q1. 文件的哈希值是什么?

文件的哈希值是通過特定的哈希算法對文件內(nèi)容進(jìn)行計(jì)算后得到的固定長度的字符串(通常由數(shù)字和字母組成),它具有以下特點(diǎn)和相關(guān)信息:

  • 哈希算法:常見的用于計(jì)算文件哈希值的算法包括 MD5、SHA-1、SHA-256、SHA-512 等。不同算法的計(jì)算方式和生成的哈希值長度不同。例如,MD5 算法生成的哈希值是 128 位(通常以 32 個(gè)十六進(jìn)制字符表示),SHA-256 算法生成的哈希值是 256 位(以 64 個(gè)十六進(jìn)制字符表示) 。
  • 唯一性:理論上,不同內(nèi)容的文件經(jīng)過哈希算法計(jì)算后,應(yīng)該得到不同的哈希值。這意味著如果兩個(gè)文件的哈希值相同,那么它們的內(nèi)容很可能是完全一樣的(雖然存在極小概率的哈希碰撞,即不同內(nèi)容產(chǎn)生相同哈希值,但這種情況非常罕見)。例如,在文件傳輸過程中,接收方可以計(jì)算接收到的文件的哈希值,并與發(fā)送方提供的原始文件哈希值進(jìn)行比較,以驗(yàn)證文件在傳輸過程中是否完整無損,沒有被篡改。
  • 固定長度:無論文件的大小和內(nèi)容如何,使用特定哈希算法計(jì)算得到的哈希值長度是固定的。例如,無論一個(gè)文本文件是幾 KB 還是幾 MB,使用 SHA-256 算法計(jì)算出的哈希值始終是 256 位。
  • 不可逆性:哈希計(jì)算是一種單向操作,即可以通過文件內(nèi)容計(jì)算出哈希值,但無法從哈希值反向推導(dǎo)出原始的文件內(nèi)容。這使得哈希值在數(shù)據(jù)存儲和安全驗(yàn)證等方面具有重要作用,比如在存儲用戶密碼時(shí),通常存儲的是密碼的哈希值,即使數(shù)據(jù)庫被攻擊,攻擊者也難以從哈希值還原出原始密碼。

哈希值在文件驗(yàn)證、數(shù)據(jù)完整性檢查、文件去重、密碼存儲等眾多領(lǐng)域都有廣泛應(yīng)用,是確保數(shù)據(jù)一致性和安全性的重要手段之一。

Q2. 比如一個(gè)文件 有1G大小,那么它的哈希值會(huì)多大?

文件哈希值的大小與文件本身的大小無關(guān),而是由所使用的哈希算法決定。

常見的哈希算法及其生成的哈希值大小如下:

  • MD5 算法:生成 128 位(16 字節(jié))的哈希值,通常以 32 個(gè)十六進(jìn)制字符表示。例如:d41d8cd98f00b204e9800998ecf8427e ,無論原文件是 1 字節(jié)還是 1GB 甚至更大,使用 MD5 算法計(jì)算出的哈希值固定是 128 位。
  • SHA-1 算法:產(chǎn)生 160 位(20 字節(jié))的哈希值,一般以 40 個(gè)十六進(jìn)制字符呈現(xiàn)。比如:da39a3ee5e6b4b0d3255bfef95601890afd80709 ,不管文件大小怎樣變化,SHA-1 算法得到的哈希值長度不變。SHA-256 算法:輸出 256 位(32 字節(jié))的哈希值,以 64 個(gè)十六進(jìn)制字符展示。例如:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 ,即使是 1GB 的大文件,其 SHA-256 哈希值依然是 256 位。
  • SHA-512 算法:生成 512 位(64 字節(jié))的哈希值,用 128 個(gè)十六進(jìn)制字符表示。如:cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e ,同樣不受文件大小影響。

所以,一個(gè) 1GB 大小的文件,其哈希值的大小取決于選擇的哈希算法,而不是文件自身的體積大小。

需求:客戶有200+份文件來源于不同的三方平臺,但是客戶不確定是否有重復(fù)文件??赡軄碓床煌俏募嗤???蛻粝MY出這些重復(fù)文件。供用戶搜索用,這樣用戶就只會(huì)搜出唯一的文件結(jié)果,而不是來源于不同渠道的相同文件。

實(shí)現(xiàn)思路:

先獲取所有文件的大小,并按照大小group by,這樣相同大小的文件就會(huì)在一組。文件大小不同一定不屬于相同文件,文件大小相同有可能屬于相同文件,也有可能是不同的文件剛好大小相等。按照這方式,遍歷所有相同大小的組。比對哈希值。文件大小不同的就不用比較了??隙ú皇窍嗤募?/p>

/*
代碼說明
FindDuplicateFilesGrouped 方法:
首先遍歷傳入的文件路徑數(shù)組,將每個(gè)文件的信息(Id、FileName、FileSize)封裝到 FileInfoEntity 對象中,并添加到 fileInfos 列表。
接著按文件大小對 fileInfos 進(jìn)行分組,得到 sizeGroups。
針對每個(gè)大小組,計(jì)算組內(nèi)每個(gè)文件的哈希值,把具有相同哈希值的文件存到 hashGroups 字典里。
最后,將 hashGroups 中包含多個(gè)文件的組添加到 duplicateFileGroups 列表,該列表即為最終按組返回的重復(fù)文件結(jié)果。
通過這種方式,就能方便地找出所有重復(fù)文件,并將它們按組分類返回。
*/

FileComparisonTool.cs

//FileComparisonTool.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
namespace ConsoleApp1_CompareFiles
{
    // 文件實(shí)體類
    public class FileInfoEntity
    {
        public Guid Id { get; set; }
        public MemoryStream Stream { get; set; }
        public string FileName { get; set; }
        public long FileSize { get; set; }
    }
    // 文件比較工具類
    public class FileComparisonTool
    {
        public static string[] GetAllFilesInFolder(string folderPath)
        {
            try
            {
                // 獲取當(dāng)前文件夾下的所有文件
                string[] files = Directory.GetFiles(folderPath);
                // 獲取當(dāng)前文件夾下的所有子文件夾
                string[] subFolders = Directory.GetDirectories(folderPath);
                foreach (string subFolder in subFolders)
                {
                    // 遞歸調(diào)用獲取子文件夾下的所有文件
                    string[] subFiles = GetAllFilesInFolder(subFolder);
                    files = files.Concat(subFiles).ToArray();
                }
                return files;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"發(fā)生錯(cuò)誤: {ex.Message}");
                return new string[0];
            }
        }
        // 計(jì)算文件哈希值
        private static string CalculateHash(Stream stream)
        {
            using (SHA256 sha256 = SHA256.Create())
            {
                byte[] hashBytes = sha256.ComputeHash(stream);
                return BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
            }
        }
        // 入?yún)⑹莾蓚€(gè)文件流,比較兩個(gè)文件
        public static bool CompareFiles(Stream stream1, Stream stream2)
        {
            stream1.Position = 0;
            stream2.Position = 0;
            string hash1 = CalculateHash(stream1);
            string hash2 = CalculateHash(stream2);
            return hash1 == hash2;
        }
        // 入?yún)⑹莾蓚€(gè)文件路徑,比較兩個(gè)文件
        public static bool CompareFiles(string filePath1, string filePath2)
        {
            using (FileStream stream1 = File.OpenRead(filePath1))
            using (FileStream stream2 = File.OpenRead(filePath2))
            {
                return CompareFiles(stream1, stream2);
            }
        }
        // 入?yún)⑹俏募窂降臄?shù)組,找出重復(fù)文件
        public static List<FileInfoEntity> FindDuplicateFiles(string[] filePaths)
        {
            var fileInfos = new List<FileInfoEntity>();
            foreach (var filePath in filePaths)
            {
                var fileInfo = new FileInfo(filePath);
                fileInfos.Add(new FileInfoEntity
                {
                    Id = Guid.NewGuid(),
                    FileName = filePath,
                    FileSize = fileInfo.Length
                });
            }
            var groups = fileInfos.GroupBy(f => f.FileSize);
            var duplicateFiles = new List<FileInfoEntity>();
            foreach (var group in groups)
            {
                if (group.Count() > 1)
                {
                    var hashes = new Dictionary<string, FileInfoEntity>();
                    foreach (var file in group)
                    {
                        using (FileStream stream = File.OpenRead(file.FileName))
                        {
                            string hash = CalculateHash(stream);
                            if (hashes.ContainsKey(hash))
                            {
                                if (!duplicateFiles.Contains(hashes[hash]))
                                {
                                    duplicateFiles.Add(hashes[hash]);
                                }
                                duplicateFiles.Add(file);
                            }
                            else
                            {
                                hashes[hash] = file;
                            }
                        }
                    }
                }
            }
            return duplicateFiles;
        }
        /*
        代碼說明
        FindDuplicateFilesGrouped 方法:
        首先遍歷傳入的文件路徑數(shù)組,將每個(gè)文件的信息(Id、FileName、FileSize)封裝到 FileInfoEntity 對象中,并添加到 fileInfos 列表。
        接著按文件大小對 fileInfos 進(jìn)行分組,得到 sizeGroups。
        針對每個(gè)大小組,計(jì)算組內(nèi)每個(gè)文件的哈希值,把具有相同哈希值的文件存到 hashGroups 字典里。
        最后,將 hashGroups 中包含多個(gè)文件的組添加到 duplicateFileGroups 列表,該列表即為最終按組返回的重復(fù)文件結(jié)果。
        通過這種方式,就能方便地找出所有重復(fù)文件,并將它們按組分類返回。
        */
        // 入?yún)⑹俏募窂綌?shù)組,按組返回重復(fù)文件
        public static List<List<FileInfoEntity>> FindDuplicateFilesGrouped(string[] filePaths)
        {
            var fileInfos = new List<FileInfoEntity>();
            foreach (var filePath in filePaths)
            {
                var fileInfo = new FileInfo(filePath);
                fileInfos.Add(new FileInfoEntity
                {
                    Id = Guid.NewGuid(),
                    FileName = filePath,
                    FileSize = fileInfo.Length
                });
            }
            var sizeGroups = fileInfos.GroupBy(f => f.FileSize);
            var duplicateFileGroups = new List<List<FileInfoEntity>>();
            foreach (var sizeGroup in sizeGroups)
            {
                if (sizeGroup.Count() > 1)
                {
                    var hashGroups = new Dictionary<string, List<FileInfoEntity>>();
                    foreach (var file in sizeGroup)
                    {
                        using (FileStream stream = File.OpenRead(file.FileName))
                        {
                            string hash = CalculateHash(stream);
                            if (!hashGroups.ContainsKey(hash))
                            {
                                hashGroups[hash] = new List<FileInfoEntity>();
                            }
                            hashGroups[hash].Add(file);
                        }
                    }
                    foreach (var hashGroup in hashGroups.Values)
                    {
                        if (hashGroup.Count > 1)
                        {
                            duplicateFileGroups.Add(hashGroup);
                        }
                    }
                }
            }
            return duplicateFileGroups;
        }
    }
}
 

//

// Program.cs
// See https://aka.ms/new-console-template for more information
using ConsoleApp1_CompareFiles;
Console.WriteLine("Hello, World!");
string[] filePaths = { 
    "C:\\Users\\Aa\\Desktop\\新建文件夾\\1.txt",
    "C:\\Users\\Aa\\Desktop\\新建文件夾\\2.txt",
    "C:\\Users\\Aa\\Desktop\\新建文件夾\\3.txt",
    "C:\\Users\\Aa\\Desktop\\新建文件夾\\4.xlsx",
    "C:\\Users\\Aa\\Desktop\\新建文件夾\\5.xlsx",
    "C:\\Users\\Aa\\Desktop\\新建文件夾\\6.docx",
    "C:\\Users\\Aa\\Desktop\\新建文件夾\\7.docx",
    "C:\\Users\\Aa\\Desktop\\新建文件夾\\8.jpeg",
    "C:\\Users\\Aa\\Desktop\\新建文件夾\\9.jpeg",
    "C:\\Users\\Aa\\Desktop\\新建文件夾\\捕獲 - 副本.PNG",
    "C:\\Users\\Aa\\Desktop\\新建文件夾\\捕獲.PNG",
    "C:\\Users\\Aa\\Desktop\\新建文件夾\\微信圖片_20250221165428.png",
};
string folderPath = @"C:\Users\Aa\Desktop\新建文件夾";
string[] allFiles = FileComparisonTool.GetAllFilesInFolder(folderPath);
var duplicateFileGroups = FileComparisonTool.FindDuplicateFilesGrouped(allFiles);
Console.WriteLine($"找到的重復(fù)文件組數(shù)量: {duplicateFileGroups.Count}");
foreach (var group in duplicateFileGroups)
{
    Console.WriteLine($"該組重復(fù)文件數(shù)量: {group.Count}");
    foreach (var file in group)
    {
        Console.WriteLine($"  文件 ID: {file.Id}, 文件名: {file.FileName}, 文件大小: {file.FileSize}");
    }
}

實(shí)現(xiàn)效果:

測試文件.txt文本的舉例子??梢钥吹近S框和紅框內(nèi)的都屬于相同文件。紅框和黃框內(nèi)的雖然字節(jié)數(shù)是一樣的,相同大小會(huì)group by到一組。但是hash值肯定是不同的。

到此這篇關(guān)于.NET下根據(jù)文件的哈希值篩選重復(fù)文件的文章就介紹到這了,更多相關(guān).net哈希值篩選重復(fù)文件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解.NET Core 使用HttpClient SSL請求出錯(cuò)的解決辦法

    詳解.NET Core 使用HttpClient SSL請求出錯(cuò)的解決辦法

    這篇文章主要介紹了.NET Core 使用HttpClient SSL請求出錯(cuò)的解決辦法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-03-03
  • .NET?6中的dotnet?monitor講解

    .NET?6中的dotnet?monitor講解

    dotnet?monitor為Azure?App?Service(Linux)提供.NET?應(yīng)用程序的診斷工具提供支持。這篇文章講解了.NET?6中的dotnet?monitor,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-12-12
  • ASP.NET 頁生命周期概述(小結(jié))

    ASP.NET 頁生命周期概述(小結(jié))

    了解個(gè)掌握ASP.NET頁面生命周期是非常必要的,這有助于我們更加靈活的控制頁面,以我們需要的方式編程開發(fā)。本文詳細(xì)的介紹了ASP.NET 頁生命周期,感興趣的可以了解一下
    2018-11-11
  • ASP.Net頁面生成餅圖實(shí)例

    ASP.Net頁面生成餅圖實(shí)例

    這篇文章主要介紹了ASP.Net頁面生成餅圖的方法,實(shí)例講述了生成普通餅圖與增加邊線的方法,具有不錯(cuò)的參考借鑒價(jià)值,需要的朋友可以參考下
    2014-11-11
  • ASP.NET?MVC5網(wǎng)站開發(fā)顯示文章列表(九)

    ASP.NET?MVC5網(wǎng)站開發(fā)顯示文章列表(九)

    顯示文章列表分兩塊,管理員可以顯示全部文章列表,一般用戶只顯示自己的文章列表。文章列表的顯示采用easyui-datagrid,后臺需要與之對應(yīng)的action返回json類型數(shù)據(jù),感興趣的小伙伴們可以參考一下
    2015-09-09
  • DataTable轉(zhuǎn)成字符串復(fù)制到txt文本的小例子

    DataTable轉(zhuǎn)成字符串復(fù)制到txt文本的小例子

    DataTable轉(zhuǎn)成字符串復(fù)制到txt文本的小例子,需要的朋友可以參考一下
    2013-03-03
  • viewstate和datatable動(dòng)態(tài)錄入數(shù)據(jù)示例

    viewstate和datatable動(dòng)態(tài)錄入數(shù)據(jù)示例

    這篇文章主要介紹了viewstate和datatable動(dòng)態(tài)錄入數(shù)據(jù)示例,需要的朋友可以參考下
    2014-02-02
  • asp.net(C#)壓縮圖片,可以指定圖片模板高寬

    asp.net(C#)壓縮圖片,可以指定圖片模板高寬

    今天要在web程序處理圖片,指定圖片的高寬大小。google了一把資料。覺得此方法挺不錯(cuò)的,大家可以借鑒一下,如果小弟寫的有不對的地方請大家指點(diǎn)一下:以下代碼在winform寫的,在web下測試可以使用。
    2010-03-03
  • Asp.net core實(shí)現(xiàn)PushStream視頻流推送

    Asp.net core實(shí)現(xiàn)PushStream視頻流推送

    這篇文章介紹了Asp.net core實(shí)現(xiàn)PushStream視頻流推送的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • 防SQL注入 生成參數(shù)化的通用分頁查詢語句

    防SQL注入 生成參數(shù)化的通用分頁查詢語句

    前些時(shí)間看了玉開兄的“如此高效通用的分頁存儲過程是帶有sql注入漏洞的”這篇文章,才突然想起某個(gè)項(xiàng)目也是使用了累似的通用分頁存儲過程。
    2010-07-07

最新評論

志丹县| 琼中| 嘉鱼县| 黄浦区| 和平县| 南投市| 南靖县| 普格县| 潞西市| 甘孜县| 许昌县| 兴城市| 武乡县| 琼中| 墨玉县| 泸西县| 修武县| 靖宇县| 彰化市| 北碚区| 平南县| 亳州市| 新巴尔虎右旗| 宜城市| 克山县| 谢通门县| 浏阳市| 盖州市| 武定县| 玉田县| 东方市| 甘孜| 寻乌县| 台湾省| 紫金县| 嘉峪关市| 枣阳市| 皋兰县| 大庆市| 临颍县| 津市市|