Najkrótszy kod do bezpiecznego czyszczenia dysku

9

Napiszmy najkrótszy kod, aby wykonać uproszczony wariant metody czyszczenia DoD 5220.22-M z tylko dwoma przebiegami zapisu.

Dowolny język programowania jest akceptowany, ale korzystanie z bibliotek zorientowanych na czyszczenie dysku jest zabronione.

Oto jak mamy to zaimplementować w pseudokodzie:

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

Innymi słowy, ten kod będzie działał dwukrotnie, z przepustką zapisu i przepustką weryfikacyjną dla 0, oraz przepustką zapisu i przepustką weryfikacyjną dla 1.

Czy ktoś jest wystarczająco bystry, aby wdrożyć ten styl golfa? ;)

MathuSum Mut
źródło
6
Wątpię, czy otrzymają jakieś odpowiedzi z powodu tego, jak trudno będzie przetestować.
James
12
Poważnie, co zrobiłeś z dyskiem SSD, aby zasłużyć na tego rodzaju leczenie? Czy to zabiło całą Twoją kolekcję misiów?
R.Kap
2
Naprawdę chcę spróbować rozwiązać ten problem ... tak naprawdę nie chcę poświęcać mojego dysku twardego, aby go przetestować.
Michelfrancis Bustillos
6
Głosuję za zamknięciem tego pytania jako nie na temat, ponieważ to wyzwanie wymaga złośliwego kodu.
AdmBorkBork
2
Twierdziłbym inaczej. To wyzwanie wymaga kodu, który promuje prywatność i bezpieczeństwo informacji.
MathuSum Mut

Odpowiedzi:

1

kod maszynowy x86 (Linux), 116 bajtów

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.

Jako argument przyjmuje nazwę pliku

Montaż (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

Wypróbuj online! (Wykorzystuje plik tymczasowy)

-11 bajtów poprzez optymalizację ruchomych rejestrów i wykorzystanie stosu jako bufora zamiast stałej lokalizacji w pamięci.

Logern
źródło
3

W systemie Linux nie ma potrzeby specjalnej obsługi urządzeń. Wystarczy użyć interfejsu pliku urządzenia.

Python 3 (ciągi bajtów) - 141 bajtów

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

Jest dość prosty i niezbyt mocno zoptymalizowany, ale działa. Oto podstawowe podsumowanie.

  • Uzyskaj dane wejściowe (ścieżka pliku urządzenia)
  • Otwórz plik urządzenia
  • Szukaj do końca, uzyskaj rozmiar pliku (urządzenia blokowe mają zawsze swój rzeczywisty rozmiar)
  • wejdź w pętlę zapisu i sprawdzenia
  • konstruować łańcuchy 0-bitowe i 1-bitowe (x)
  • napisz ciąg bitów
  • wyjście koloru (mógłbym ustawić buforowanie = 0, ale to jest krótsze)
  • testuj plik względem x i zwiększaj krok pętli, jeśli przejdzie

pętla wyjściowa, gdy przyrost jest wystarczająco wysoki

Jako bonus, możesz to zmodyfikować dla dowolnego zestawu i liczby wzorców modyfikacji bajtów, takich jak 0x55 / 0xaa dla silniejszych efektów nadpisywania.

Testowałem to na pliku urządzenia, używając sprzężenia zwrotnego. Nie jestem jednak w 100% pewien, że sprawdzanie rzeczywiście działa. Konieczne może być zamknięcie i ponowne otwarcie pliku przy każdym przejściu, ze względu na zachowanie buforowania. Mam nadzieję, że kolor temu zapobiegnie.

* edytowane w celu uwzględnienia sugestii w komentarzach

William Shipley
źródło
1
Witamy na stronie. Z pewnością nie potrzebujesz białych znaków =w Pythonie. Możesz również zmniejszyć liczbę bajtów, używając ;do zmniejszenia wcięcia.
Ad Hoc Garf Hunter
Zwykle liczymy zgłoszenia w bajtach, a nie w znakach. Możesz także aliasować niektóre swoje funkcje, np. f.seek(0);f.seek(0)(19 bajtów) może być s=f.seek;s(0);s(0)(18 bajtów). Ponadto if f.read()==x:i+=1może być i+=f.read()==x.
Jonathan Frech
Nie powinieneś również potrzebować pustego łańcucha jako argumentu do wprowadzenia.
Quintec
Myślę, że b'\0'zamiast b'\x00'powinien działać.
Jason
Właśnie zrealizowałem ważną funkcję. Ten program zużywa pamięć RAM równą wielkości wyczyszczonego urządzenia.
William Shipley
2

C (brzęk) , -DZ=lseek(d,0+ 139 = 152 bajty

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

Wypróbuj online!

Traktuje nazwę pliku jako argument

Nie golfowany:

#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
źródło
Hmm ... czy TiO wyczyści Internet? ;-D
Tytus
@Titus Tworzy plik tymczasowy i czyści go.
Logern
1

Tcl, 286 bajtów

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

Niezbyt dobrze zoptymalizowane. Próbowałem, co mogłem, ale niewiele wiem o Tcl.

Zapisz jako „f.tcl” i uruchom na Uniksie za pomocą tclsh f.tcl "your filename". Upewnij się, że jest dokładnie jeden argument! Przetestowałem to na zwykłym pliku, ale powinien on również działać na pliku urządzenia.

Ustawienie zmiennych i indeksowanie jest bardziej zaangażowane w Tcl, więc postanowiłem umieścić wspólny kod między przejściami w funkcji. Następnie nazywam to najpierw „\ 0” i powtarzam, dopóki się nie weryfikuje. Robię to samo z „\ xff”.

Zarumieniłam się po napisaniu; może nie być konieczne. fconfigure -translation binary -buffering nonejest dłuższe.

-2 bajty poprzez usunięcie cudzysłowów r+.

Jason
źródło