Il codice più breve per pulire in modo sicuro un disco


9

Scriviamo il codice più breve per eseguire una variante semplificata del metodo di pulizia DoD 5220.22-M con solo due passaggi di scrittura.

È accettato qualsiasi linguaggio di programmazione, ma è vietato l'uso di librerie orientate alla pulizia del disco.

Ecco come dobbiamo implementarlo in pseudocodice:

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

In altre parole, questo codice verrà eseguito due volte, con un passaggio di scrittura e un passaggio di verifica per 0e un passaggio di scrittura e un passaggio di verifica per 1.

Qualcuno abbastanza pallido da implementarlo in stile code-golf? ;)


6
Dubito che questo otterrà risposte a causa di quanto sarà difficile testare.
James,

12
Seriamente, cosa ti ha fatto il tuo SSD per meritare questo tipo di trattamento? Ha ucciso la tua intera collezione di orsacchiotti o qualcosa del genere?
R. Kap

2
Voglio davvero provare ad affrontare questo ... inoltre non voglio sacrificare il mio HDD per testarlo.
Michelfrancis Bustillos,

6
Sto votando per chiudere questa domanda come fuori tema perché questa sfida richiede codice dannoso.
AdmBorkBork,

2
Direi diversamente. Questa sfida richiede un codice che promuova la privacy e la sicurezza delle informazioni.
MathuSum Mut

Risposte:


1

codice macchina x86 (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.

Utilizza il nome file come argomento

Assembly (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

Provalo online! (Utilizza un file temporaneo)

-11 byte ottimizzando i registri mobili e usando lo stack come buffer anziché una posizione costante nella memoria.


3

Su un sistema Linux non è necessaria una gestione speciale dei dispositivi. Usa semplicemente l'interfaccia del file del dispositivo.

Python 3 (stringhe di byte) - 141 byte

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

È abbastanza semplice e non molto ottimizzato, ma funziona. Ecco una carrellata di base.

  • Ottieni input (percorso del file del dispositivo)
  • Apri il file del dispositivo
  • Cerca fino alla fine, ottieni la dimensione del file (i dispositivi a blocchi hanno sempre la loro dimensione reale)
  • entra nel ciclo di scrittura e verifica
  • costruire stringhe 0-bit e 1-bit (x)
  • scrivi bitstring
  • flush output (avrei potuto impostare buffering = 0 ma questo è più corto)
  • prova il file contro x e incrementa il passaggio del ciclo se passa

esce dal loop quando l'incremento è abbastanza alto

Come bonus, potresti modificarlo per qualsiasi set e numero di pattern di modifica byte, come 0x55 / 0xaa per effetti di sovrascrittura più forti.

Ho effettivamente testato questo su un file del dispositivo, usando il loopback. Tuttavia, non sono sicuro al 100% che il controllo funzioni davvero. Potrebbe essere necessario chiudere e riaprire il file ogni passaggio, a causa di comportamenti di buffering. Spero che flush lo impedisca.

* modificato per includere alcuni suggerimenti nei commenti


1
Benvenuti nel sito. Certamente non hai bisogno di spazi bianchi attorno a =in in Python. È inoltre possibile ridurre il numero di byte utilizzando ;per ridurre il rientro.
Ad Hoc Garf Hunter,

Normalmente contiamo gli invii in byte, non in caratteri. È inoltre possibile alias alcune funzioni, ad es. f.seek(0);f.seek(0)(19 byte) possono essere s=f.seek;s(0);s(0)(18 byte). Inoltre, if f.read()==x:i+=1può essere i+=f.read()==x.
Jonathan Frech,

Inoltre non dovresti aver bisogno della stringa vuota come argomento da inserire.
Quintec,

Penso che b'\0'invece b'\x00'dovrebbe funzionare.
Jason,

Ho appena realizzato una caratteristica importante. Questo programma consumerà RAM pari alla dimensione del dispositivo cancellato.
William Shipley,

2

C (clang) , -DZ=lseek(d,0+ 139 = 152 byte

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--);}}

Provalo online!

Prende il nome file come argomento

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++;
	}
}

Hmm ... il TiO cancellerà Internet? ;-D
Tito,

@Titus Crea un file temporaneo e lo cancella.
Logern,

1

Tcl, 286 byte

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]} {}

Non proprio ottimizzato così bene. Ho provato quello che potevo, ma non so molto di Tcl.

Salvare come "f.tcl" ed eseguire su Unix con tclsh f.tcl "your filename". Assicurati che ci sia esattamente un argomento! Ho provato questo su un semplice file, ma dovrebbe funzionare anche su un file del dispositivo.

L'impostazione delle variabili e dell'indicizzazione è più coinvolta in Tcl, quindi ho deciso di inserire in una funzione il codice comune tra i passaggi. Quindi lo chiamo prima con "\ 0" e ripeto mentre non riesce a verificare. Faccio la stessa cosa con "\ xff".

Ho arrossito dopo aver scritto; potrebbe non essere necessario. fconfigure -translation binary -buffering noneè più lungo.

-2 byte rimuovendo le virgolette r+.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.