Kürzester Code zum sicheren Löschen einer Festplatte

9

Schreiben wir den kürzesten Code, um eine vereinfachte Variante der DoD 5220.22-M-Löschmethode mit nur zwei Schreibdurchläufen auszuführen .

Jede Programmiersprache wird akzeptiert, aber die Verwendung von Bibliotheken zum Löschen von Datenträgern ist verboten.

So implementieren wir es im Pseudocode:

Set x to 0

[Start]
'Write Pass
For each sector in disk write the content of x
'Verification Pass
For each sector in disk {
    If sector does not contain the content of x then goto [Start]
}
'Check whether we already did the pass with 1
If x is not 1 then {
    Set x to 1
    GoTo [Start]
}
Else end

Mit anderen Worten, dieser Code wird zweimal ausgeführt, mit einem Schreib- und Verifizierungspass für 0und einem Schreibpass und einem Verifizierungspass für 1.

Ist jemand ballig genug, um es im Code-Golf-Stil umzusetzen? ;)

MathuSum Mut
quelle
6
Ich bezweifle, dass dies zu Antworten führen wird, da es schwierig sein wird, es zu testen.
James
12
Ernsthaft, was hat Ihre SSD mit Ihnen gemacht, um diese Art der Behandlung zu verdienen? Hat es deine gesamte Teddybärensammlung getötet oder so?
R. Kap
2
Ich möchte wirklich versuchen, dies in Angriff zu nehmen ... möchte auch nicht wirklich meine Festplatte opfern, um sie zu testen.
Michelfrancis Bustillos
6
Ich stimme dafür, diese Frage als nicht zum Thema gehörend zu schließen, da bei dieser Herausforderung nach bösartigem Code gefragt wird.
AdmBorkBork
2
Ich würde anders argumentieren. Bei dieser Herausforderung wird nach Code gefragt, der den Datenschutz und die Informationssicherheit fördert.
MathuSum Mut

Antworten:

1

x86-Maschinencode (Linux), 116 Byte

00000000: 89cb 6a02 5931 d289 4c24 f4b0 05cd 8050  ..j.Y1..L$.....P
00000010: 5b53 6a02 5a31 c9b0 13cd 8089 c65b 5331  [Sj.Z1.......[S1
00000020: d231 c9b0 13cd 8089 f75b 53b2 018d 4c24  .1.......[S...L$
00000030: f8b0 04cd 804e 09f6 75ef 5b53 31d2 31c9  .....N..u.[S1.1.
00000040: b013 cd80 89fe 5b53 8d4c 24f4 b201 b003  ......[S.L$.....
00000050: cd80 4e09 f674 0c8a 4424 f838 4424 f474  ..N..t..D$.8D$.t
00000060: e5eb ad89 fe8a 4424 f8c6 4424 f801 3c01  ......D$..D$..<.
00000070: 759e 58c3                                u.X.

Nimmt den Dateinamen als Argument

Versammlung (NASM):

section .text
	global func
func:			;this function uses fastcall conventions
	;seems like no enter instr needed

	;open file
	mov ebx, ecx	;first argument to func (filename)
	push 0x2	;flag O_RDWR
	pop ecx		;pushing a constant is shorter than mov
	xor edx, edx	;mode=0
	mov [esp-12], ecx ;set first byte (msg) to write to 0. msg later in esp-8, buf in esp-12
	mov al, 5	;using 8 bit regs is smaller
	int 0x80	;syscall open
	push eax	;save file descriptor

	write_verify:

	;get file size
	pop ebx		;get fd
	push ebx
	push 0x2	;flag SEEK_END
	pop edx
	xor ecx, ecx 	;offset 0
	mov al, 0x13
	int 0x80	;syscall lseek
	mov esi, eax	;save file byte count in esi
	

	;reset index of file to 0
	pop ebx		;get fd
	push ebx
	xor edx, edx	;flag SEEK_SET=0
	xor ecx, ecx	;ecx=0
	mov al, 0x13
	int 0x80	;syscall lseek

	;***write pass***
	mov edi, esi
	write_loop:	;for each byte in byte count, write [msg]
		;write to file
		pop ebx		;file descriptor
		push ebx
		mov dl, 1	;bytes to write
		lea ecx, [esp-8] ;buffer to write from
		mov al, 4
		int 0x80	;syscall write
		dec esi	;decrement esi (byte count) to 0
		or esi, esi	;cmp esi to 0
		jne write_loop	;while esi!=0, keep looping

	;reset index of file to 0
	pop ebx		;get fd
	push ebx
	xor edx, edx	;flag SEEK_SET=0
	xor ecx, ecx	;ecx=0
	mov al, 0x13
	int 0x80	;syscall lseek

	
	;***verification pass***
	mov esi, edi
	verify_loop:	;for each byte in byte count, verify written byte
		pop ebx		;get fd
		push ebx
		lea ecx, [esp-12] ;buffer to store read byte
		mov dl, 1	;read 1 byte
		mov al, 3
		int 0x80	;syscall read
		dec esi
		or esi, esi	;cmp esi to 0 
		je end_verify	;at final byte, end verification
		mov al, [esp-8]
		cmp byte [esp-12],al
		je verify_loop	 ;keep looping if expected value found
		jmp write_verify ;if byte!=expected value, restart

	end_verify:
	mov esi, edi
	mov al, [esp-8]
	mov byte [esp-8],0x1	;set new byte to write to 1
	cmp al, 0x1
	jne write_verify	;if old byte to write!=1, goto start
	
	pop eax			;reset stack
	ret

Probieren Sie es online aus! (Verwendet eine temporäre Datei)

-11 Bytes durch Optimieren von sich bewegenden Registern und Verwenden des Stapels als Puffer anstelle einer konstanten Position im Speicher.

Logern
quelle
3

Auf einem Linux-System ist keine spezielle Handhabung von Geräten erforderlich. Verwenden Sie einfach die Gerätedateischnittstelle.

Python 3 (Byte-Strings) - 141 Bytes

d=input()
f=open(d,'r+b')
z=f.seek
z(0,2)
s=f.tell()
i=0
while i<2:
 z(0);f.write([b'\0',b'\xff'][i]*s);f.flush();z(0)
 if f.read()==x:i+=1

Es ist ziemlich einfach und nicht wirklich stark optimiert, aber es funktioniert. Hier ist ein grundlegender Überblick.

  • Eingabe abrufen (Gerätedateipfad)
  • Gerätedatei öffnen
  • Suchen Sie bis zum Ende, erhalten Sie die Dateigröße (Blockgeräte haben immer ihre tatsächliche Größe)
  • Geben Sie die Write-and-Check-Schleife ein
  • konstruiere 0-Bit- und 1-Bit-Strings (x)
  • Bitstring schreiben
  • Flush-Ausgabe (ich hätte die Pufferung auf 0 setzen können, aber das ist kürzer)
  • Testdatei gegen x und inkrementiere den Schritt der Schleife, wenn sie erfolgreich ist

Exit-Schleife, wenn das Inkrement hoch genug ist

Als Bonus können Sie dies für jeden Satz und jede Anzahl von Bytemodifikationsmustern ändern, z. B. 0x55 / 0xaa für stärkere Überschreibungseffekte.

Ich habe dies tatsächlich an einer Gerätedatei mit Loopback getestet. Ich bin mir jedoch nicht 100% sicher, ob die Überprüfung tatsächlich funktioniert. Aufgrund des Pufferverhaltens kann es erforderlich sein, die Datei bei jedem Durchgang zu schließen und erneut zu öffnen. Ich würde hoffen, dass Flush dies verhindert.

* bearbeitet, um einige Vorschläge in die Kommentare aufzunehmen

William Shipley
quelle
1
Willkommen auf der Website. Sie brauchen sicherlich kein Leerzeichen um eine =Python. Sie können auch die Anzahl der Bytes ;reduzieren, indem Sie die Einrückung reduzieren.
Ad-hoc-Garf-Jäger
Normalerweise zählen wir Einsendungen in Bytes, nicht in Zeichen. Sie können auch einige Ihrer Funktionen aliasen, z. B. f.seek(0);f.seek(0)(19 Byte) s=f.seek;s(0);s(0)(18 Byte). Darüber hinaus if f.read()==x:i+=1kann sein i+=f.read()==x.
Jonathan Frech
Sie sollten die leere Zeichenfolge auch nicht als Argument für die Eingabe benötigen.
Quintec
Ich denke b'\0'statt b'\x00'sollte funktionieren.
Jason
Gerade ein wichtiges Merkmal realisiert. Dieses Programm belegt RAM, das der Größe des gelöschten Geräts entspricht.
William Shipley
2

C (Klirren) , -DZ=lseek(d,0+ 139 = 152 Bytes

g,j,x,d,s,i,c;f(n){x=0;d=open(n,2);s=Z,2);for(j=2;j--;x++){Z,0);for(i=s;i--;write(d,&x,1));Z,0);for(i=s;i--;read(d,&c,1),c!=x&&x--&&j--);}}

Probieren Sie es online aus!

Nimmt den Dateinamen als Argument

Ungolfed:

#include <unistd.h>
int g,j,x,d,s,i,c;
void f(char*n){
	x=0; /*Byte to write*/
	d=open(n,O_RDWR);
	s=lseek(d,0,SEEK_END); /*Get size of file*/
	j=0;
	for(j=0;j<2;j++){
		/*Write Pass*/
		lseek(d,0,SEEK_SET); /*Start writing from start of file*/
		for(i=0;i<s;i++){
			write(d,&x,1);
		}
		
		/*Verification Pass*/
		lseek(d,0,SEEK_SET);
		for(i=0;i<s;i++){
			read(d,&c,1);
			if(c!=x)x--,j--; /*If verification fails, repeat loop with the same value*/
		}
		x++;
	}
}
Logern
quelle
Hmm ... wird das TiO das Internet löschen? ;-D
Titus
@Titus Erstellt eine temporäre Datei und löscht sie.
Logern
1

Tcl, 286 Bytes

proc f {o i l} {seek $o 0
set s [string repeat $i $l]
puts -nonewline $o $s
flush $o
seek $o 0
return [string equal [read $o $l] $s]}
set n [open $argv r+]
fconfigure $n -translation binary
seek $n 0 end
set m [tell $n]
while {![f $n "\0" $m]} {}
while {![f $n "\xff" $m]} {}

Nicht wirklich so gut optimiert. Ich habe versucht, was ich konnte, aber ich weiß nicht so viel über Tcl.

Speichern Sie als "f.tcl" und führen Sie unter Unix mit tclsh f.tcl "your filename". Stellen Sie sicher, dass es genau ein Argument gibt! Ich habe dies an einer einfachen Datei getestet, aber es sollte auch an einer Gerätedatei funktionieren.

Das Festlegen von Variablen und die Indizierung sind in Tcl wichtiger, daher habe ich beschlossen, den gemeinsamen Code zwischen den Durchläufen in eine Funktion einzufügen. Dann rufe ich es zuerst mit "\ 0" auf und wiederhole es, während es nicht überprüft werden kann. Ich mache das gleiche mit "\ xff".

Ich errötete nach dem Schreiben; es könnte nicht notwendig sein. fconfigure -translation binary -buffering noneist länger.

-2 Bytes durch Entfernen von Anführungszeichen r+.

Jason
quelle