C# 使用C擦除硬盘上的可用空间#

C# 使用C擦除硬盘上的可用空间#,c#,.net,security,hard-drive,C#,.net,Security,Hard Drive,我的任务是覆盖几台笔记本电脑上的所有可用空间3次。我知道有一些选择,但我想知道事情是如何运作的,以及我是否可以自己用C#来做 1)是的,我知道有很多免费软件应用程序可以做到这一点 2)不,我们不需要遵守任何特定的政府标准 我在哪里寻找关于如何开始这项工作的想法 如果你能给我指出正确的方向,谢谢 可以用C#实现吗?如果是,怎么做?简单算法: 创建一个包含任意文本的大型文本文件(最好使用预先创建的文件,而不是出于性能原因重新生成随机文件。请进行测试。) 创建一个聪明的文件夹和文件命名方案,以便能够

我的任务是覆盖几台笔记本电脑上的所有可用空间3次。我知道有一些选择,但我想知道事情是如何运作的,以及我是否可以自己用C#来做

1)是的,我知道有很多免费软件应用程序可以做到这一点

2)不,我们不需要遵守任何特定的政府标准

我在哪里寻找关于如何开始这项工作的想法

如果你能给我指出正确的方向,谢谢

可以用C#实现吗?如果是,怎么做?

简单算法:

  • 创建一个包含任意文本的大型文本文件(最好使用预先创建的文件,而不是出于性能原因重新生成随机文件。请进行测试。)
  • 创建一个聪明的文件夹和文件命名方案,以便能够跟踪文件。你也应该用你的应用程序跟踪文件,但是如果它崩溃了,特别是在前几次测试运行接近尾声时,你会希望能够轻松地找到并清理你手头的工作
  • 将其写入硬盘,直到硬盘满为止
  • 删除您创建的文件
  • 再重复上述步骤两次
更新:后续讨论中关于擦拭的更多高级考虑:

  • 首次通过时写入0x0000值的文件(所有位关闭)
  • 第二次通过时,将所有位写入0xFFFF(所有位打开)
  • 最后一次通过时,重复0x0000

上面忽略了一些想法,例如文件的最佳大小是多少,这取决于您的文件系统。当你靠近一个填充的硬盘时,你可能会从操作系统中得到不同的行为

您必须执行一些低级操作,因此您肯定必须与Win32 API对话。我还没有做过这类事情,所以我不能给您提供详细信息,但一个开始寻找的好地方可能是Win32 API参考:

我真的不是这个领域的专家,但我天真的认为你需要: 1) 获取有关文件系统启动和停止位置的信息 2) 使用未删除的文件作为参考,获取可用空间的物理位置列表 3) 将0写入这些位置

也许这不是一个很好的答案,因为我不是该领域的专家,但我的评论时间太长了一点;)我希望这能有所帮助。

查看文档,也许你可以从那里得到一些线索。

我想这段代码是我写的。我不确定原始文章在哪里,但它符合您的要求:

根据我的评论,我显然需要多加一点调羹

根据您的需求,您可以非常简单地执行此操作

  • 制作一个大文件,填充驱动器上剩余的可用大小。然后简单地擦除这个文件

  • 创建多个文件,直到驱动器已满。(如果您想在机器运行时使用,这可能会更好)。然后您可以开始擦除每个文件,因此实际上系统拥有完整硬盘disj驱动器的总时间比使用方法1要短。但它可能会慢一点,并使用更多的代码

  • 使用的优点是代码少,易于使用。你不必玩那些会把你搞砸的低级API

    using System;
    using System.IO;
    using System.Security.Cryptography;
    
    namespace QuickStarterShared
    {
        public class Wipe
        {
            /// <summary>
            /// Deletes a file in a secure way by overwriting it with
            /// random garbage data n times.
            /// </summary>
            /// <param name="filename">Full path of the file to be deleted</param>
            /// <param name="timesToWrite">Specifies the number of times the file should be overwritten</param>
            public void WipeFile(string filename, int timesToWrite)
            {
    #if !DEBUG
                try
                {
    #endif
                    if (File.Exists(filename))
                    {
                        // Set the files attributes to normal in case it's read-only.
                        File.SetAttributes(filename, FileAttributes.Normal);
    
                        // Calculate the total number of sectors in the file.
                        double sectors = Math.Ceiling(new FileInfo(filename).Length/512.0);
    
                        // Create a dummy-buffer the size of a sector.
                        byte[] dummyBuffer = new byte[512];
    
                        // Create a cryptographic Random Number Generator.
                        // This is what I use to create the garbage data.
                        RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    
                        // Open a FileStream to the file.
                        FileStream inputStream = new FileStream(filename, FileMode.Open);
                        for (int currentPass = 0; currentPass < timesToWrite; currentPass++)
                        {
                            // Go to the beginning of the stream
                            inputStream.Position = 0;
    
                            // Loop all sectors
                            for (int sectorsWritten = 0; sectorsWritten < sectors; sectorsWritten++)
                            {
                                // Fill the dummy-buffer with random data
                                rng.GetBytes(dummyBuffer);
                                // Write it to the stream
                                inputStream.Write(dummyBuffer, 0, dummyBuffer.Length);
                            }
                        }
                        // Truncate the file to 0 bytes.
                        // This will hide the original file-length if you try to recover the file.
                        inputStream.SetLength(0);
                        // Close the stream.
                        inputStream.Close();
    
                        // As an extra precaution I change the dates of the file so the
                        // original dates are hidden if you try to recover the file.
                        DateTime dt = new DateTime(2037, 1, 1, 0, 0, 0);
                        File.SetCreationTime(filename, dt);
                        File.SetLastAccessTime(filename, dt);
                        File.SetLastWriteTime(filename, dt);
    
                        File.SetCreationTimeUtc(filename, dt);
                        File.SetLastAccessTimeUtc(filename, dt);
                        File.SetLastWriteTimeUtc(filename, dt);
    
                        // Finally, delete the file
                        File.Delete(filename);
                    }
    #if !DEBUG
                }
                catch(Exception e)
                {
    
                }
    #endif
            }
        }
    
        # region Events
        # region PassInfo
        public delegate void PassInfoEventHandler(PassInfoEventArgs e); 
        public class PassInfoEventArgs : EventArgs
        {
            private readonly int cPass;
            private readonly int tPass;
    
            public PassInfoEventArgs(int currentPass, int totalPasses)
            {
                cPass = currentPass;
                tPass = totalPasses;
            }
    
            /// <summary> Get the current pass </summary>
            public int CurrentPass { get { return cPass; } }
            /// <summary> Get the total number of passes to be run </summary> 
            public int TotalPasses { get { return tPass; } }
        }
        # endregion
    
        # region SectorInfo        
        public delegate void SectorInfoEventHandler(SectorInfoEventArgs e);
        public class SectorInfoEventArgs : EventArgs
        {
            private readonly int cSector;
            private readonly int tSectors;
    
            public SectorInfoEventArgs(int currentSector, int totalSectors)
            {
                cSector = currentSector;
                tSectors = totalSectors;
            }
    
            /// <summary> Get the current sector </summary> 
            public int CurrentSector { get { return cSector; } }
            /// <summary> Get the total number of sectors to be run </summary> 
            public int TotalSectors { get { return tSectors; } }
        }
        # endregion
    
        # region WipeDone        
        public delegate void WipeDoneEventHandler(WipeDoneEventArgs e);
        public class WipeDoneEventArgs : EventArgs
        {
        }
        # endregion
    
        # region WipeError
        public delegate void WipeErrorEventHandler(WipeErrorEventArgs e);
        public class WipeErrorEventArgs : EventArgs
        {
            private readonly Exception e;
    
            public WipeErrorEventArgs(Exception error)
            {
                e = error;
            }
    
            public Exception WipeError{get{ return e;}}
        }
        # endregion
        # endregion
    }
    
    使用系统;
    使用System.IO;
    使用System.Security.Cryptography;
    命名空间QuickStarterShared
    {
    公共类擦除
    {
    /// 
    ///以安全的方式删除文件,方法是使用
    ///随机垃圾数据n次。
    /// 
    ///要删除的文件的完整路径
    ///指定应覆盖文件的次数
    公共文件(字符串文件名,int timesToWrite)
    {
    #如果!调试
    尝试
    {
    #恩迪夫
    if(File.Exists(filename))
    {
    //如果是只读的,请将文件属性设置为“正常”。
    SetAttributes(filename,FileAttributes.Normal);
    //计算文件中的扇区总数。
    双扇区=Math.天花(新的FileInfo(filename.Length/512.0);
    //创建一个扇区大小的虚拟缓冲区。
    字节[]dummyBuffer=新字节[512];
    //创建加密随机数生成器。
    //这就是我用来创建垃圾数据的方法。
    RNGCryptoServiceProvider rng=新的RNGCryptoServiceProvider();
    //打开该文件的文件流。
    FileStream inputStream=newfilestream(文件名,FileMode.Open);
    对于(int currentPass=0;currentPassSystem.Diagonstics.Process.Start("chipher.exe /WC:\");