Bir diski güvenli şekilde silmek için en kısa kod


9

DoD 5220.22-M Silme Yönteminin basitleştirilmiş bir varyantını sadece iki yazma geçişiyle gerçekleştirmek için en kısa kodu yazalım .

Herhangi bir programlama dili kabul edilir, ancak disk silme odaklı kitaplıkların kullanılması yasaktır.

Pseudocode ile nasıl uygulayacağımız aşağıda açıklanmıştır:

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

Başka bir deyişle, bu kod iki kez çalışacak, bir yazma geçişi ve doğrulama geçişi 0ve bir yazma geçişi ve doğrulama geçişi için 1.

Kod-golf tarzı uygulamak için yeterince ballsy kimse var mı? ;)


6
Test etmenin ne kadar zor olacağı için bunun herhangi bir cevap alacağından şüpheliyim.
James

12
Cidden, SSD'niz bu tür tedaviyi hak etmek için size ne yaptı? Oyuncak ayı koleksiyonunuzun tamamını veya başka bir şeyi mi öldürdü?
R. Kap

2
Gerçekten bunu denemek ve uğraşmak istiyorum ... ayrıca gerçekten HDD'yi test etmek için feda etmek istemiyorum.
Michelfrancis Bustillos

6
Bu soruyu konu dışı olarak kapatmak için oy kullanıyorum çünkü bu meydan okuma kötü amaçlı kod istiyor.
AdmBorkBork

2
Aksine tartışırım. Bu zorluk gizlilik ve bilgi güvenliğini destekleyen kodlar ister.
MathuSum Mut

Yanıtlar:


1

x86 makine kodu (Linux), 116 bayt

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.

Dosya adını bağımsız değişken olarak alır

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

Çevrimiçi deneyin! (Geçici bir dosya kullanır)

Hareketli kayıtları optimize ederek ve yığını bellekte sabit bir konum yerine tampon olarak kullanarak -11 bayt.


3

Linux sistemlerinde özel cihazların taşınmasına gerek yoktur. Sadece cihaz dosya arayüzünü kullanın.

Python 3 (bayt dizeleri) - 141 bayt

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

Oldukça basittir ve çok fazla optimize edilmemiştir, ancak işe yarar. İşte temel bir özet.

  • Girdiyi al (cihaz dosya yolu)
  • Cihaz dosyasını aç
  • Sonuna kadar ara, dosya boyutu al (blok cihazlar her zaman gerçek boyutlarındadır)
  • yazma ve kontrol döngüsünü girin
  • 0 bit ve 1 bit dizeler (x) oluşturun
  • bit dizisi yaz
  • sifon çıkışı (arabelleğe alma = 0 ayarlayabilirdim ama bu daha kısa)
  • x'e karşı test dosyası ve geçerse döngü adımını artır

artış yeterince yüksek olduğunda çıkış döngüsü

Bonus olarak, daha güçlü üzerine yazma efektleri için 0x55 / 0xaa gibi herhangi bir dizi ve bayt değiştirme modeli için bunu değiştirebilirsiniz.

Aslında bunu bir aygıt dosyasında geri döngü kullanarak test ettim. Ancak, kontrolün gerçekten işe yaradığından% 100 emin değilim. Arabelleğe alma davranışları nedeniyle dosyayı her geçişte kapatmak ve yeniden açmak gerekebilir. Umarım sifon bunu engeller.

* yorumlara bazı öneriler eklemek için düzenlendi


1
Siteye hoş geldiniz. Kesinlikle bir =python etrafında boşluk gerekmez . Girintiyi azaltmak için kullanarak bayt sayınızı da azaltabilirsiniz ;.
Ad Hoc Garf Hunter

Normalde, gönderimleri karakter değil bayt cinsinden sayarız. Ayrıca bazı işlevlerinizin takma adını da kullanabilirsiniz, örneğin f.seek(0);f.seek(0)(19 bayt) s=f.seek;s(0);s(0)(18 bayt) olabilir. Ayrıca if f.read()==x:i+=1olabilir i+=f.read()==x.
Jonathan Frech

Girmek için argüman olarak boş dizeye de ihtiyacınız olmamalıdır.
Quintec

Çalışmak b'\0'yerine bence b'\x00'.
Jason

Sadece önemli bir özellik fark ettim. Bu program, silinen cihazın boyutuna eşit RAM tüketir.
William Shipley

2

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

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

Çevrimiçi deneyin!

Dosya adını argüman olarak alır

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 ... TiO interneti silecek mi? ;-D
Titus

@Titus Geçici bir dosya oluşturur ve siler.
Logern

1

Tcl, 286 bayt

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

Gerçekten iyi optimize edilmedi. Elimden geleni denedim, ama Tcl hakkında çok şey bilmiyorum.

"F.tcl" olarak kaydedin ve ile Unix üzerinde çalıştırın tclsh f.tcl "your filename". Tam olarak bir argüman olduğundan emin olun! Bunu düz bir dosyada test ettim, ancak bir cihaz dosyasında da çalışması gerekir.

Değişkenleri ayarlama ve indeksleme Tcl'ye daha fazla dahil olduğundan, geçişler arasındaki ortak kodu bir işleve koymaya karar verdim. Sonra ilk olarak "\ 0" ile çağırıyorum ve doğrulama başarısız olduğunda tekrar ediyorum. Aynı şeyi "\ xff" ile de yaparım.

Yazdıktan sonra kızardım; gerekli olmayabilir. fconfigure -translation binary -buffering nonedaha uzun.

-2 bayt etrafında tırnak kaldırarak r+.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.