Найкоротший код для безпечного витирання диска


9

Давайте напишемо найкоротший код для виконання спрощеного варіанту методу протирання DoD 5220.22-M лише з двома записами на запис.

Будь-яка мова програмування прийнята, але використання бібліотек, орієнтованих на витирання дисків, заборонено.

Ось як ми реалізуємо це у псевдокоді:

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

Іншими словами, цей код буде виконуватися двічі, з пропуском для запису та перевіркою для підтвердження, а також з пропуском для 0запису та перевіркою для перевірки 1.

Хто-небудь досить м'який, щоб втілити його у стилі код-гольф? ;)


6
Я сумніваюся, що це отримає будь-які відповіді через те, як важко буде перевірити.
Джеймс

12
Серйозно, що зробив ваш SSD для того, щоб заслужити такого роду лікування? Це вбило всю вашу колекцію плюшевого ведмедика чи щось таке?
Р. Кап

2
Дійсно хочу спробувати вирішити це ... також дуже не хочу принести в жертву мій жорсткий диск, щоб перевірити його.
Michelfrancis Bustillos

6
Я голосую, щоб закрити це питання поза темою, оскільки ця проблема вимагає зловмисного коду.
AdmBorkBork

2
Я б заперечував інакше. Цей виклик запитує код, що сприяє конфіденційності та безпеці інформації.
MathuSum Mut

Відповіді:


1

машинний код x86 (Linux), 116 байт

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.

В якості аргументу береться ім'я файлу

Асамблея (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

Спробуйте в Інтернеті! (Використовує тимчасовий файл)

-11 байт шляхом оптимізації рухомих регістрів та використання стека як буфера замість постійного розташування в пам'яті.


3

У системі Linux немає необхідності в спеціальній обробці пристроїв. Просто використовуйте інтерфейс файлу пристрою.

Python 3 (рядки байтів) - 141 байт

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

Це досить просто і не дуже оптимізовано, але це працює. Ось базовий пробіг.

  • Отримати введення (шлях до файлу пристрою)
  • Відкрити файл пристрою
  • Прагніть до кінця, отримайте розмір файлів (блокові пристрої завжди мають їх реальний розмір)
  • введіть цикл запису і перевірки
  • побудувати 0-бітні та 1-бітні рядки (x)
  • написати бітстринг
  • флеш-вихід (я міг встановити буферизацію = 0, але це коротше)
  • тестовий файл проти x та крок циклу, якщо він проходить

петлю виходу, коли приріст досить високий

Як бонус, ви можете змінити це для будь-якого набору та кількості шаблонів модифікації байтів, наприклад, 0x55 / 0xaa для більш сильних ефектів перезапису.

Я фактично перевіряв це на файлі пристрою, використовуючи loopback. Проте я не на 100% впевнений, що перевірка справді працює. Можливо, потрібно буде закрити та повторно відкрити файл кожен прохід через буферизацію поведінки. Я сподіваюся, що промивання цьому заважає.

* відредаговано, щоб включити деякі пропозиції до коментарів


1
Ласкаво просимо на сайт. Вам, звичайно, не потрібен пробіл навколо =пітона. Ви також можете зменшити кількість байтів, ;зменшивши відступ.
Ad Hoc Hunter Hunter

Зазвичай ми рахуємо подання в байтах, а не символи. Ви також f.seek(0);f.seek(0)можете встановити псевдоніми деяких своїх функцій, наприклад (19 байт) s=f.seek;s(0);s(0)(18 байт). Крім того, if f.read()==x:i+=1може бути i+=f.read()==x.
Джонатан Фрех

Ви також не повинні мати порожній рядок як аргумент для введення.
Квінтек

Думаю, b'\0'замість цього b'\x00'слід працювати.
Джейсон

Щойно зрозумів важливу особливість. Ця програма буде споживати оперативну пам’ять, рівну розміру пристрою, що витирається.
Вільям Шиплі

2

C (кланг) , -DZ=lseek(d,0+ 139 = 152 байти

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

Спробуйте в Інтернеті!

Приймає ім'я файлу як аргумент

Безголівки:

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

Хм ... чи буде TiO витерти Інтернет? ;-D
Тіт

@Titus Створює тимчасовий файл і витирає його.
Логерн

1

Tcl, 286 байт

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

Не дуже оптимізовано. Я спробував, що міг, але про Tcl я не знаю так багато.

Збережіть як "f.tcl" і запустіть на Unix з tclsh f.tcl "your filename". Переконайтесь, що є рівно один аргумент! Я перевірив це на звичайному файлі, але він також повинен працювати на файлі пристрою.

Встановлення змінних та індексація більше задіяні в Tcl, тому я вирішив поставити загальний код між пропусками у функцію. Потім я називаю це спочатку "\ 0", і повторюю, поки він не може перевірити. Я роблю те саме, що і з "\ xff".

Я почервонів після запису; це може не бути необхідним. fconfigure -translation binary -buffering noneдовше.

-2 байти, видаливши лапки навколо r+ .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.