我的任务是覆盖几台笔记本电脑上的所有可用空间3次。我知道有一些选择,但我想知道事情是如何工作的,如果我能用C#自己做的话。
1)是的,我知道有很多免费软件应用程序可以做到这一点
2)不,我们不需要遵守任何特定的政府标准
我在哪里寻找有关如何开始这个的想法?
谢谢你能指出我正确的方向。
可以用C#实现吗?如果是这样,怎么样?
答案 0 :(得分:3)
简单算法:
更新:对于后续讨论中擦除的更高级考虑因素:
上面忽略了一些想法,例如文件的最佳大小,取决于你的文件系统。当您靠近填充的HDD时,您可能也会从操作系统中获得不同的行为......
答案 1 :(得分:2)
这非常危险但是......
您可以使用Defrag APIs (here's a C# wrapper)来获取驱动器“map”,并专门定位自由空间并将垃圾写入磁盘的那些部分。
答案 2 :(得分:1)
此代码来自The Code Project我认为。我不确定orignal文章在哪里,但它符合你的要求:
基于评论,我显然需要更多地舀勺..
根据您的要求,您可以非常简单地完成此任务。
制作1个大文件,填充驱动器上剩余的空闲大小。然后只需擦除此文件。
制作多个文件,直到您的驱动器已满。 (如果要在机器运行时使用机器,这可能会更好)。然后你可以开始擦除每个文件,所以实际上系统有一个完整的硬盘驱动器的总时间小于使用方法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
}
答案 3 :(得分:0)
你将不得不做一些低级别的操作,所以你肯定要和Win32 API交谈。我没有做过这类事情,所以我不能给你详细说明,但是开始寻找的好地方可能是Win32 API参考:http://msdn.microsoft.com/en-us/library/aa383749%28VS.85%29.aspx
我根本不是这个领域的专家,但我天真的理解似乎是你需要: 1)获取文件系统启动位置的信息&amp;停止 2)使用未删除的文件作为参考,获取应该是可用空间的物理位置列表 3)将0写入那些位置
也许这不是一个很好的答案,因为我不是该领域的专家,但评论时间太长了;)我希望这有点帮助。
答案 4 :(得分:0)
查看SDelete文档,也许您可以在那里获得线索。
答案 5 :(得分:-1)
System.Diagonstics.Process.Start("chipher.exe /WC:\");
默认情况下这是异步的,你明白了。